LoginSignup
22

More than 5 years have passed since last update.

RailsからShift-JISとUTF-8でCSV出力する

Last updated at Posted at 2016-09-22

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

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
22