LoginSignup
40
37

More than 5 years have passed since last update.

Rails4で簡単CSVダウンロード

Last updated at Posted at 2015-09-10

Rails4からRubyテンプレートが追加されました。
hoge.csv.rubyというようなファイルを用意することで、hoge.html.erbと同じような感覚でrubyスクリプトでViewが書けます。

環境

  • OS: Windows10 64bit, Rails version: 4.2.1, Ruby version: 2.1.6-p336 (x64-mingw32)
  • rails g scaffold User name:string email:string した直後の状態
  • ja.ymlでカラム名を日本語化済み

要件

  • http://localhost:3000/usersにアクセスするとユーザー一覧が表示できる状態で、http://localhost:3000/users.csvにアクセスすると、ユーザー一覧のCSVファイルusers.csvがダウンロードできる。
  • CSVのカラムはnameとemailで、ヘッダーのカラム名は日本語
  • Windows環境で文字化けしないように文字コードはShift_JISで。

コード

/app/views/users/index.csv.ruby
require 'kconv'
columns = [:name, :email]
res = ""
res << columns.map{|c| User.human_attribute_name c }.join(',')+"\r" # header
@users.pluck(*columns).each do |u|
  res << u.join(',')+"\r" # body
end
res.tosjis

# もしくは
require 'kconv'
require 'csv'
columns = [:name, :email]
CSV.generate do |csv|
  csv << columns.map{|c| User.human_attribute_name c } # header
  @users.pluck(*columns).each{|u| csv << u } # body
end.tosjis
/app/controllers/users_controller.rb
# 抜粋です。scaffold直後から変更なし。respond_toかかなくてもOK
class UsersController < ApplicationController
  def index
    @users = User.all
    respond_to do |format|
      format.html
      format.csv do
        filename = 'users'
        headers['Content-Disposition'] = "attachment; filename=\"#{filename}.csv\""
      end
    end
  end  end
end
/app/views/users/index.html.erb
# お好きなところにリンクをどうぞ。
<%= link_to 'csv download', users_path(format: :csv) %>

メリット

  • CSVの整形に関するコードをModelやControllerに書かなくてスッキリ!

デメリット

  • 例えば、テンプレートのCSVをダウンロードし、それを編集した後にアップロードする、というフローがあるとする。テンプレートCSVのカラムとアップロードされたCSVのカラムがずれていないことをチェックする、という要件がある場合、使いにくい。カラムの列整形にかかわるコードが、View(index.csv.ruby)とView以外(UsersControllerかUserモデル)に分かれてしまい、メリットが無くなる。
  • ファイル名を動的に変更できない。"URLの最後のスラッシュ以下".csv というファイル名になる。send_data filename: hoge.csvを使えばよいが、他に良い方法があれば教えて下さい。 レスポンスヘッダの Content-Disposition でファイル名を指定すればOK(上記参照)。

参考文献

40
37
0

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
40
37