Wicked PDF using Rails 4 on Heroku

Categories: Coding, VCS

Intro

A recent project I began building on Rails was a monthly report generator for our employees at BrandYourself. Functionally it needs to allow our representatives to input information quickly or easily, allow them to edit it using a WYSIWYG editor after the report has been created, and finally save the report to a PDF in the browser so the rep can download it and email to our clients. It sounded like a simple project at first, but implementation proved complicated.

Setup

The two main gems that I used for this project were:

Bootsy was essentially plug-and-play, while wicked PDF required a lot of playing with to get it working.

Bootsy

Bootsy was so easy to use I’m not even going to dive too deeply into this gem. Basically, on whichever form you’d like to impliment the WYSIWYG editor you use a special `bootsy_area` method for `form_for`. Here’s an example:

<%= form_for(@report) do |r| %>
	
        # Add 'Summary' Bootsy Area
	<%= r.label :summary, 'Summary:'  %>
	<%= r.bootsy_area :summary, class: 'form-control', placeholder: 'Enter your report summary here...', rows: 6 %>

<% end %>

It’s that simple.

Wicked PDF

Before taking on this project I didn’t realize how difficult in-browser PDF generation was. Wicked PDF takes a lot of the sting out of this process, but it’s still not easy to setup. A lot of the problems stemmed from Wicked PDF being a wrapper for a binary library called wkhtmltopdf which does the heavy lifting for converting HTML to PDF. But, since this is a binary library (which I’ve never really worked with until now) it was tough to get this working properly on Heroku.

The basic setup for wicked_pdf is straightforward. First install the gem, and make sure you have wkhtmltopdf installed on your local machine: usually this is stored in `/usr/local/bin` on Macs. Then you’ll want to run `rails g wicked_pdf` to setup the the gem. This just creates a `wicked_pdf.rb` initializer in your app.  Following the other steps on their github you can easily get this setup properly on your local app! The way it’s setup you can add `.pdf` to the end of any URL and it will convert that page to a PDF; pretty cool! The basic idea is something like this in your controller:

@report = Report.find(params[:id])
		respond_to do |format|
      format.html
      format.pdf do
        render :pdf => 'file_name',
        :layout => 'pdf.html.erb',
        :show_as_html => params[:debug].present?, 
        :margin => {
        		top: 0,
        		bottom: 0, 
        		left: 0, 
        		right: 0
        	}

      end
    end

Don’t let this fool you though, implementing this on Heroku is another endeavor.

Wicked PDF on Heroku

Wicked PDF on Heroku is a challenge because of the way wkhtmltopdf works. Locally, this library is stored in `/usr/local/bin` but obviously Heroku doesn’t have this out of the box. So, we have to ensure that Heroku has access to this library so it can utilize it. After a lot of research on Google I found a potential solution which had me firstly download the Linux version of wkhtmltopdf. This is available from their website under obsolete downloads (which turned out not to be so obsolete). I used the latest version of the Linux 64-bit library which was version 0.11.0.

Once this was downloaded I unzipped the library and put it in my `/bin` folder in my app. After that was done, I had to change where Wicked PDF looked for this library if we were in a production environment. This code, obtained from stack overflow, was added to the `wicked_pdf.rb` initializer:

if Rails.env.production?
  wkhtmltopdf_path = "#{Rails.root}/bin/wkhtmltopdf-amd64"
else
  wkhtmltopdf_path = "/usr/local/bin/wkhtmltopdf"            
end

WickedPdf.config = { exe_path: wkhtmltopdf_path, wkhtmltopdf: wkhtmltopdf_path }

This finally got wicked PDF working on Heroku even though there are still a few bugs.

Future #TODOs

Aside from general functionality TODOs there are still a few things tricky with Wicked PDF. Most specifically getting it to allow the use of Google fonts when generating PDFs. Presently, the font that I’ve included in the report doesn’t seem to be displaying properly in the generated PDF. At first this was because Heroku was blocking an “insecure” connection to Google fonts (since it was using http://) but changing this to https:// fixed this pretty quickly.

Other than that, everything seems to be working rather well with this project! I’m excited to continue to build it out and develop more functionality to improve the overall efficiency of our company 🙂

 

«
»
  • Fast forward to 2017, I don’t remember having any trouble getting wicked_pdf gem to run on heroku… but my pdf generation seems to be leaking of memory on Heroku, unlike on a local development machine. :/