LoginSignup
59
65

More than 5 years have passed since last update.

Rails で CSV ファイルを View を使って生成する

Posted at

利用明細、売上系のデータを、CSV でダウンロードする機能が必要になったので、
色々調べて実装した時のメモ。

色々調べると、モデルに self.to_csv とクラスメソッド作ってやってるのが多かったんだけど、
「CSV 出力 ( 何の attribute を出力する云々 ) は View の責務だろ!!!!!!」と思い、
Rails4 から View のテンプレートに .ruby が使えるようになったので、それを利用して View で出力するように実装。

利用イメージは、下記 URL にアクセスすると、csv のダウンロードが開始するイメージ。

http://hoge.hogehoge.com/sales/:target_month/donwload.csv
:target_month はダウンロードする対象の月(YYYYMM)が入る。

routes.rb には、URL から :target_month として、params で受けられるよう記述

config/routes.rb
Hoge::Application.routes.draw do
  resources :sales, only: [] do
    collection do
      get ':target_month/download', to: 'sales#download'
    end
  end
end
app/controllers/sales_controller.rb
class SalesController < ApplicationController

  def download

    @sales = Sales.target_month(params[:target_month]) # 対象月の売上を取得

    respond_to do |format|
      format.html { redirect_to :action => 'download', :format => 'csv' } # .csv がなくアクセスした場合はリダイレクト
      format.csv { render :content_type => 'text/csv' }
    end
  end
end

CSV ファイルは、SHIFT-JIS じゃなきゃマズイだろうと思い、NKF で変換かけておく。

app/views/users/download.csv.ruby
require 'csv' # config/application.rb に書いてもいいけど、こっちにした
require 'nkf'

csv_str = CSV.generate do |csv|
  # I18n で CSV のカラム名を取得
  cols = {
    Sales.human_attribute_name(:id)              => ->(s){ s.id },
    # 'ID'                                       => ->(s){ s.id }, # key をそのまま指定する場合
    Sales.human_attribute_name(:created_at)      => ->(s){ s.created_at },
    Sales.human_attribute_name(:sales_amount)    => ->(s){ s.sales_amount },
    Sales.human_attribute_name(:sales_tax)       => ->(s){ s.sales_tax },
    Sales.human_attribute_name(:sales_sum)       => ->(s){ s.sales_amount + r.sales_tax },
  }

  # header の追加
  csv << cols.keys

  # body の追加
  @sales.each do |sale|
    csv << cols.map{|k, col| col.call(sale) }
  end
end
# 文字コード変換
NKF::nkf('--sjis -Lw', csv_str)

もし、関連するモデルから値を取得したい場合も、いつもの記述方で法普通に取得できるのが便利

'ユーザー名' => ->(s){ s.user.name },
59
65
3

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
59
65