For a recent project we needed (and wanted) a simple solution to generate PDF files. Ideally, the solution would use HTML for the general layout and design of the generated PDF, working just like a normal view in Rails.
After testing a number of potential PDF solutions we came across a neat little library called HTMLDOC. What it does is take basic HTML and converts it to PDF, among many other output formats.
For the situation and solution we wanted it does a great job, especially for the price. To make it even easier to use, there is a also a Ruby HTMLDOC Gem to use along with it. Score!
To generate the PDF files we used plain old HTML, something we were familiar with. Exactly like creating a normal rhtml view.
Below follows our experience installing and using HTMLDOC to get PDF file generation out of our Rails application. This has been tested and used on Linux and MacOS X 10.4.9.
Note: You will need the proper tools installed to compile HTMLDOC. On MacOS X, that usually consists of installing the developer tools.
1. Installing HTMLDOC
The first thing we need to do is get HTMLDOC downloaded, compiled, and installed. Copy and past the following in your console:
curl -O http://ftp.easysw.com/pub/htmldoc/snapshots/htmldoc-1.9.x-r1521.tar.gz tar zxvf htmldoc-1.9.x-r1521.tar.gz cd htmldoc-1.9.x-r1521 ./configure --prefix=/usr/local make sudo make install
2. Install the HTMLDOC Gem
Now that we have the HTMLDOC application ready to go, we want to install the HTMLDOC Ruby Gem to interface HTMLDOC with our Rails application:
sudo gem install htmldoc
3. Configuring Your Application
Next we need to configure our application. Open up your config/environment.rb file and add the following (to the end):
Mime::Type.register 'application/pdf', :pdf require 'htmldoc'
Note: There is a way to make Rails handle the ‘.pdf’ extension format, but when we tried it, it kept asking us to download a file no matter what format we requested on every page. After many attempts at trying to rectify the issue, we eventually decided on the following solution:
4. PDF Renderer
We also added a method to our app/controllers/application.rb file to help DRY up the PDF generation, sort of like the render methods already included in Rails:
def render_to_pdf(options = nil) data = render_to_string(options) pdf = PDF::HTMLDoc.new pdf.set_option :bodycolor, :white pdf.set_option :toc, false pdf.set_option :portrait, true pdf.set_option :links, false pdf.set_option :webpage, true pdf.set_option :left, '2cm' pdf.set_option :right, '2cm' pdf << data pdf.generate end
Just pass it the same options you would pass render. Check the HTMLDOC Gem rdoc page for more options and configurations.
Example
Here is an example controller method:
def index @items = Item.find(:all) respond_to do |format| format.html # index.html format.xml { head :ok } format.pdf { send_data render_to_pdf({ :action => 'index.rpdf', :layout => 'pdf_report' }) } end end
Pretty typical Rails, no? We tell it to explicitly use that action/view and to use a different layout file.
Now an example of a view:
<h3>Showing: <%= pluralize(@items.size, 'item') %></h3> <table><tbody> <tr> <th>Field1</th> <th>Field1</th> <th>Field1</th> </tr> <% @items.each do |item| %> <tr> <td><%= item.field1 %></td> <td><%= item.field1 %></td> <td><%= item.field1 %></td> </tr> <% end %> </tbody></table>
Maybe it’s just me, but that sure beats using the examples using the PDF Writer plugin. At least from what I have seen.
Finally, to generate a link to the PDF, assuming you are using restful routes:
<%= link_to 'PDF', formatted_items_path(:pdf) %>
HTMLDOC may not be perfect, but I found it’s ease of use to generate nicely formatted PDF files far outweighed it’s limitations. I hope you found this useful.
Update: 12-26-2007
I made a little helper method for images also, put this in your application_helper.rb:
def pdf_image_tag(image, options = {}) options[:src] = File.expand_path(RAILS_ROOT) + '/public/images/' + image tag(:img, options) end
Other Posts That Might Interest You

