Каков правильный способ render_to_string в злом pdf?

Вот что указывает документация wicked pdf:

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'})}
)   

Я получаю ActionView::MissingTemplate, хотя у меня есть pdf.html.erb в каталоге. Я использую метод gen_pdf в контроллере приложения и эквивалентный pdf.html.erb в папке views/application. Что мне не хватает.


person user1323136    schedule 12.04.2013    source источник
comment
Есть ли шанс, что вы выберете правильный ответ здесь?   -  person Joshua Pinter    schedule 03.02.2021


Ответы (3)


Не используйте template.

Я столкнулся с той же проблемой, что и вы. Вы должны отображать свой PDF-файл совсем по-другому, когда делаете это в действии контроллера, а не в почтовой программе или чем-то еще.

Во-первых, использование template не сработает. Есть некоторые другие нюансы, но вот моя реализация, из которой вы можете построить:

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: '[email protected]' } )

end
person Joshua Pinter    schedule 05.08.2015

Если вы используете wicked_pdf и пытаетесь сгенерировать pdf вне контроллера (т.е. в задании cron), вы можете сделать это следующим образом (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

и вызовите этот метод:

  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

теперь вы можете использовать temp_pdf.path, чтобы делать с этим файлом все, что хотите (например, отправлять электронную почту)

вы можете прочитать больше об этом здесь: http://blog.arkency.com/2014/03/pdf-in-rails-without-controllers/

person yossico    schedule 13.04.2017
comment
Какие есть модули для Rails 5? - person Sushil; 24.05.2018

У вас может быть что-то вроде этого внутри почтовой программы:

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 

Надеюсь это поможет. Кроме того, если вам нужна дополнительная помощь, было бы идеально опубликовать часть вашего кода, чтобы другие могли лучше понять, что вы сделали и чего пытаетесь достичь.

person David    schedule 12.04.2013