Rails 3 Wicked PDF - 包括 Paperclip S3 pdf 文件
Rails 3 Wicked PDF - include Paperclip S3 pdf files
我有一个 Rails 3 应用程序使用这些 gems:
gem 'paperclip'
gem 'wicked_pdf'
gem 'combine_pdf'
我正在使用 wicked_pdf
打开 costproject
的 pdf。 costproject
有一个名为 viewproject.pdf.erb
的 HTML 页面。
我正在尝试将 wicked pdf 与 costproject 附件合并为一个 pdf。
这是我的控制器代码:
def viewproject
@costproject = Costproject.find(params[:costproject_id])
respond_to do |format|
format.html
format.pdf do
pdf = CombinePDF.new
pdf2 = render_to_string pdf: "Costproject.pdf", template: "costprojects/viewproject", encoding: "UTF-8"
pdf << CombinePDF.new(pdf2)
@costproject.attachments.each do |attachment|
pdf << CombinePDF.new(attachment.attach.path)
end
send_data pdf.to_pdf, :disposition => 'inline', :type => "application/pdf"
end
end
end
行 pdf << CombinePDF.new(pdf2)
给我:
string contains null byte
如果我查看 pdf2,它的开头是这样的 - 所以它看起来像一个 pdf:
>> pdf2
=> "%PDF-1.4\n1 0 obj\n<<\n/Title (\xFE\xFF)\n/Producer (wkhtmltopdf)\n/CreationDate (D:20150405202628)\n>>\nendobj\n4 0 obj\n<<\n/Type /ExtGState\n/SA true\n/SM 0.02\n/ca 1.0\n/CA 1.0\n/AIS false\n/SMask /None>>\nendobj\n5 0 obj\n[/Pattern /DeviceRGB]\nendobj\n8 0 obj\n<<\n/Type /XObject\n/Subtype /Image\n/Width 71\n/Height 75\n/BitsPerComponent 8\n/ColorSpace /DeviceRGB\n/Length 9 0 R\n/Filter
我也试过了pdf << CombinePDF.new(pdf2.to_pdf)
感谢您的帮助!
更新 1
作为测试,查看 pdf2 是否正常工作,我成功地做到了:
def viewproject
@costproject = Costproject.find(params[:costproject_id])
respond_to do |format|
format.html
format.pdf do
pdf2 = render_to_string pdf: "Costproject.pdf", template: "costprojects/viewproject", encoding: "UTF-8"
send_data pdf2, :disposition => 'inline', :type => "application/pdf"
end
end
end
更新2
Myst 关于使用 parse
的说法是正确的。谢谢!
我现在在控制器代码中使用这一行:
pdf << CombinePDF.new(attachment.attach.url)
我收到这个错误:
No such file or directory - http://s3.amazonaws.com/ ...
但是,如果我复制 http 地址并粘贴到浏览器中,则会显示 pdf。
我正在编辑此答案以反映远程存储 PDF 文件的问题。
我应该指出,如果没有与 S3 存储的持久连接并且没有使用 S3 API,以下解决方案将影响性能*。
正如我所指出的,CombinePDF.new 方法与 CombinePDF.load 方法相同。它接受一个文件名并尝试打开该文件。 CombinePDF.parse 方法将接受原始 PDF 数据并将其解析为 PDF 对象。
在下面的代码中,我使用 Net::HTTP.get(URI.parse(url))
获取原始 PDF 数据。
我建议用S3原生方案替换这个方案,这样整个应用可以共享一个或多个持久连接。这是一个性能问题,对您来说可能重要也可能不重要。
require 'net/http'
def viewproject
@costproject = Costproject.find(params[:costproject_id])
respond_to do |format|
format.html
format.pdf do
pdf = CombinePDF.new
pdf2 = render_to_string pdf: "Costproject.pdf", template: "costprojects/viewproject", encoding: "UTF-8"
pdf << CombinePDF.parse(pdf2)
@costproject.attachments.each do |attachment|
pdf << CombinePDF.parse( Net::HTTP.get( URI.parse( attachment.attach.url ) ) )
end
send_data pdf.to_pdf, :disposition => 'inline', :type => "application/pdf"
end
end
end
* 性能影响取决于您拥有的 PDF 附件数量、您的应用程序拥有的用户数量、网络流量、您的框架 (single/multi-thread) 和其他因素。
持久连接应该可以显着降低性能损失,这主要是因为建立连接是一项昂贵的操作。
我有一个 Rails 3 应用程序使用这些 gems:
gem 'paperclip'
gem 'wicked_pdf'
gem 'combine_pdf'
我正在使用 wicked_pdf
打开 costproject
的 pdf。 costproject
有一个名为 viewproject.pdf.erb
的 HTML 页面。
我正在尝试将 wicked pdf 与 costproject 附件合并为一个 pdf。
这是我的控制器代码:
def viewproject
@costproject = Costproject.find(params[:costproject_id])
respond_to do |format|
format.html
format.pdf do
pdf = CombinePDF.new
pdf2 = render_to_string pdf: "Costproject.pdf", template: "costprojects/viewproject", encoding: "UTF-8"
pdf << CombinePDF.new(pdf2)
@costproject.attachments.each do |attachment|
pdf << CombinePDF.new(attachment.attach.path)
end
send_data pdf.to_pdf, :disposition => 'inline', :type => "application/pdf"
end
end
end
行 pdf << CombinePDF.new(pdf2)
给我:
string contains null byte
如果我查看 pdf2,它的开头是这样的 - 所以它看起来像一个 pdf:
>> pdf2
=> "%PDF-1.4\n1 0 obj\n<<\n/Title (\xFE\xFF)\n/Producer (wkhtmltopdf)\n/CreationDate (D:20150405202628)\n>>\nendobj\n4 0 obj\n<<\n/Type /ExtGState\n/SA true\n/SM 0.02\n/ca 1.0\n/CA 1.0\n/AIS false\n/SMask /None>>\nendobj\n5 0 obj\n[/Pattern /DeviceRGB]\nendobj\n8 0 obj\n<<\n/Type /XObject\n/Subtype /Image\n/Width 71\n/Height 75\n/BitsPerComponent 8\n/ColorSpace /DeviceRGB\n/Length 9 0 R\n/Filter
我也试过了pdf << CombinePDF.new(pdf2.to_pdf)
感谢您的帮助!
更新 1
作为测试,查看 pdf2 是否正常工作,我成功地做到了:
def viewproject
@costproject = Costproject.find(params[:costproject_id])
respond_to do |format|
format.html
format.pdf do
pdf2 = render_to_string pdf: "Costproject.pdf", template: "costprojects/viewproject", encoding: "UTF-8"
send_data pdf2, :disposition => 'inline', :type => "application/pdf"
end
end
end
更新2
Myst 关于使用 parse
的说法是正确的。谢谢!
我现在在控制器代码中使用这一行:
pdf << CombinePDF.new(attachment.attach.url)
我收到这个错误:
No such file or directory - http://s3.amazonaws.com/ ...
但是,如果我复制 http 地址并粘贴到浏览器中,则会显示 pdf。
我正在编辑此答案以反映远程存储 PDF 文件的问题。
我应该指出,如果没有与 S3 存储的持久连接并且没有使用 S3 API,以下解决方案将影响性能*。
正如我所指出的,CombinePDF.new 方法与 CombinePDF.load 方法相同。它接受一个文件名并尝试打开该文件。 CombinePDF.parse 方法将接受原始 PDF 数据并将其解析为 PDF 对象。
在下面的代码中,我使用 Net::HTTP.get(URI.parse(url))
获取原始 PDF 数据。
我建议用S3原生方案替换这个方案,这样整个应用可以共享一个或多个持久连接。这是一个性能问题,对您来说可能重要也可能不重要。
require 'net/http'
def viewproject
@costproject = Costproject.find(params[:costproject_id])
respond_to do |format|
format.html
format.pdf do
pdf = CombinePDF.new
pdf2 = render_to_string pdf: "Costproject.pdf", template: "costprojects/viewproject", encoding: "UTF-8"
pdf << CombinePDF.parse(pdf2)
@costproject.attachments.each do |attachment|
pdf << CombinePDF.parse( Net::HTTP.get( URI.parse( attachment.attach.url ) ) )
end
send_data pdf.to_pdf, :disposition => 'inline', :type => "application/pdf"
end
end
end
* 性能影响取决于您拥有的 PDF 附件数量、您的应用程序拥有的用户数量、网络流量、您的框架 (single/multi-thread) 和其他因素。
持久连接应该可以显着降低性能损失,这主要是因为建立连接是一项昂贵的操作。