将哈希数组导出到csv文件

时间:2015-11-21 23:01:08

标签: ruby-on-rails ruby csv export-to-csv

我的目标是将哈希数组转换为csv文件。 这是我的控制者:

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

@comsumptions是一个哈希数组:

[{"x"=>76,
  "y"=>"example",
  "z"=>2015,
  "consumption"=>#<BigDecimal:7fea4a1cadb8,'0.5382857142E4',18(27)>},
 {"x"=>76,
  "y"=>"example2",
  "z"=>2015,
  "consumption"=>#<BigDecimal:7fea4a1ca7c8,'0.5437E4',9(27)>},(..)

我想创建一个包含2个特定列的CSV文件,&#34;消费&#34;和&#34; z&#34;。 当我用这3行注释时,输出是一个包含所有@consumptions的文件。如何选择这两列并在cv文件中进行转换?

def self.to_csv
    CSV.generate(headers: true ) do |csv|
      #csv << column_names
      #all.each do |product|
      #  csv << product.attributes.values_at(*column_names)
      end
    end
  end

2 个答案:

答案 0 :(得分:2)

根据您的反馈,我认为最好的方法是在您的视图中创建一个csv视图文件。例如,如果您的html文件为$(function () { "use strict"; var mydata = [ { id: "10", invdate: "2007-10-01", name: "test", note: "note", amount: "", tax: "", closed: true, ship_via: "TN", total: "" }, { id: "20", invdate: "2007-10-02", name: "test2", note: "note2", amount: "300.1", tax: "20.12", closed: false, ship_via: "FE", total: "320.123" }, { id: "30", invdate: "2007-09-01", name: "test3", note: "note3", amount: "400.00", tax: "30.00", closed: false, ship_via: "FE", total: "430.00" }, { id: "40", invdate: "2007-10-04", name: "test4 test4 test4", note: "note4", amount: "200.00", tax: "10.00", closed: true, ship_via: "TN", total: "210.00" }, { id: "50", invdate: "2007-10-31", name: "test5", note: "note5", amount: "300.00", tax: "20.00", closed: false, ship_via: "FE", total: "320.00" }, { id: "60", invdate: "2007-09-06", name: "test6", note: "note6", amount: "400.00", tax: "30.00", closed: false, ship_via: "FE", total: "430.00" }, { id: "70", invdate: "2007-10-04", name: "test7", note: "note7", amount: "200.00", tax: "10.00", closed: true, ship_via: "TN", total: "210.00" }, { id: "80", invdate: "2007-10-03", name: "test8", note: "note8", amount: "300.00", tax: "20.00", closed: false, ship_via: "FE", total: "320.00" }, { id: "90", invdate: "2007-09-01", name: "test9 test9 test9 test9 test9", note: "note9", amount: "400.00", tax: "30.00", closed: false, ship_via: "TN", total: "430.00" }, { id: "100", invdate: "2007-09-08", name: "test10", note: "note10", amount: "500.00", tax: "30.00", closed: true, ship_via: "TN", total: "530.00" }, { id: "110", invdate: "2007-09-08", name: "test11", note: "note11", amount: "500.00", tax: "30.00", closed: false, ship_via: "FE", total: "530.00" }, { id: "120", invdate: "2007-09-10", name: "test12", note: "note12", amount: "500.00", tax: "30.00", closed: false, ship_via: "FE", total: "530.00" } ], $grid = $("#list"), initDateEdit = function (elem) { $(elem).datepicker({ dateFormat: "dd-M-yy", autoSize: true, changeYear: true, changeMonth: true, showButtonPanel: true, showWeek: true }); }, initDateSearch = function (elem) { setTimeout(function () { initDateEdit(elem); }, 50); }; $grid.jqGrid({ data: mydata, colNames: ["", "Client", "Date", "Amount", "Tax", "Total", "Closed", "Shipped via", "Notes"], colModel: [ { name: "act", template: "actions" }, { name: "name", align: "center", width: 100, editrules: {required: true} }, { name: "invdate", width: 82, align: "center", sorttype: "date", frozen: true, formatter: "date", formatoptions: { newformat: "d-M-Y", reformatAfterEdit: true }, datefmt: "d-M-Y", editoptions: { dataInit: initDateEdit }, searchoptions: { sopt: ["eq", "ne", "lt", "le", "gt", "ge"], dataInit: initDateSearch } }, { name: "amount", width: 62, template: "number", formatter: "number", formatoptions: {decimalSeparator:",", thousandsSeparator: " ", decimalPlaces: 4, defaultValue: '0.0000'}, editoptions: { type: "number", step: "0.01", min: "0.00", max: "1000", pattern: "[0-9]+([\.|,][0-9]+)?", title: "This should be a number with up to 2 decimal places." } }, { name: "tax", width: 45, template: "number", autoResizableMinColSize: 40 }, { name: "total", width: 53, template: "number" }, { name: "closed", width: 60, template: "booleanCheckboxFa" }, { name: "ship_via", width: 76, align: "center", formatter: "select", edittype: "select", editoptions: { value: "FE:FedEx;TN:TNT;IN:Intim", defaultValue: "IN" }, stype: "select", searchoptions: { sopt: ["eq", "ne"], value: ":Any;FE:FedEx;TN:TNT;IN:IN" } }, { name: "note", width: 43, edittype: "textarea", sortable: false } ], cmTemplate: { editable: true, autoResizable: true }, autoResizing: { compact: true }, iconSet: "fontAwesome", rowNum: 10, rowList: [5, 10, 20, "10000:All"], viewrecords: true, autoencode: true, pager: true, sortname: "invdate", sortorder: "desc", searching: { defaultSearch: "cn", searchOperators: true } }) .jqGrid("filterToolbar") .jqGrid("gridResize"); }); ,则您的csv视图文件应为comsumptions.html.erb

comsumptions.csv.ruby

我们也需要改变控制器。删除# comsumptions.csv.ruby require 'csv' CSV.generate do |csv| csv << ['consumption', 'z'] @comsumptions.each do |c| csv << [ c['consumption'].to_s, c['z'] ] end end 部分或按如下所示进行修改

respond_to

我已经在我的localhost上测试了,这应该可行!

答案 1 :(得分:0)

require 'csv'

@comsumptions =
[{"x"=>76,
  "y"=>"example",
  "z"=>2015},
 {"x"=>76,
  "y"=>"example2",
  "z"=>2015}]

class << @comsumptions
  def to_csv (*keys)
    keys = first.keys if keys.empty?
    CSV.generate(headers: keys, write_headers: true) do |csv|
      each do |e|
        csv << e.values_at(*keys)
      end
    end
  end
end

p @comsumptions.to_csv("x","y")
p @comsumptions.to_csv()

这个解决方案很大程度上来自于Van Huy的解决方案,只要哈希具有所有相同的键,就可以预期未定义的行为

我不清楚你在控制器内放置def self.to_csv方法的位置?那是错的。你想要做的是增加@consumptions对象,扩充Array类,或者在控制器中定义一个方法。我的例子确实扩充了@consumptions对象,你可以将所有内容放在控制器方法中,它应该可以工作。