In almost any web application you create, the question of generating PDF files will pop up pretty soon.
Setup
As always, using a ruby gem in rails is pretty simple, you just add a couple of lines to the
Gemfile
gem 'wicked_pdf'
#we need the new binary here, so that we can be OS independent
gem 'wkhtmltopdf-binary', github: 'pallymore/wkhtmltopdf-binary-edge', tag: 'v0.12.2'
Usage
This setup will work pretty straightforward in the controllers, because WickedPdf registers
:pdf
request format, and you can respond to it in the same fashion as html or js in a respond_to
block. Code below is copied from the WickedPdf Readme page.class ThingsController < ApplicationController
def show
respond_to do |format|
format.html
format.pdf do
render pdf: "file_name" # Excluding ".pdf" extension.
end
end
end
end
That part was pretty easy, and you can configure the pdf render with a lot of options that are mentioned in the advanced configuration section of the WickedPdf Readme
Generating PDF from ActionMailer
The issue when trying to generate the PDF from ActionMailer is that there is no request, so you have to render the html in a different way. In a nutshell, you want to render the template to a string, and then forward that string (html) to the wkhtmltopdf. This is the same way the gem work when rendering pdf from the controller, but it is worth mentioning once more.
We will use a method that exists on the
AbstractController::Rendering
and it is called render_to_string So we can do something like this in the mailer:class TodoMailer < ActionMailer::Base
#...
def pdf_attachment_method(todo_id)
todo = Todo.find(todo_id)
attachments["todo_#{todo.id}.pdf"] = WickedPdf.new.pdf_from_string(
render_to_string(pdf: 'todo', template: 'todo.pdf.erb', layout: 'pdf.html'), { :hash_with_wickedpdf_options }
)
mail(to: todo.owner.email, subject: 'Your todo PDF is attached', todo: todo)
end
end
By using this approach, we can easily send a PDF attachment from an ActionMailer method. You can do this for any Rails template you want, but be sure to test everything before putting it into production.
No comments:
Post a Comment