Friday, August 30, 2013

Another take on WickedPDF, wkhtmltopdf, and heroku...

A while back, I commented on installing WickedPDF/wkhtmltopdf to work on Heroku. But there are still a few more things to be done to get it all to work. Here's a checklist I provided to a friend when they were having problems.

1. Added gem "wickedpdf" in my Gemfile

2. Copied the appropriate wkhtmltopdf binary into the bin/ directory in my Rails app

3. Updated config/initializers/wicked_pdf.rb to include:
WickedPdf.config = { :exe_path => "#{Rails.root}/bin/wkhtmltopdf" }
so that it knows where I've stored the binary

4. Added the following to the show method in my controller; this is what drives the whole PDF creation. There are many more options available; this is just my minimal setup.
format.pdf do
  render :pdf => "AccRpt_#{}",
    :template => 'accident_reports/show', :formats => [:pdf], :handlers => [:haml],
    :show_as_html => params[:debug].present?,
   # allow debuging based on url param
    :page_size => :letter,
    #:debug_javascript => true,
    :footer => {
      :left => "#{}",
      :center => "Accident Report ##{}",
      :right => "Page [page] of [topage]",
      :line => true         },
    :user_style_sheet => "/assets/stylesheets/pdf.css",
    :layout => "pdf.html" #false end

NOTE The "show_as_html" option. By adding this, you can add "&debug=1" to your URL and see what the html would have been. Sometimes helpful in tweaking the output.

5. Created a new stylesheet called pdf.css and a new javascript file called pdf.js. They don't do a lot, but I pretty much extract out as much stuff as I can so that only what's absolutely necessary is included here.

6. Created a new layout called pdf.html.haml. Cuts out all the overhead associated with 'normal' html display. Again, nothing but what's absolutely necessary to produce the PDF.

7. In that layout, used a Content Delivery Network (CDN) for all the jquery stuff I use - that's directly available to wkhtmltopdf since it's a full URL (Remember I said that you can't use relative URL's with wkhtmltopdf).

8. Where necessary, used the WickedPDF-provided helpers to include other stylesheets/javscript files. Make sure you read the "Usage Conditions - Important!" section on the WickedPDF page - I added that after I ran into problems.

9. Created a show.pdf.haml view template with the data/formatting I wanted.
*NOTE**: You can render an existing html partial as part of your PDF output, but to do so you MUST add:
":handlers => [:haml], :formats => [:pdf]"
to the render and then you can actually reuse an html partial, such as _body.html.haml. If you don't do that, you'll get a complaint that it doesn't have the proper pdf template.

10. Added 'PDF' links at various places, such as in the index view and the show view.

11. Made sure that the PDF mime-type was registered:
'Mime::Type.register "application/pdf", :pdf' in config/initializers/mime_types.rb  

I believe that covers it all.