55

「エントリ」と呼ばれる単純なデータベース テーブルがあります。

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

Entries テーブルの内容を CSV ファイルとして返すハンドラーを作成するにはどうすればよいですか (理想的には、Excel で自動的に開く方法で)。

class EntriesController < ApplicationController

  def getcsv
    @entries = Entry.find( :all )

    # ??? NOW WHAT ????

  end

end
4

10 に答える 10

89

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_csvFasterCSV からのものです)

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 %>
于 2008-09-18T17:21:41.153 に答える
27

最初に FasterCSV を教えてくれた @Brian の回答を受け入れました (そして投票しました!)。その後、Google で宝石を見つけたところ、この wiki ページでかなり完全な例も見つかりました。それらをまとめて、次のコードに落ち着きました。

ちなみに、gem をインストールするコマンドは sudo gem installfastercsv (すべて小文字) です。

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
于 2008-09-18T17:24:32.193 に答える
26

FasterCSV を使用せずにこれを行う別の方法:

config/initializers/dependencies.rb のような初期化ファイルで ruby​​ の csv ライブラリを要求する

require "csv"

背景として、次のコードは、検索リソースを作成するRyan Bate の Advanced Search Formに基づいています。私の場合、検索リソースの 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) %>
于 2008-10-21T17:16:04.517 に答える
23

これを見事に処理する FasterCSV というプラグインがあります。

于 2008-09-18T17:07:43.840 に答える
7

FasterCSV gemを調べてください。

Excel のサポートだけが必要な場合は、xls を直接生成することも検討してください。(スプレッドシート::エクセル参照)

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
于 2008-09-18T17:08:03.310 に答える
2

私の場合、次のアプローチがうまく機能し、ダウンロード後にブラウザが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
于 2012-06-22T00:02:32.117 に答える
2

応答に Content-Type ヘッダーを設定してから、データを送信する必要があります。Content_Type: application/vnd.ms-excel でうまくいくはずです。

また、Content-Disposition ヘッダーを Excel ドキュメントのように設定することもできます。これにより、ブラウザーは適切な既定のファイル名を選択します。それは Content-Disposition: attachment; のようなものです。filename="#{suggested_name}.xls"

CSV を生成するには、fastercsv ruby​​ gem を使用することをお勧めしますが、組み込みの csv もあります。fastcsv サンプル コード (gem のドキュメントから) は次のようになります。

csv_string = FasterCSV.generate do |csv|
  csv << ["row", "of", "CSV", "data"]
  csv << ["another", "row"]
# ...
end
于 2008-09-18T17:16:28.547 に答える
1

Rails から CSV を生成する素敵な gem を試して ください https://github.com/crafter/comma

于 2012-07-17T07:00:59.637 に答える
0

コンソールから 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(""))}
于 2013-07-19T01:25:36.017 に答える
0

CSV Shaper gem を見てください。

https://github.com/paulspringett/csv_shaper

優れた DSL を備えており、Rails モデルで非常にうまく機能します。また、応答ヘッダーを処理し、ファイル名のカスタマイズを可能にします。

于 2012-07-25T19:15:21.813 に答える