如何生成CSV文件?

时间:2015-08-01 14:22:00

标签: ruby-on-rails ruby csv action

我正在尝试使用数据库中的数据生成CSV输出。我想将这些数据提供给第三方,所以我想我会给某人一个URL(website.com/api_data/cars)并通过访问此URL可以使用它 - 我想我想访问该网址,然后在,;显示和分隔的数据(在操作中)。

但是怎么做?

到目前为止,我正在尝试以下方法:

csv_string = CSV.generate do |csv|
  cols = ["column one", "column two", "column three"]
  csv << cols
  csv << ["A", "B", "C"]

  @filename = "data-#{Time.now.to_date.to_s}.csv"  
end
send_data(csv_string, :type => 'text/csv; charset=utf-8; header=present', :filename => @filename)  

这是在控制器 generate_data 和操作 csv_cars

当我运行此操作( webste.com/generate_data/csv_cars )时,它会自动弹出一个窗口来下载文件。

但是如何将CSV内容写入动作?所以,当我打开URL时,我会看到那里写了数据库中的内容吗?

3 个答案:

答案 0 :(得分:8)

我知道这是一个老线程,但我在搜索中遇到过它,以防其他人也这样做,这是我的回答以及对我有用的东西。

我认为bhanu有很好的办法,但我确实改变了一些东西。我没有在respond_to中执行@cars,而是调用了send_data Cars.to_csv,因为正如Rob所说,它是作为一个类方法而制作的。它对我来说很漂亮。

class Car < ActiveRecord::Base
  def self.to_csv(make)
    attributes = %w{id name price} #customize columns here
    cars = Car.where(maker_name: make)

    CSV.generate(headers: true) do |csv|
      csv << attributes

      cars.each do |car|
        csv << attributes.map{ |attr| car.send(attr) }
      end
    end
  end
end

然后在控制器中

class CarsController < ApplicationController
  def index
    send_data Cars.to_csv('Chevy'), filename: "cars-#{Date.today}.csv"
  end
end

我知道当你去汽车/索引时会调用它,但你可以将它放入任何方法,if语句或任何你想要的东西,只要你想从那里调用它。你也可以有参数,就像我上面用make做的那样,并查询某些字段。这绝对比我想象的容易得多。希望这有助于某人。

答案 1 :(得分:4)

在模型中定义to_csv方法,如下所示

class Car < ActiveRecord::Base
  def self.to_csv
    attributes = %w{id name price} #customize columns here

    CSV.generate(headers: true) do |csv|
      csv << attributes

      all.each do |car|
        csv << attributes.map{ |attr| car.send(attr) }
      end
    end
  end
end

稍后在你的控制器中

class CarsController < ApplicationController
  def index
    @cars = Car.all

    respond_to do |format|
      format.html
      format.csv { send_data @cars.to_csv, filename: "cars-#{Date.today}.csv" }
    end
  end
end

答案 2 :(得分:0)

您需要执行以下操作。

def csv_cars
  headers = ['column one', 'column two', 'column three']

  csv_data = CSV.generate(headers: true) do |csv|
    csv << headers
    csv << ["A", "B", "C"]
  end

  send_data csv_data, filename: "data-#{Date.today.to_s}.csv", disposition: :attachment
end