#Shift-JISへの文字コード変換
CSV.generate
を使用してCSVを生成します。例として、encording
リクエストパラメータにsjis
が指定された場合にはShift-JISに変換したCSVファイルを出力し、デフォルトではそのままUTF-8で生成したCSVファイルを出力することとします。
app/models/my_model.rb
require 'csv'
# Convert to CSV
def self.to_csv
CSV.generate do |csv|
csv << csv_headers
all.each do |my_model|
csv << my_model.csv_column_values
end
end
end
# Select headers
# Write as you like
def self.csv_headers
[
"タイトル",
"ユーザ名",
"作成日時",
"更新日時"
]
end
# Select values
# Write as you like
def csv_column_values
[
title,
username,
created_at.strftime("%-Y/%-m/%-d %H:%M"),
updated_at.strftime("%-Y/%-m/%-d %H:%M")
]
end
app/controllers/my_model_controller.rb
# Convert special characters to sjis
def sjis_safe(str)
[
["301C", "FF5E"], # wave-dash
["2212", "FF0D"], # full-width minus
["00A2", "FFE0"], # cent as currency
["00A3", "FFE1"], # lb(pound) as currency
["00AC", "FFE2"], # not in boolean algebra
["2014", "2015"], # hyphen
["2016", "2225"], # double vertical lines
].inject(str) do |s, (before, after)|
s.gsub(
before.to_i(16).chr('UTF-8'),
after.to_i(16).chr('UTF-8'))
end
end
# GET /my_models/csv
def csv
csv_data = MyModel.all.to_csv
if params[:encording] == 'sjis'
csv_data = sjis_safe(csv_data).encode(Encoding::SJIS, invalid: :replace, undef: :replace)
end
respond_to do |format|
format.csv {
send_data csv_data,
filename: "my_models_#{Date.today.strftime("%Y%m%d")}.csv",
type: :csv
}
end
end
#BOM付きUTF-8の出力
ExcelでCSVファイルを開くことが目的であれば、文字コードはUTF-8のままでBOMをつければ開くことが出来ます。CSV.generate
の引数にBOMの文字列を渡すだけで済むので、よりシンプルになります。
app/models/my_model.rb
require 'csv'
# Convert to CSV with UTF-8 BOM
def self.to_csv
bom = %w(EF BB BF).map { |e| e.hex.chr }.join
CSV.generate(bom) do |csv|
csv << csv_headers
all.each do |my_model|
csv << my_model.csv_column_values
end
end
end