题
我有一个简单的数据库表称为"项目":
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 是绝对的路要走,但是如果你想为它直接从你的轨道应用程序,只要设置一些响应的标题,也是。
我保持一种周围设置的文件和必要的标题:
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.然后当我用google搜索找到宝石,我也发现了一个相当完整的例在 这一wiki网页.把它们放在一起,我决定以下代码。
通过这种方式,命令安装宝石是:sudo宝石的安装fastercsv (所有情况下)
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:
需要红宝石的csv库在初始化文件等config/初始化/相关性。rb
require "csv"
作为一背景下码是基于关闭 瑞恩贝特先进的搜索形式 创建一个搜索的资源。在我的情况显示方法搜索的资源将返回的结果以前保存的搜索。它还响应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
展示。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版本的报告页面我有一个链接到出口报告的用户观看。以下是link_to返回csv版本的报告:
<%= link_to "Export Report", formatted_advertiser_search_path(@advertiser_search, :csv) %>
看看到的 FasterCSV 宝石。
如果所有你需要的是excel的支持,你也可能会看到生xls。(参见表格::Excel)
gem install fastercsv
gem install spreadsheet-excel
我找到这些选项很好的开csv文件,在Windows Excel:
FasterCSV.generate(:col_sep => ";", :row_sep => "\r\n") { |csv| ... }
至于Email的一部分,这样的事情会这样做:
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
你需要设置Content-Type header在你的回应,然后送的数据。Content_Type:应用/越南盾。ms excel应该做的伎俩。
你可能还需要设置Content-Disposition header使它看起来像一个Excel文件和浏览器中挑选一个合理的默认文件的名称;这有点像Content-Disposition:附件;filename="#{suggested_name}.xls"
我建议使用的fastercsv红宝石宝石产生CSV,但也有一个内置的csv。该fastercsv样的代码(从宝石的文件)看起来是这样的:
csv_string = FasterCSV.generate do |csv|
csv << ["row", "of", "CSV", "data"]
csv << ["another", "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
试试一个很好的宝石生CSV从轨 https://github.com/crafterm/comma
如果你只是想要得到的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(""))}