【问题标题】:Attach Prawn pdf to email将虾 pdf 附加到电子邮件
【发布时间】:2016-04-08 03:28:58
【问题描述】:

我一直在寻找,但我似乎仍然无法弄清楚,

我目前正在使用prawn gem,我希望能够在我的invoice controllers create action 中将pdf 附加到email。我目前能够通过http://localhost:3000/invoices/297.pdf 链接到我的invoices/show 页面生成的pdf,但我不知道如何将此pdf 附加到电子邮件中。

目前我没有将生成的 PDF 存储在任何地方,我的邮件看起来像这样

邮递员

class InvoiceMailer < ActionMailer::Base
default :from => "notifications@example.com"

 def invoice_email(user)
   @user = user
   mail(:to => user.email, :subject => "Invoice Recieved")
 end
end

我的 InvoicesController 创建操作

{...}
respond_to do |format|
  if @invoice.save
    InvoiceMailer.invoice_email(@invoice.user).deliver
    format.html { redirect_to invoice_url(@invoice, back_path: 
{...}

如何将我的发票作为附件添加到此邮件中?我是否需要先将发票存储在某个地方才能发送?

【问题讨论】:

    标签: ruby-on-rails actionmailer prawn


    【解决方案1】:

    您如何执行此操作取决于 PDF 生成需要多长时间和/或它在您的服务器上放置多少负载,以及您是否关心这些。在我的例子中,我从用户生成的内容生成 PDF,我看到一些 PDF 创建时间在 30 多秒的范围内。解决这个问题变成了在其他地方运行作业和缓存(无论是数据库还是云存储)问题。

    @toddmetheny 非常正确地建议除了最简单的解决方案之外的所有解决方案都使用云存储。如果您使用临时存储托管在 Heroku 之类的东西上,或者如果您将 PDF 创建与从用户请求发送的电子邮件中分离(例如再次从 Heroku,web dynos 与 worker dynos),它会变得更有趣。您可以将 PDF 生成为本地临时文件,但当您需要在运行在“工作人员”上的 Mailer 中读取它时,该临时文件可能不存在。

    非常简单的选择

    在您的 Mailer 中,您可以将 PDF 生成到本地文件,将其读回内存,然后附加:

    def invoice_email(user)
      @user = user
    
      attachments['filename_for_user.pdf'] = generate_pdf_content
    
      mail(:to => user.email, :subject => "Invoice Recieved")
    end
    
    private
    
      # I had troubles trying to get Prawn to generate 'in memory'
      # so just write to, then read, then unlink a tempfile
      def generate_pdf_content
        pdf = some_method_that_generates_a_prawn_pdf_object
        Tempfile.create do |f|
          pdf.render_file f
          f.flush
          File.read(f)
        end
      end
    

    我建议你从这里开始让事情顺利进行。

    更复杂的选项

    有一天,您可能希望将生成 PDF 的作业(可能需要很长时间)与发送电子邮件的作业分开,后者通常要快得多。我这样做的方法是有一个将 PDF 生成到本地 Tempfile 的作业,然后将该文件上传到 S3 存储并记录 S3 对象 ID(我在我的数据库中执行此操作,您可以将其作为您的作业属性来执行推来推去)。

    完成后,该作业会创建一个新的邮件程序作业。邮件程序作业(可能在不同的服务器上执行)将 PDF 从 S3 存储下载到本地文件,然后将其添加到电子邮件中,就像上面的简单选项一样。

    【讨论】:

      【解决方案2】:

      您需要一个可以使用的网址。如果您不想将其存储在数据库中,则可以选择任何云存储解决方案。

      这里有一些关于从rails guides on action mailer向邮件中添加附件的相关信息:

      2.3.1 添加附件

      Action Mailer 使添加附件变得非常容易。

      传递文件名和内容,Action Mailer 和 Mail gem 会自动猜测 mime_type,设置编码并创建附件。

      attachments['filename.jpg'] = File.read('/path/to/filename.jpg')
      

      当邮件方法被触发时,它会发送一封带有附件的多部分电子邮件,正确嵌套,顶层是多部分/混合,第一部分是包含纯文本和 HTML 电子邮件消息的多部分/替代。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-11-21
        • 2016-01-18
        • 1970-01-01
        • 1970-01-01
        • 2016-09-28
        • 2011-12-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多