天天看点

使用rails生成excel(CSV)表格

昨天遇到生成excel表格这个需求,今天对做的过程做一个总结。

首先我在做这个问题的时候我用了两种方式,也不是为了一题多解,只是因为第一种方式gem包之间产生了冲突,导致无法使用“axlsx_rails”这个包,哈哈,所以我尝试了另一种,才完成了这个功能。

首先第一种方式,是使用了axlsx_rails这个gem包,具体的方式外国朋友都写的很详细,我就直接上链接了,只要按照要求流程走一遍,基本就可以理解了( 可能需要翻墙)。

https://www.sitepoint.com/generate-excel-spreadsheets-rails-axlsx-gem/

第二种方式:

这里是参考链接:http://railscasts.com/episodes/362-exporting-csv-and-excel

链接中介绍的也比较详细,但是不能满足一些特殊的需求。例如需要动态生成超链接的html代码,访问生成excel的Action时需要动态获取参数并传递给controller,生成excel的数据不是标准的ActiveRecord等。

1,添加config/application.rb

2,确定要访问的链接。

因为我们是动态生成的链接,所有采用rails的“link_to”标签显然不太方便,这时我们就需要看看link_to标签访问的真实的链接。

通过写link_to标签然后通过浏览器查看html代码,我们发现访问的链接实际上就是原路径名加.csv。例如我的路由配置的是”/excel/export_excel”那么,如果想生成csv文件,那么访问”/excel/export_excel.csv”就可以了.

2,配置路由

配置路由和rails配置一样,如果我的路径为”/excel/export_excel.csv”,在routes.rb添加下边代码

namespace :excel do 
    get '/export_excel' => 'excel#check_score_excel'
  end
           

3,修改config/initializers/mime_types.rb ,添加下边代码

Mime::Type.register "application/xls", :xls
           

4,生成excel(csv)数据

由于我的数据牵扯几个表链接和好几层父子关系,自己水平有限,实在不能在一个sql实现,所以生成的数据不是ActiveRecord,而是一个哈希数组.

关于生成数组的形式,我们可以按照Demo(第二个链接)中方式做一遍,然后输出几个关键的数据,”column_names”,”all”,”product.attributes”.

我们会发现column_names实际就是属性名,excel中的列名.all就是所有ActiveRecord记录,我们可以用哈希数组来代替,product.attributes就是数组中哈希,

{id:1,staff:"sxs",date:"2017-4-11",mark:"100"

清楚了这些,我们就可以把我们的数据按照这个格式来替换了.

5,修改to_csv方法

因为我们的数据不再是某个model的方法,所以我就把to_csv方法放到controller中作为一个私有方法

def to_csv(data)

    CSV.generate({}) do |csv|
        csv << ["编号","员工","日期","成绩"]
        data.each do |dd|
          csv << dd.values_at(*["id","staff","date","mark"])
        end
     end
end
           

6,修改action

数据处理每个人都不同,就不写了,最后需要得到的记录是一个哈希数组就可以了.action最后的respond

respond_to do |format|
    format.html
    format.csv { send_data to_csv(@data) }
end
           

7,添加app/views/excel/check_score_excel.xls.erb

<?xml version="1.0"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
  xmlns:o="urn:schemas-microsoft-com:office:office"
  xmlns:x="urn:schemas-microsoft-com:office:excel"
  xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
  xmlns:html="http://www.w3.org/TR/REC-html40">
  <Worksheet ss:Name="Sheet1">
    <Table>
      <Row>
        <Cell><Data ss:Type="String">ID</Data></Cell>
        <Cell><Data ss:Type="String">Name</Data></Cell>
        <Cell><Data ss:Type="String">Release Date</Data></Cell>
        <Cell><Data ss:Type="String">Price</Data></Cell>
      </Row>
    <% @data.each do |product| %>
      <Row>
        <Cell><Data ss:Type="Number"><%= product.id %></Data></Cell>
        <Cell><Data ss:Type="String"><%= product.staff %></Data></Cell>
        <Cell><Data ss:Type="String"><%= product.date %></Data></Cell>
        <Cell><Data ss:Type="Number"><%= product.mark %></Data></Cell>
      </Row>
    <% end %>
    </Table>
  </Worksheet>
</Workbook>
           

8,这样我们访问”/excel/export_excel.csv”(或者/excel/export_excel.csv?start_time=”2017-1-1”&end_time=”2017-2-1”携带条件信息),链接时,就可以下载我们需要的excel文件了.

继续阅读