昨天遇到生成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
require 'csv'
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文件了.