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: <%= var_1 %>
可用于 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 并附加到电子邮件的主要内容,如果未能解决你的问题,请参考以下文章