You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails使用caxlsx调用send_file导出Excel未下载直接在浏览器显示乱码

问题原因
  • 视图层link_to默认是普通页面跳转,未指定download属性,浏览器会默认尝试解析响应内容,而非触发下载
  • 控制器中设置的MIME类型错误:application/vnd.ms-excel是旧版.xls格式的MIME类型,.xlsx格式正确的MIME类型为application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,类型识别错误会导致浏览器直接展示二进制流内容
  • 固定的临时文件路径#{Rails.root}/tmp/basic.xlsx存在并发冲突风险,多用户同时导出时文件内容会被覆盖,也可能引发响应异常
  • 部分场景下Rails UJS的异步请求处理会干扰下载响应的识别
解决方案

1. 修改视图层链接配置

给link_to添加download属性,同时禁用异步请求处理,Rails 5.2版本修改为:

link_to '导出买家列表', export_customers_buyers_path, download: true, data: { remote: false }

2. 修正控制器导出逻辑

  • 更换为正确的MIME类型,显式指定disposition: 'attachment'强制下载
  • 推荐直接返回流式内容,省略本地文件写入步骤,避免并发冲突,修改后控制器代码如下:
def export_customers
  @customers = @client.customers
  package = Axlsx::Package.new
  workbook = package.workbook
  field = []
  field_new = []
  @client.custom_field_hstore.each do |field_name, _is_reuire|
    field << field_name
    field_new << field_name
  end
  workbook.add_worksheet(name: 'Buyers List') do |sheet|
    sheet.add_row(['S.No'] + field.first(15))
    @customers.each_with_index do |customer, index|
      row = [index + 1]
      row.concat field_new.first(15).map { |f| customer.customer_detail_hstore[f] }
      sheet.add_row row
    end
  end
  # 直接返回流,无需写入本地文件
  send_data package.to_stream.read, 
    filename: 'Buyers.xlsx', 
    type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
    disposition: 'attachment'
end

如果确实需要保留本地文件存储逻辑,使用临时文件避免并发覆盖:

temp_file = Tempfile.new(['buyers_', '.xlsx'], Rails.root.join('tmp'))
package.serialize(temp_file.path)
send_file temp_file.path, 
  filename: 'Buyers.xlsx', 
  type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
  disposition: 'attachment'
temp_file.close
temp_file.unlink # 请求处理完成后自动删除临时文件

3. 可选配置路由规则

如果项目路由配置了格式限制,给导出路由添加对xlsx格式的支持:

get 'export_customers', to: 'buyers#export_customers', defaults: { format: 'xlsx' }

内容的提问来源于stack exchange,提问作者JV Rasool

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.23 17:06:03