# For dealing with exel
gem 'caxlsx'
gem 'caxlsx_rails'
参考: https://github.com/caxlsx/caxlsx_rails
Axlsx-Rails 提供了一个 renderer 和一个 template handler. 它添加了一个新的 format :xlsx,并且可以解析 .xlsx.axlsx 模版。
在控制器层,可以处理 :xlsx format 的请求:
class ButtonController < ApplicationController
def action_name
@buttons = Button.all
respond_to do |format|
format.xlsx
end
end
end
然后我们需要提供一个模版,根据 convention,它的名字需要是这样: action_name.xlsx.axlsx
wb = xlsx_package.workbook
wb.add_worksheet(name: "Buttons") do |sheet|
@buttons.each do |button|
sheet.add_row [button.name, button.category, button.price]
end
end
然后我们就可以通过请求,直接下载 excel 文件
$(".export-consumers").on('click', (e) =>{
e.preventDefault();
$.ajax({
method: 'GET',
dataType: 'json',
url: `/admin/consumers.js?campaign_id=${e.currentTarget.dataset.campaignId}`
}).done((response) => {
window.location = `/admin/consumers/download-consumers?file_name=${response.exported_file_name}`;
}).fail((msg) => {
alert('Export Failed');
})
});
respond_to do |format|
format.js do
@consumers = consumers
exported_file_name = Admin::XlsxGeneration.new(@consumers, @current_campaign_id).build_tw_consumers_xlsx
render json: {exported_file_name: exported_file_name}
end
end
def download_consumers
send_file Rails.root.join("tmp", "#{params[:file_name]}.xlsx"), type: :xlsx, filename: "#{params[:file_name]}.xlsx"
end
对于异步形式的下载,上面示例的方案是先生成临时文件,返回文件名,然后再异步的下载这个文件。这个方案经过验证,有效可行。
对于异步的情况我还有一个想法,就是在后端不生成文件,直接通过send_data
异步返回文件,但是我没有成功,因为在前端的 callback( done ) 中,没法拿到send_data
返回的文件数据。不知道有人尝试过没?