Ruby on Rails 中的 send_data 与电子表格插件结合使用时遇到困难

发布于 2024-09-27 20:17:48 字数 1369 浏览 4 评论 0原文

我在控制器中有一个函数,它接受一些规范并生成有关它们的报告。这个函数 user_report 在视图中调用:

< %= Submit_to_remote '提交按钮', "将报告导出到 Excel", :url => {:控制器=> :报告,:行动 => :user_report, :print_state => '打印'} % >

在 reports_controller 中,我使用电子表格插件在 user_report 函数中生成 Excel 文件。我想使用 send_data 将文件流式传输给用户,而不先在服务器上创建它。我所做的研究表明,使用 StringIO 是可行的方法,如下所示。令人沮丧的是,当我调用 send_data 时没有任何反应。该插件似乎可以很好地创建文件并将其保存在服务器上,但当我使用 send_file 时什么也不做,这表明问题不在于插件。但是我对 send_file/send_data 做错了什么?

该函数本身如下所示:

定义用户报告

if request.post?
  unless params[:reports][:userid].blank?
    @userid=params[:reports][:userid]
  end
  if params[:print_state]=='print'  

    report = Spreadsheet::Workbook.new
    info = report.create_worksheet :name => 'User Information'
    info.row(1).push 'User ID', @userid

    @outfile = "Report_for_#{@userid}.xls"

    require 'stringio'
    data = StringIO.new ''
    report.write data
    send_data data.string, :type=>"application/excel", :disposition=>'attachment', :filename => @outfile
  end

  respond_to do |format|
    format.js { }
  end
end

结束

日志文件读取 2010-10-18 14:13:59 INFO -- 发送数据 Report_for_jjohnson.xls 但浏览器中没有开始下载。我之前曾在这个应用程序上成功使用过 send_data ,这很令人困惑。

我正在电子表格.rubyforge.org 上使用 Rails v2.3、Ruby v1.8.7 和 Spreadsheet v6.4.1。

I have a function in a controller that takes in some specifications and generates a report on them. This function user_report is called in a view:

< %= submit_to_remote 'submit-button', "Export Report to Excel", :url => { :controller => :reports, :action => :user_report, :print_state => 'print'} % >

In reports_controller I use the Spreadsheet plugin to generate an Excel file within the user_report function. I want to use send_data to stream the file to the user without creating it on the server first. The research I've done shows that using StringIO is the way to go, as shown below. Frustratingly, nothing happens when I call send_data. The plugin seems to work well creating a file and saving it on the server, but does nothing when I use send_file, suggesting that the problem doesn't lie in the plugin. But then what am I doing wrong with send_file/send_data?

The function itself looks like this:

def user_report

if request.post?
  unless params[:reports][:userid].blank?
    @userid=params[:reports][:userid]
  end
  if params[:print_state]=='print'  

    report = Spreadsheet::Workbook.new
    info = report.create_worksheet :name => 'User Information'
    info.row(1).push 'User ID', @userid

    @outfile = "Report_for_#{@userid}.xls"

    require 'stringio'
    data = StringIO.new ''
    report.write data
    send_data data.string, :type=>"application/excel", :disposition=>'attachment', :filename => @outfile
  end

  respond_to do |format|
    format.js { }
  end
end

end

The log file reads
2010-10-18 14:13:59 INFO -- Sending data Report_for_jjohnson.xls
but no download begins in-browser. I've succeed in using send_data on this app before, which is confusing.

I'm using Rails v2.3, Ruby v1.8.7, and Spreadsheet v6.4.1 at spreadsheet.rubyforge.org.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

薄暮涼年 2024-10-04 20:17:48

只需将行:更改

send_data data.string, :type=>"application/excel", :disposition=>'attachment', :filename => @outfile

为:

send_data data.string.bytes.to_a.pack("C*"), :type=>"application/excel", :disposition=>'attachment', :filename => @outfile

Just change the line:

send_data data.string, :type=>"application/excel", :disposition=>'attachment', :filename => @outfile

to:

send_data data.string.bytes.to_a.pack("C*"), :type=>"application/excel", :disposition=>'attachment', :filename => @outfile
梦与时光遇 2024-10-04 20:17:48

对于 2022 年(或之后)关注此问题的人来说,可能的解决方案是使用 Axlsx Gem。该接口提供了将其转换为 StringIO 对象的方法。 (来自 Axlsx 文档

#serialize to a file
p = Axlsx::Package.new
# ......add cool stuff to your workbook......
# Serialize to a stream
s = p.to_stream()
send_data(
      s.read,
      :type => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
      :disposition => 'attachment',
      :filename => @filename
)

For someone looking at this in (or after) 2022, a possible solution to this would be to use Axlsx Gem. The interface provides a method for converting it to a StringIO object. (From Axlsx Documentation)

#serialize to a file
p = Axlsx::Package.new
# ......add cool stuff to your workbook......
# Serialize to a stream
s = p.to_stream()
send_data(
      s.read,
      :type => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
      :disposition => 'attachment',
      :filename => @filename
)
过去的过去 2024-10-04 20:17:48

尽管我不喜欢写入和删除,但使用电子表格似乎是唯一的解决方案。


  # write the file

 book.write "Employee_History_#{ params[:id]}.xls"

 # send the file

 send_file "Employee_History_#{ params[:id]}.xls", :type => "application/vnd.ms-excel", :filename => "data.xls", :stream => false

 # and then delete the file

 File.delete("Employee_History_#{ params[:id]}.xls")

Even though I dont like to write and delete , but with spreadsheet seems like the only solution.


  # write the file

 book.write "Employee_History_#{ params[:id]}.xls"

 # send the file

 send_file "Employee_History_#{ params[:id]}.xls", :type => "application/vnd.ms-excel", :filename => "data.xls", :stream => false

 # and then delete the file

 File.delete("Employee_History_#{ params[:id]}.xls")
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文