てみたの不思議空間【後ろ】

フィーリングで感じたことを書く

Rails3でExcelで作ったSJISのCSVファイルをUTF-8で読み込む方法

2013/05/30 Rails3, Ruby 1.9.3-p125

Excelで作ったCSVの読み込み方法を探してもいいものが見つからなかった。
誰も困ってないのかな。お気に入りのやつを作る。

過程

まず、試行錯誤してる最中のやつを載せる。Excelで作ったCSVSJISとして保存される。
DBはUTF-8なので変換しなくてはいけない。

CSV.foreach(filename, encoding: "Shift_JIS:UTF-8") do |row|
  # …
end

ArgumentError: invalid byte sequence in UTF-8

で引っかかりまくる。
未定義文字があると、errorになるようだ?
open()を使ってやりましょうってあるけど、
Webでopen()とか恐怖症で使えない。(調べてないだけ、だけど。)

SJISで読み込んで、UTF-8に変換していくことにする。

CSV.foreach(filename, encoding: "SJIS") do |row|
  new_hash = row.to_hash
  row = Hash[new_hash.map { |k,v| k, v.encode("UTF-16BE", :invalid => :replace, :undef => :replace, :replace => '?').encode("UTF-8")] }]
end

それでも、

ArgumentError: invalid byte sequence in UTF-8

と出たりする。

終端文字が悪さをしているようだ。Excelの終端文字は"\r\n"になるみたいです。

row_sep: "\r\n"

を追加することにすることで直った。

結果

結果はこうなりました。

CSV.foreach(filename, headers: true, row_sep: "\r\n", encoding: "SJIS") do |row|
  new_hash = row.to_hash
  row = Hash[new_hash.map { |k,v| k, v.encode("UTF-16BE", :invalid => :replace, :undef => :replace, :replace => '?').encode("UTF-8")] }]
  Products.new(row).save!
end

たしか、redmineでもCSV読み込めたような。ソース読んでみよう。