экспортировать объект в CSV-файл, в котором в данный момент отображаются данные - PullRequest
0 голосов
/ 14 мая 2019

У меня @people переменная содержит данные выглядят так же, как:

Что у меня есть

[{"id"=>1, "name"=>"Tom", "age"=>"25"},
 {"id"=>2, "name"=>"Marry", "age"=>"27"},
 {"id"=>3, "name"=>"Jack", "age"=>"28"}] 

и я пытаюсь преобразовать данные в файл CSV, который может выглядеть как

Что я собираюсь сделать

id | name | age
 1 | Tom  | 25
 2 | Marry| 27
 3 | Jack | 28

но мой код генерирует CSV-файл с отображением всех встроенных данных. Например:

Что я получу

{"id"=>1,"name"=>"Tom","age"=>25},{"id"=>2, "name"=>"Marry", 
"age"=>"27"},{"id"=>3, "name"=>"Jack", "age"=>"28"}

Что я сделал:

to_csv действие выглядит так:

  def to_csv
    CSV.generate(option) do |csv|
      csv << column_names
      values.each do |value|
        csv << value.attributes.values_at(*column_names)
      end
    end
  end

Я добавил этот блок respond_to к одному из своих действий:

respond_to do |format|
   format.html
   format.csv { 
   send_data @people.to_csv,
   filename: "export.csv",
   type: 'text/csv; charset=utf-8' 
 }

Я получаю данные (например, {"id"=>1,"name"=>"Tom","age"=>25 ...) из внешнего источника, поэтому я поместил эти данные в переменную @people для использования. Любая помощь будет принята с благодарностью.

Ответы [ 3 ]

1 голос
/ 14 мая 2019

Я думаю, вам нужно написать функцию по-другому:

  def to_csv(people)
    CSV.generate do |csv|
      return unless people.count > 0
      csv << people[0].keys
      people.each do |person|
        csv << person.values
      end
    end
  end

Полагаю, вы могли бы даже сделать:

  def to_csv(people)
    CSV.generate do |csv|
      return unless people.count > 0
      csv << people[0].keys
      csv << people.each.map{|item| item.values}
    end
  end

А затем вызвать его как функцию:

respond_to do |format|
   format.html
   format.csv { 
   send_data to_csv(@people),
   filename: "export.csv",
   type: 'text/csv; charset=utf-8' 
 }
0 голосов
/ 14 мая 2019

Вот как я это делаю, в моем контроллере я добавил

respond_to do |format|
      format.html
      format.csv { send_data @people.to_csv }
    end

затем

def self.to_csv(options = {})
      CSV.generate(options) do |csv|
        csv << column_names
        all.each do |project|
          csv << people.attributes.values_at(*column_names)
        end
      end
    end

, тогда не забудьте require 'csv' в вашем config / application.rb

тогда вы можете связать свой CSV с чем-то вроде <%= link_to "CSV", people_path(format: "csv") %>

0 голосов
/ 14 мая 2019

вам не нужно делать, как value.attributes.values_at(*column_names), просто вам нужно сделать value.values, который даст вам массив значений, которые вы хотите сохранить в CSV.

, например

people = [{"id"=>1, "name"=>"Tom", "age"=>"25"},
         {"id"=>2, "name"=>"Marry", "age"=>"27"},
         {"id"=>3, "name"=>"Jack", "age"=>"28"}]


def to_csv
    CSV.generate(headers: true) do |csv|
      csv << column_names
      people.each do |person|
        csv << person.values
      end
    end
  end
...