production.log

スナップマート株式会社で取締役CTOをやっている星直史のブログです。

RailsでCSVを生成し、Excelで開く時にハマったこと

概要

久しぶりのRailsネタ。
管理画面的なシステムで、RailsからCSVを出力し、それをエンドユーザーがExcelで開くようなシュチュエーションで困ったことがありました。

  • セル内の日本語が文字化けしてしまう
  • 0埋め文字を生成しても、Excelで先頭の0が除かれてしまう

それぞれ5分ほどハマったのと、複数回ハマりそうなのでRailsでCSVを生成し、Excelで開く時にハマったこととしてメモに残します。

セル内の日本語が文字化けしてしまう

手法は2つです。

  1. BOM付き(UTF-8)でCSVを出力する
  2. SJISにエンコードして出力する

BOM付き(UTF-8)でCSVを出力する

bom = "\uFEFF"
header = %w(ID 名前)
CSV.generate(bom) do |csv|
  csv << header
end

generateメソッドの引数にbomを渡すわけですね。

SJISにエンコードして出力する

CSV.generate(encoding: Encoding::SJIS, row_sep: "\r\n", force_quotes: true) do |csv|
   ...
end

先ほどと同様に、generateメソッドの引数にエンコードを指定する方法です。

0埋め文字を生成しても、Excelで先頭の0が除かれてしまう

ExcelでCSVを読み込む際、"001"という文字列を数値として扱ってしまいます。
これを避けるために、「"001"は文字列ですよ」とExcelが認識できる形で出力します。

Excel単体で考えた場合に、セル内に「="001"」と入力すると文字列として認識してくれるため、
CSV出力時もこれと同様の文字列を作ると、うまく行きます。

CSV.generate(bom) do |csv|
  csv << [format('="%04d"', "0001")]
end

まとめ

いつもRailsでCSVを出力してExcelで確認してもらう時に、「オレは何と戦っているんだ....」という気持ちになりますが、そんな気持ちになる前に瞬殺してしまえば良いと思い立ち書きました。

  • セル内の日本語が文字化けしてしまう
  • 0埋め文字を生成しても、Excelで先頭の0が除かれてしまう