The League of Extraordinary Developers

Telephone
0845 272 5205
Email
team@theled.co.uk

Blog

Whilst working on client projects we often find useful bits of information out. Where possible we blog about that information to pass on our knowledge. Below are some of our most recent entries.

Screengrab of the new LED site

PDF Generation in Rails

We were recently set the challenge by Bluestorm to create a PDF plugin for their in house Rails based CMS.

Having not done PDF generation in Rails before we needed a starting point and rather than doing some random searches on Google, we put out a few tweets to get advice from developers we knew and trusted. The most common piece of advice was to use Prawn with the Rails plugin Prawnto. We now had a starting point for PDF generation side of things.

The next stage was to start prototyping the document generation side of things. The client had provided wireframes of the functionality, and these included the ability to see the PDF being built on the fly as the editors added more and more content and imagery. The simplest solution here was show the PDF as a html document within the editing page.

We started the prototype by creating a series of user stories and putting those stories into Cucumber features. Within a short space of time we had our basic document creation functionality up and running. We were still left with one problem though. The generation of the PDF document.

Prawn and Prawnto

Having had these tools recommended to us we started testing how we could take our HTML preview and turn it into a PDF document. It didn't take us long to realise that using Prawn was going to become complicated and potentially pretty unflexible as the project developed.

Some sample code for Prawn PDF generation below:


# views/orders/show.pdf.prawn
pdf.text "Order ##{@order.id}", :size => 30, :style => :bold

pdf.move_down(30)

items = @order.cart.line_items.map do |item|
  [
    item.product.name,
    item.quantity,
    number_to_currency(item.unit_price),
    number_to_currency(item.full_price)
  ]
end

pdf.table items, :border_style => :grid,
  :row_colors => ["FFFFFF","DDDDDD"],
  :headers => ["Product", "Qty", "Unit Price", "Full Price"],
  :align => { 0 => :left, 1 => :right, 2 => :right, 3 => :right }

pdf.move_down(10)

pdf.text "Total Price: #{number_to_currency(@order.cart.total_price)}", :size => 16, 
            :style => :bold

As you can see, using Prawn would mean we would need to write a parser to convert our already existing HTML preview code into relevant Prawn related calls. Whilst this wouldn't be impossible, we like to keep our code as simple as possible, so future development is easier. We were also concerned how close the final PDF document would look to the HTML preview.

We decided we needed to look for some way to convert our HTML into a PDF document without the worry of the final document not looking exactly the same as the preview.

Prince XML and Princely

Prince XML is a command line tool that converts XML and HTML into PDF documents. To make things even easier their is a Rails wrapper for the library called Princely. So now we could use our existing view code to generate the PDF documents. We just needed to update our controller and bang, we were done.


def show
  respond_to do |format|
    format.html
    format.pdf do
      render :pdf => "filename", :stylesheets => ["application", "prince"], :layout => "pdf"
    end
  end
end

Easy right? Well, there was one thing that stopped us dancing around the office. Prince XML requires a Server Licence which costs $3,800. This was going to blow our client's budget.

Wicked PDF and wkhtmltopdf to the rescue!

Having just given up on the idea of Prince XML we found exactly what we were looking for in Wicked PDF, a rails plugin that uses wkhtmltopdf to generate PDF documents from HTML code.

The code to generate the PDF document was again very simple.


show.wants.pdf { 
  render :pdf => @print_publication.title,
          :template => 'admin/print_publications/show.pdf.erb',
          :layout => 'pdf.pdf.erb',
          :disable_javascript => false,
          :margin => {:top => 20,
                       :bottom  => 20,
                       :left  => 20, 
                       :right  => 20}, 
          :zoom => 2, 
          :disable_smart_shrinking => false, 
}

(Yes we are using resource_controller).

One thing to note is that we have enabled JavaScript as part of the PDF generation. We needed to use JavaScript in the view code as wkhtmltopdf doesn't support CSS 3 columns. It does have other CSS 3 support, just not columns. As the PDF documents required a two column structure we ended up using the Columnizer jQuery Plugin to generate the columns.

In our experience it was worthwhile disabling the smart shrinking in wkhtmltopdf as this caused some problems with the generated PDF not looking exactly the same as the HTML preview.

Conclusion

We can see that Prawn is a great library and is really powerful, but wkhtmltopdf offered us the ability to use the same view code for the HTML preview to generate the PDF document. This meant that anyone with HTML experience could generate a new PDF template easily.

Read more entries

Keep up to date

Blog RSS feed

Want to find out more?

If we have piqued your interest then we'd love to hear from you.

Get in contact with us

Services

  • Ruby on Rails
  • .Net
  • PHP
  • MySQL / MS SQL Server
  • NoSQL
  • HTML5
  • CSS3
  • JavaScript
  • Responsive Layout
  • Web Apps
  • Mobile Web Apps

Blog

  1. Blog title
    Keep your requests thin
    Post Date
    Friday, January 06 2012
  1. Blog title
    Storing a Product Catalog for eCommerce with a Document Database
    Post Date
    Monday, November 21 2011
  1. Blog title
    Success for Incentive Maker - Hull Digital Post
    Post Date
    Friday, July 08 2011
  1. Blog title
    SASS, Compass and some clarity
    Post Date
    Thursday, June 16 2011
  1. Blog title
    The League of Extraordinary Developers : Year One
    Post Date
    Friday, April 01 2011
  1. Blog title
    A Client, a Sales Team, Incentives and the development of a Commercial Application
    Post Date
    Tuesday, February 01 2011
  1. Blog title
    jQuery Mobile SASS Alpha 2 released
    Post Date
    Friday, November 12 2010
RSS

Twitter

  1. Tweet
    As part of the upgrade we also converted all the JS to CoffeeScript. #happygeeks
    Date
    10:46 AM Mar 01
  2. Tweet
    We finally got @IM_app upgraded to rails 3.2. Pretty smooth upgrade with lots of green from the tests.
    Date
    10:41 AM Mar 01
Follow