【问题标题】:Rails 3 Wicked PDF - include Paperclip S3 pdf filesRails 3 Wicked PDF - 包括 Paperclip S3 pdf 文件
【发布时间】:2015-04-04 15:56:06
【问题描述】:

我有一个使用这些 gem 的 Rails 3 应用程序:

gem 'paperclip'
gem 'wicked_pdf'
gem 'combine_pdf'

我正在使用wicked_pdf 打开costproject 的pdf。 costproject 有一个名为 viewproject.pdf.erb 的 HTML 页面。

我正在尝试将邪恶的 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 &lt;&lt; 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 &lt;&lt; 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。

【问题讨论】:

    标签: ruby-on-rails paperclip wicked-pdf


    【解决方案1】:

    我正在编辑此答案以反映远程存储 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 附件数量、您的应用拥有的用户数量、网络流量、您的框架(单/多线程)和其他因素。

    持久连接应该以显着的方式降低性能损失,主要是因为建立连接是一项昂贵的操作。

    【讨论】:

    • 您使用parse 是正确的。但是,现在我有一个问题,它可以在本地工作 - 因为我将附件 PDF 保存在 Rails 中,但在 Heroku 上,我使用 S3。我正在为 `pdf 尝试不同的代码
    • 您通常如何从 S3 层访问原始文件内容?它是本地安装的吗?您是否使用特定的 API?
    • 你试过pdf &lt;&lt; CombinePDF.new(attachment.attach.path) 吗?
    • 如果 pdf 存储在 Rails 中,attachemnt.attach.path 将起作用。当它们存储在 S3 中时它不起作用。
    猜你喜欢
    • 1970-01-01
    • 2016-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多