web-dev-qa-db-fra.com

Comment écrire l'en-tête des colonnes dans un fichier csv avec Ruby?

J'ai du mal à écrire des colonnes dans un fichier csv avec Ruby. Ci-dessous mon extrait de code.

 calc = numerator/denominator.to_f
 data_out = "#{numerator}, #{denominator}, #{calc}"
 File.open('cdhu3_X.csv','a+') do|hdr|
      hdr << ["numerator","denominator","calculation\n"] #< column header
          hdr << "#{data_out}\n"
 end

Le code ajoute les en-têtes de colonne à chaque ligne et je n'en ai besoin qu'en haut de chaque colonne de données. J'ai cherché ici et ailleurs, mais je ne trouve pas de réponse claire à la façon dont c'est fait. Toute aide serait grandement appréciée.

23
Joe

Je recommanderais d'utiliser la bibliothèque CSV à la place:

require 'csv'

CSV.open('test.csv','w', 
    :write_headers=> true,
    :headers => ["numerator","denominator","calculation"] #< column header
  ) do|hdr|
  1.upto(12){|numerator|
    1.upto(12){ |denominator|
      data_out = [numerator, denominator, numerator/denominator.to_f]
      hdr << data_out
    }
  }
end

Si vous ne pouvez pas utiliser l'option w et que vous avez vraiment besoin de a+ (par exemple, les données ne sont pas disponibles d'un seul coup), vous pouvez alors essayer l'astuce suivante:

require 'csv'

column_header = ["numerator","denominator","calculation"]
1.upto(12){|numerator|
  1.upto(12){ |denominator|
    CSV.open('test.csv','a+', 
        :write_headers=> true,
        :headers => column_header
      ) do|hdr|
          column_header = nil #No header after first insertion
          data_out = [numerator, denominator, numerator/denominator.to_f]
          hdr << data_out
        end
  }
}
51
knut

La façon la plus simple de le faire est d'ouvrir le fichier une fois, en mode 'w', écrivez les en-têtes, puis écrivez les données.

S'il y a une raison technique qui ne peut pas le faire (par exemple, les données ne sont pas disponibles d'un coup), vous pouvez utiliser le IO#tell méthode sur le fichier pour retourner la position actuelle du fichier. Lorsque vous ouvrez le fichier pour l'ajout, la position est définie à la fin du fichier, donc si la position actuelle du fichier est zéro, le fichier a été nouvellement créé et n'a pas d'en-tête:

File.open('cdhu3_X.csv', 'a+') do |hdr|
  if hdr.tell() == 0  # file is empty, so write header
    hdr << "numerator, denominator, calculation\n"
  end
  hdr << "#{data_out}\n"
end
6
sfstewman

La meilleure façon de gérer le fichier csv est d'utiliser le module CSV de Ruby.

J'ai eu le même problème après avoir lu le code CSV. Je suis tombé sur cette solution que je trouve la plus efficace.

headers = ['col1','col2','col3']

CSV.open(file_path, 'a+', {force_quotes: true}) do |csv|
  csv << headers if csv.count.eql? 0 # csv.count method gives number of lines in file if zero insert headers
end
4
Asad Ali