Rails 3 - 从视图中渲染 PDF 并附加到电子邮件

Posted

技术标签:

【中文标题】Rails 3 - 从视图中渲染 PDF 并附加到电子邮件【英文标题】:Rails 3 -Render PDF from view and attach to email 【发布时间】: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 或其他任何东西。

【问题讨论】:

【参考方案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】:

有两种方法。

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

    或者,您只需在电子邮件中提供指向 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,而不是答案。

以上是关于Rails 3 - 从视图中渲染 PDF 并附加到电子邮件的主要内容,如果未能解决你的问题,请参考以下文章

使用 Rails 5.2 ActiveStorage 创建和保存 pdf 并稍后附加到电子邮件

从 Rails 3 生成 pdf - 选择啥工具?

添加附件会破坏邮件内容轨道

在rails中相同模型的新视图中附加表单部分

Rails jquery移动路由/渲染问题

为啥 Rails 渲染视图如此缓慢?