調査のスタート
現在触っているシステムでrailsのサーバーからcsv作成する時、データー量が少ない時には
csv = "column1,column2\ndata1,data2\n..."
send_data csv, filename: 'result.csv', type: :csv
こんな感じでsend_dataでstringをすぐ送っているものにしました。
今まで特に問題ないと思いましたがEXCELでは文字化けが発生している連絡が来ました。
自分はexcel使っていないし自分が使っているエディタでは問題無かったので全然気づいていない状態でした。
エンコーディング確認するとちゃんとutf-8だったのでexcelでデーターインポートでファイル開けると問題ないことまで確認しました。
もしかしてMIMEが問題だったか?
上に話した通りデーターが少ない時だけstringをsend_dataしていることでデーターが多い場合サーバーでcsvファイルを作って配信するパタンがあります。
ファイル作成しているパタンでは同じデーター書いている時にも文字化けが発生していないことが確認してもしかしてファイルが同じ状態ではないかとしてターミナルに
$ file -I result.csv
result.csv: text/plain; charset=utf-8
$ file -I big_result.csv #EXCELにも文字化け発生しないファイル
big_result.csv: text/csv; charset=utf-8
MIMEが違いました。もしEXCELだけ厳しいか?とかなぜtype: :csvしたのにtext/plainになっているか考えながら確認するとcsvというMIMEが存在しないこと確認しました。
text/csvでした。
railsのsend_dataもただcontent_typeに入れるだけだったので
send_data csv, filename: 'result.csv', type: 'text/csv'
それにするとダウンロードしたファイルも
$ file -I result.csv
result.csv: text/csv; charset=utf-8
type変更したので終わりだと思いましたがまだEXCELで文字化けが…
BOM
もしかして特定の文字列が問題か?と思ってテキストエディタで問題あるファイルとないファイルを文言コピペしならが確認すると問題あるファイルのヘッダーを問題ないファイルの頭に貼りると問題無かったファイルも文字化けが発生したこと発見
問題が発生した後ではコピペした文言を削除しても文字化け発生する状態そのまま!
自分の作業がターミナルがメインだったので気づくことが遅かったんですがBOM有無の問題でした。
ファイルを作って配信する時にはBOMが存在しstringだけでは存在しなかっただけでした。
エディタでは文字列として見えないですが右のファイルはutf-8だと判断できる0xEF 0xBB 0xBFがちゃんと履いていることだけでした。見えないけどテキストエディタで修正するとBOMも削除されたので気づいた。
エディタによった保存する時確認したり開ける時に確認することがあることもあるけどEXCELが少し厳しかった、、、
解決
毎回ファイルの作ることは嫌だったので
def send_csv(csv_text, options = {})
bom = " "
bom.setbyte(0, 0xEF)
bom.setbyte(1, 0xBB)
bom.setbyte(2, 0xBF)
send_data bom + csv_text, options.merge(type: 'text/csv')
end
BOMを勝手に追加するメソッドでcsvダウンロードすることにしました。
終わり