What is the correct way to render_to_string in wicked pdf?

好久不见. 提交于 2019-12-10 20:12:38

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!