「エントリ」と呼ばれる単純なデータベーステーブルがあります。
class CreateEntries < ActiveRecord::Migration
def self.up
create_table :entries do |t|
t.string :firstName
t.string :lastName
#etc.
t.timestamps
end
end
def self.down
drop_table :entries
end
end
エントリテーブルの内容をCSVファイルとして返すハンドラを作成するにはどうすればよいですか(理想的にはExcelで自動的に開くように)。
class EntriesController < ApplicationController
def getcsv
@entries = Entry.find( :all )
# ??? NOW WHAT ????
end
end
これを素晴らしく処理するFasterCSVというプラグインがあります。
FasterCSV を使用するのは間違いありませんが、Railsアプリから直接提供する場合は、応答ヘッダーも設定する必要があります。
ファイル名と必要なヘッダーを設定するためのメソッドを保持しています。
def render_csv(filename = nil)
filename ||= params[:action]
filename += '.csv'
if request.env['HTTP_USER_AGENT'] =~ /msie/i
headers['Pragma'] = 'public'
headers["Content-type"] = "text/plain"
headers['Cache-Control'] = 'no-cache, must-revalidate, post-check=0, pre-check=0'
headers['Content-Disposition'] = "attachment; filename=\"#{filename}\""
headers['Expires'] = "0"
else
headers["Content-Type"] ||= 'text/csv'
headers["Content-Disposition"] = "attachment; filename=\"#{filename}\""
end
render :layout => false
end
これを使用すると、コントローラーに次のようなものを簡単に含めることができます。
respond_to do |wants|
wants.csv do
render_csv("users-#{Time.now.strftime("%Y%m%d")}")
end
end
そして、次のようなビューがあります:(generate_csv
はFasterCSVからのものです)
UserID,Email,Password,ActivationURL,Messages
<%= generate_csv do |csv|
@users.each do |user|
csv << [ user[:id], user[:email], user[:password], user[:url], user[:message] ]
end
end %>
最初にFasterCSVを指し示した@Brianの回答を受け入れました(そして投票しました!)。次に、gemを見つけるためにグーグルで検索したとき、 このwikiページ でかなり完全な例も見つけました。それらをまとめると、次のコードに落ち着きました。
ところで、gemをインストールするコマンドは次のとおりです。sudogem install fastcsv(すべて小文字)
require 'fastercsv'
class EntriesController < ApplicationController
def getcsv
entries = Entry.find(:all)
csv_string = FasterCSV.generate do |csv|
csv << ["first","last"]
entries.each do |e|
csv << [e.firstName,e.lastName]
end
end
send_data csv_string, :type => "text/plain",
:filename=>"entries.csv",
:disposition => 'attachment'
end
end
FasterCSVを使用せずにこれを行う別の方法:
Config/initializers/dependencies.rbのような初期化ファイルにRubyのcsvライブラリが必要です
require "csv"
背景として、次のコードは、検索リソースを作成する Ryan Bateの高度な検索フォーム に基づいています。私の場合、検索リソースのshowメソッドは、以前に保存された検索の結果を返します。また、csvに応答し、ビューテンプレートを使用して目的の出力をフォーマットします。
def show
@advertiser_search = AdvertiserSearch.find(params[:id])
@advertisers = @advertiser_search.search(params[:page])
respond_to do |format|
format.html # show.html.erb
format.csv # show.csv.erb
end
end
Show.csv.erbファイルは次のようになります。
<%- headers = ["Id", "Name", "Account Number", "Publisher", "Product Name", "Status"] -%>
<%= CSV.generate_line headers %>
<%- @advertiser_search.advertisers.each do |advertiser| -%>
<%- advertiser.subscriptions.each do |subscription| -%>
<%- row = [ advertiser.id,
advertiser.name,
advertiser.external_id,
advertiser.publisher.name,
publisher_product_name(subscription),
subscription.state ] -%>
<%= CSV.generate_line row %>
<%- end -%>
<%- end -%>
レポートページのhtmlバージョンには、ユーザーが表示しているレポートをエクスポートするためのリンクがあります。以下は、csvバージョンのレポートを返すlink_toです。
<%= link_to "Export Report", formatted_advertiser_search_path(@advertiser_search, :csv) %>
FasterCSV gemをご覧ください。
Excelのサポートだけが必要な場合は、xlsを直接生成することも検討できます。 (スプレッドシート:: Excelを参照)
gem install fastercsv
gem install spreadsheet-Excel
これらのオプションは、Windows Excelでcsvファイルを開くのに適しています。
FasterCSV.generate(:col_sep => ";", :row_sep => "\r\n") { |csv| ... }
ActiveRecord部分については、次のようにします。
CSV_FIELDS = %w[ title created_at etc ]
FasterCSV.generate do |csv|
Entry.all.map { |r| CSV_FIELDS.map { |m| r.send m } }.each { |row| csv << row }
end
私の場合、次のアプローチがうまく機能し、ダウンロード後にブラウザがCSVタイプに適したアプリケーションを開きます。
def index
respond_to do |format|
format.csv { return index_csv }
end
end
def index_csv
send_data(
method_that_returns_csv_data(...),
:type => 'text/csv',
:filename => 'export.csv',
:disposition => 'attachment'
)
end
応答にContent-Typeヘッダーを設定してから、データを送信する必要があります。 Content_Type:application/vnd.ms-Excelがトリックを行うはずです。
また、Excelドキュメントのように見えるようにContent-Dispositionヘッダーを設定し、ブラウザが適切なデフォルトのファイル名を選択することもできます。それはContent-Disposition:attachmentのようなものです。 filename = "#{suggested_name} .xls"
Fastcsv Ruby gemを使用してCSVを生成することをお勧めしますが、組み込みのcsvもあります。fastercsvサンプルコード(gemのドキュメントから)は次のようになります。
csv_string = FasterCSV.generate do |csv|
csv << ["row", "of", "CSV", "data"]
csv << ["another", "row"]
# ...
end
niceジェムを試してRails https://github.com/crafterm/comma からCSVを生成します
CSV Shaper gemをご覧ください。
https://github.com/paulspringett/csv_shaper
Nice DSLがあり、Railsモデルでうまく動作します。また、応答ヘッダーを処理し、ファイル名をカスタマイズできます。
コンソールから自分でcsvデータベースを取得したい場合は、数行で取得できます
tags = [Model.column_names]
rows = tags + Model.all.map(&:attributes).map(&:to_a).map { |m| m.inject([]) { |data, pair| data << pair.last } }
File.open("ss.csv", "w") {|f| f.write(rows.inject([]) { |csv, row| csv << CSV.generate_line(row) }.join(""))}