Ruby:使用group方法时将PDF拖出内存 [英] Ruby: Prawn PDF out of memory when using the group method
问题描述
我想在pdf中显示大量产品,并带有类别标题.如果某个类别不适用于当前页面,我想将其移至下一页.为此,我使用了Prawn的分组方法.
I have a large number of products I want to display in a pdf, with category headers. If a category doesn't fit on the current page I want to move it to the next. For this I'm using Prawn's group method.
Product.all.group_by(&:category).each do |category, products|
pdf.group do
# Simplified the data a bit for this example
pdf.text category
pdf.table products.map{ |p| [p.title, p.price] }
end
end
这对于少量产品非常有效,但是当我添加100多个产品时,它会花费很长时间,然后以分配内存失败"结束.如果我不使用分组方法,则大约需要30秒.
This works very well for small amounts of products, but when I add more than 100 or so it takes a very long time and then ends in "failed to allocate memory". If I don't use the group method it takes about 30 seconds.
显然,group方法不能很好地管理其内存使用情况.任何解决方法的建议将不胜感激.
Clearly the group method does not manage its memory usage very well. Any suggestions for workarounds would be appreciated.
推荐答案
----------更新的答案--------
---------- UPDATED ANSWER --------
以前的解决方法对于生产服务器来说还不够好,所以我不得不使用git repo的开发版本,将其作为子模块安装在vendor/prawn下,如下所示:
The previous workaround wasn't good enough for the production server, so I had to use development version from git repo installed as a submodule under vendor/prawn, as described here: https://github.com/sandal/prawn/wiki/Using-Prawn-in-Rails
group方法的内存问题已消失,但事物的语法/选项已有所更改.所以我不得不重写代码以生成PDF.
The memory issue with the group method is gone, but the syntax/options for things have changed somewhat. So I had to rewrite the code to generate PDF.
此外,要使子模块与Rails应用程序的git repo很好地配合也很困难.部署到生产环境很困难.
Also, getting the submodule to play nicely with the git repo for the Rails app is difficult. Deployment to production was tough.
----------原始答案--------
---------- ORIGINAL ANSWER --------
这不是一个解决方法,但是它使问题在表现出来之前还需要进行几次小组迭代:
This isn't a fix, but it makes the problem take a few more group iterations before it manifests itself:
- 覆盖名为"group"的Prawn :: Document实例方法
- 使用最新开发的prawn版本(来自github.com)的'group'函数中的代码
我这样做的方法是,我在Rails应用程序的/lib文件夹中添加了一个文件.该文件将包含大虾"宝石,并定义了PDF文档的mime类型:
The way I did this is that I added a file to the /lib folder of my Rails app. This file will include the Prawn gems and defined the mime type for a PDF document:
class PdfPrawn
require 'prawn'
require 'prawn/core'
require 'prawn/table'
MIME_TYPE = "application/pdf"
end
class Prawn::Document
def group(second_attempt=false)
old_bounding_box = @bounding_box
@bounding_box = SimpleDelegator.new(@bounding_box)
def @bounding_box.move_past_bottom
raise RollbackTransaction
end
success = transaction { yield }
@bounding_box = old_bounding_box
unless success
raise Prawn::Errors::CannotGroup if second_attempt
old_bounding_box.move_past_bottom
group(second_attempt=true) { yield }
end
success
end
end
然后,在模型文件中,我定义了一种方法来生成PDF并使用如下格式:
And then in a model file, I define a method to generate my PDF and use something like this:
def to_pdf
require "#{File.expand_path(RAILS_ROOT)}/lib/pdf_prawn"
pdf = Prawn::Document.new
# code to add stuff to PDF
pdf.render
end
这篇关于Ruby:使用group方法时将PDF拖出内存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!