Ruby on rails 我是否可以将http流与axlsx_rails一起使用,以避免大型/时间密集型查询的超时问题?
我正在使用Rails4.2.5中的RubyGem生成一个Excel文件,让用户下载他们的数据 我在index.xlsx.axlsx模板中有以下内容:Ruby on rails 我是否可以将http流与axlsx_rails一起使用,以避免大型/时间密集型查询的超时问题?,ruby-on-rails,ruby,excel,ruby-on-rails-4,axlsx,Ruby On Rails,Ruby,Excel,Ruby On Rails 4,Axlsx,我正在使用Rails4.2.5中的RubyGem生成一个Excel文件,让用户下载他们的数据 我在index.xlsx.axlsx模板中有以下内容: wb = xlsx_package.workbook wb.add_worksheet(name: 'Transactions') do |sheet| sheet.add_row ["Date", "Vendor Name", "Account", "Transaction Category",
wb = xlsx_package.workbook
wb.add_worksheet(name: 'Transactions') do |sheet|
sheet.add_row ["Date", "Vendor Name", "Account",
"Transaction Category",
"Amount Spent", "Description"]
@transactions.find_each(batch_size: 100) do |transaction|
sheet.add_row [transaction.transaction_date,
transaction.vendor_name,
transaction.account.account_name,
transaction.transaction_category.name,
transaction.amount,
transaction.description]
end
end
如果有足够的数据,则在返回Excel文件之前,页面将超时。有没有一种方法可以在处理过程中使用HTTP流将结果发送回,而不是等到整个事务完成。查找每个循环是否已完成
我看到了使用response.stream.write的代码:
response.headers['Content-Type'] = 'text/event-stream'
10.times {
response.stream.write "This is a test message"
sleep 1
}
response.stream.close
这种方法看起来很有希望,但我不知道如何将response.stream.write集成到axlsx_rails模板中。有办法吗
这是我的第一个堆栈溢出问题-为任何失礼道歉,并感谢您提供的任何想法 欢迎来到SO,乔
我在评论中问道,但也许最好回答和解释一下
简单的回答是,是的,如果可以渲染,则始终可以流式处理(尽管有时会产生混合的性能结果)
但是,如果您直接引用文件,则它不起作用。IE,http://someurl.com/reports/mycustomreport.xlsx
rails中的流媒体只是默认情况下并不是这样构建的。但不要担心,只要您希望节省的时间仅用于渲染,您“应该”仍然能够解决您的问题
在控制器中(*注意,将来,当您询问渲染操作时,提供控制器操作代码*)有助于您执行类似操作:
def report
@transactions = current_user.transactions.all
respond_to do |format|
format.html { render xlsx: 'report', stream: true}
end
end
可能有助于对您的加载进行健全检查。在您的日志中,作为200响应的一部分,您应该得到如下信息:
在506ms内完成200 OK(视图:494.6ms |活动记录:2.8ms)
如果活动记录编号过高,或高于视图编号,此解决方案可能无法用于您的查询,并且正如建议的那样,这可能需要线程化或发送到作业。即使您可以流式处理,我认为它也不会更快。问题是Axlsx在构建完电子表格之前不会生成电子表格。而axlsx_rails只是包装了这个过程,所以也不会有任何帮助。因此,将不会有部分电子表格以bits形式提供,延迟也将同样长 你应该咬紧牙关,试试(速度非常快)或者其他的作业调度程序。然后您可以立即返回请求并在后台生成电子表格。您必须执行某种监视或通知来获取生成的报告,或者使用javascript ping返回到另一个url,当在render complete上设置标志时,该url将转发到新页面。你的电话在那里 当您需要发送电子邮件以响应请求时,拥有作业调度器也非常方便;回复可以立即返回,而不必等待电子邮件完成。一旦你有了一个调度器,你会发现它有更多的用途
如果您选择作业调度器,axlsx_rails将允许您,或者您可以。或者对于呈现模板的简单方式,.您是在url中调用文件名还是在控制器中使用呈现块?谢谢,@trh!我在控制器代码中使用了respond_to:在这种情况下,我认为是ActiveRecord查询占用了所有的时间。这是一个很好的答案,谢谢!我的控制器会超时约15k行,查询速度会非常快,但创建文件所需的时间太长,而这会导致技巧性的错误,@Noel和@Jamie!我来看看Sidekiq。由于我只使用axlsx的基本功能(基本上,我只是在寻找一个美化的csv,在这里我不必转义逗号和换行符等),我可以尝试在自己的代码中为Excel文档构建xml,这样我就可以一行一行地流出来。流式csv听起来是一个可行的解决方案。Railscasts提供了一些很好的教程,例如: