问题
This is what the documentation of wicked pdf specifies:
WickedPdf.new.pdf_from_string(
render_to_string(:pdf => "pdf_file.pdf", :template => 'templates/pdf.html.erb', :layout => 'pdfs/layout_pdf'),
:footer => {:content => render_to_string({:template => 'templates/pdf_footer.html.erb', :layout => 'pdfs/layout_pdf'})}
)
What i get is ActionView::MissingTemplate Even though i have pdf.html.erb in directory. I use a gen_pdf method in the application controller and an equivalent pdf.html.erb in the views/application folder. What am i missing.
回答1:
Don't Use template
.
I ran into the same problem as you. You have to render your PDF quite differently when you're doing it in a Controller action as opposed to a Mailer or something else.
First off, using template
won't work. There's some other nuances but here is my implementation you can build off of:
notification_mailer.rb
def export
header_html = render_to_string( partial: 'exports/header.pdf.erb',
locals: { report_title: 'Emissions Export' } )
body_html = render_to_string( partial: "exports/show.pdf.erb" )
footer_html = render_to_string( partial: 'exports/footer.pdf.erb' )
@pdf = WickedPdf.new.pdf_from_string( body_html,
orientation: 'Landscape',
margin: { bottom: 20, top: 30 },
header: { content: header_html },
footer: { content: footer_html } )
# Attach to email as attachment.
attachments["Export.pdf"] = @pdf
# Send email. Attachment assigned above will automatically be included.
mail( { subject: 'Export PDF', to: 'elon@musk.com' } )
end
回答2:
If you are using wicked_pdf and try to generate pdf outside of controller (i.e. in a cron job) you can do it this way (raild 4.1 +):
# app/renderers/pdf_renderer.rb
class PdfRenderer < ActionController::Metal
include ActionView::ViewPaths
include AbstractController::Rendering
include AbstractController::Helpers
include ActionController::Helpers
include ActionView::Rendering
include ActionView::Layouts
include ActionController::Rendering
include ActionController::Renderers
include ActionController::Renderers::All
append_view_path "app/views"
View = Struct.new(:layout, :template, :locals)
def render_pdf(view)
wicked = WickedPdf.new
pdf_string = render_to_string(template: view.template, layout: view.layout, locals: view.locals)
# Make a PDF in memory
pdf_file = wicked.pdf_from_string(pdf_string, pdf: "pdf_name",
page_size: 'A4',
wkhtmltopdf: ENV['WKHTMLTOPDF_EXECUTABLE_PATH'],
margin: { top: '0.5in', bottom: '1in', left: '0.5in', right: '0.5in'}
)
# Write it to tempfile
tempfile = Tempfile.new(['document', '.pdf'], Rails.root.join('tmp'))
tempfile.binmode
tempfile.write pdf_file
tempfile.close
tempfile
end
end
and call this method:
renderer = PdfRenderer.new
pdf_view = PdfRenderer::View.new.tap do |v|
v.template = "postal/#{template_file}.pdf.erb"
v.layout = 'layouts/layout.pdf.erb'
v.locals = {:user=> @user, :other_stuff => @details}
end
temp_pdf = renderer.render_pdf pdf_view
now you can use temp_pdf.path
to do whatever you want with this file (i.e. send email)
you can read more about this way here: http://blog.arkency.com/2014/03/pdf-in-rails-without-controllers/
回答3:
You can have something like this inside your mailer:
class ReportMailer < ActionMailer::Base
default :from => DEFAULT_FROM
def report_pdf(user, bookings)
@bookings = booking
@user = user
mail(:subject => 'Overtime', :to => user.email) do |format|
format.text # renders overtime_pdf.text.erb for body of email
format.pdf do
attachments['monthly_report.pdf'] = WickedPdf.new.pdf_from_string(
render_to_string(:pdf => 'monthly_report', :template =>
'hospital_bookings/index.pdf.erb', :layouts => 'pdf.html')
)
end
end
end
end
Hope this helps. Also if you want further help it would be ideal to post some of your code so that others can gain better understanding on what you have done and what your trying to achieve.
来源:https://stackoverflow.com/questions/15972189/what-is-the-correct-way-to-render-to-string-in-wicked-pdf