【问题标题】:Rails 3 -Render PDF from view and attach to emailRails 3 - 从视图中渲染 PDF 并附加到电子邮件
【发布时间】:2011-08-11 09:06:21
【问题描述】:

我一直在使用 Wicked_pdf 将视图呈现为 PDF 并使用 actionmailer 来发送电子邮件,但我无法让它们一起工作。我想使用 actionmailer 将某个视图的 PDF 版本附加到电子邮件中,然后通过单击链接或按钮将其发送出去。我有一个发送电子邮件的 link_to 命令。这是生成电子邮件的控制器:

def sendemail
 @user = User.find(params[:id])
 Sendpdf.send_report(@user).deliver
 redirect_to user_path(@user)
 flash[:notice] = 'Email has been sent!'
end  

这是我的 actionmailer 中的内容:

class Sendpdf < ActionMailer::Base
default :from => "myemail@email.com"

def send_report(user)
@user = user
  attachment "application/pdf" do |a|
  a.body = #Something should go here, maybe WickedPDF.new.something?
  a.filename = 'MyPDF'
end     
mail(:to => user.email, :subject => "awesome pdf, check it")
end

end

我见过很多问题和答案,大部分都是关于虾的。似乎应该有一个简单的答案。有人可以帮忙吗?

更新我很感谢在下面的答案中提出建议作为替代选项。但是,我真的很想学习如何将视图呈现为 PDF 并将其附加到我的电子邮件中。如果需要,我愿意使用不同的东西,比如 Prawn 或其他任何东西。

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 pdf-generation actionmailer wicked-pdf


    【解决方案1】:

    2 种按照您想要的方式执行此操作的好方法:

    1:在控制器中创建 pdf,然后将其作为参数发送到电子邮件。

    # controller
    def sendemail
      @user = User.find(params[:id])
      pdf = render_to_string :pdf => 'MyPDF'
      Sendpdf.send_report(@user, pdf).deliver
      redirect_to user_path(@user)
      flash[:notice] = 'Email has been sent!'
    end
    
    # mailer
    def send_report(user, pdf)
      @user = user
      attachments['MyPDF.pdf'] = pdf
      mail(:to => user.email, :subject => "awesome pdf, check it")
    end
    

    2:直接在mailer中创建pdf(有点复杂,但可以从模型中调用)

    def send_report(user)
      @user = user
      mail(:to => user.email, :subject => "awesome pdf, check it") do |format|
        format.text # renders send_report.text.erb for body of email
        format.pdf do
          attachments['MyPDF.pdf'] = WickedPdf.new.pdf_from_string(
            render_to_string(:pdf => 'MyPDF',:template => 'reports/show.pdf.erb')
          )
        end
      end
    end
    

    【讨论】:

    • 感谢您回答这个问题。我最终做的是创建一个将 pdf 保存到文件的操作。然后在发送邮件的操作中,我调用了此操作,将其附加到电子邮件中,然后将其从文件中删除。这是一个不好的方法吗?效果很好。
    • 不错的方法,但有时不需要写入文件系统,例如在 Heroku 上。另外,请注意您的文件不能被其他进程移动或删除。
    • @Unixmonkey 补充一点,我注意到大多数关于 WickedPDF 的答案都来自您。我已经搜索了你所有的答案,并进行了以下设置:gist.github.com/anonymous/5229508 但似乎无法确定。我尝试过的每个解决方案似乎都给了我一个Template is missing。期待您的回复。
    • 如何将变量传递给 render_to_string 中的模板?
    • @CodecPM render_to_string(pdf: 'MyPDF', template: 'reports/show.pdf.erb', locals: { var_1: 'variable 1' }) 将使 Variable: &lt;%= var_1 %&gt; 可用于 erb 模板。
    【解决方案2】:

    有两种方法。

    1. 或者,您希望将 pdf 嵌入到您发送的电子邮件中,这样当用户从电子邮件中下载 pdf 时,没有请求为您各自的控制器渲染新的 pdf 操作。 我不知道如何有效地做到这一点,因为我以前从未这样做过。

    2. 或者,您只需在电子邮件中提供指向 pdf 的链接,当用户单击它时,现在会调用创建 pdf 的操作,然后用户可以下载它。
      这样,如果服务器上下载 pdf 的负担很大,您可以将这些请求重定向到其他地方。简而言之,效率的空间很大。

    第二种方法的示例代码(提供的代码是使用PDFkit编写的,因此请相应更改):

    class PdfsController < ApplicationController
      def pdf
        respond_to do |format|
          format.pdf { render :text => wickedPDF.new( Pdf.find(params[:id]).content ).to_pdf }
        end
      end
    ...
    end
    

    根据您的选择替换 Pdf.find(params[:id]).content,并根据 wickedPDF 替换 to_pdf 方法。

    然后,您可以像这样在电子邮件中简单地传递 pdf 下载的链接

    <%= link_to "Download", pdf_pdf_path(pdf, :format => "pdf") %>
    

    或任何适合 wickedPDF 的东西。

    【讨论】:

    • 那是个不错的选择,其实我没有想到。如果我有选择,我想将 PDF 附加到电子邮件中,但在我弄清楚之前,在电子邮件中放置“下载”链接是个好主意,谢谢!
    • 这没有回答提出的问题。解决方法通常最适合用于 cmets,而不是答案。
    猜你喜欢
    • 2017-11-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    相关资源
    最近更新 更多