どうもこんにちは。
最近、RailsでCSVファイルをエクスポートする方法を学んだのでメモします。
実装手順
1. クラス定義
導入方法は至って簡単です。使用したい機能のコントローラファイルの一番上に、以下のようにライブラリを定義します。
require 'csv'
class SampleController < ApplicationController
...
これだけでCSV
クラスのメソッドをコントローラ内で使用することができるようになります。
2. exportアクションを定義
まず、使用したいコントローラにexport
メソッドを定義します。
class SampleController < ApplicationController
def export
end
end
3. ルーティングを定義
resources :samples do
collection do
get 'export'
end
end
4. exportアクションに処理を記述
def export
respond_to do |format|
format.csv do
headers['Content-Disposition'] = 'attachment; filename="samples.csv"'
headers['Content-Type'] ||= 'text/csv'
end
end
end
5. viewファイルを追加
ファイルの名前をsample.csv.erb
としてcsvファイルに表示したい項目を記述します。
サンプル1, サンプル2, サンプル3, サンプル4
また、エクスポート用のリンク(ボタン)をページに設置します。
<%= link_to 'エクスポート', export_samples_path(format: 'csv') %>
完成じゃない!
完成かと思いきや、このままエクスポートしたファイルをエクセルで開くと、文字化けしてます。。。
なので、エンコード的なことをしてからcsvファイルを出力する必要があります。
(文字をBOM化することでUTF-8の文字をエクセルで閲覧できるようにします。)
処理修正
6. コントローラ修正
def export
respond_to do |format|
format.csv do
bom = "\uFEFF"
csv_data = CSV.generate(bom) do |csv|
csv << ['サンプル1', 'サンプル2', 'サンプル3', 'サンプル4']
end
send_data(csv_data, filename: "samples.csv")
end
end
end
7. viewファイル修正
sample.csv.erb
のファイルの中身を空にします。
(手順6で追加項目を設定しているので不要になりました。)
完成
これで正常にCSVファイルを出力することができました!
付録(文字コードとBOM)
文字コードとは
- エンコードは方法
- 文字や記号をコンピュータが理解できるバイトまたはビットの並びにマッピングするルールのセット
- テキストをデジタルデータとして表現、転送、保存するために使用される
BOMとは
- BOMはオプション
- UTF-16やUTF-32などのエンコーディングで使用される特殊なマーカー
- テキストファイルの先頭に配置され、テキストファイルのバイトオーダーを識別するのに使用される
- UTF-8のBOMは必須ではなく、また一部のアプリケーションでは問題を引き起こす可能性がある
まとめ
今回の文字化けの対処では、UTF-8で設定した文字をエクセルで見れるようにするために文字をBOM化しました。
これらの違いは、「文字をバイト列に変換する」ものが文字コードのエンコード、「すでにエンコードされた文字がどのようにエンコードされているかを示すマーカー」がBOMであるということです。
めちゃめちゃややこしいですが、今回はBOMを通じて文字をエクスポートすることでエクセルで文字化けするのを防いだということになります。