Thursday, March 15, 2012

Prawn: The Pure Ruby PDF Generation Library

Create and Install
Note: I’m assuming Rails 2.1+. Fire up terminal and create a new app and install the prawnto plugin.

rails prawn_demo
sudo gem install prawn
script/plugin install git://github.com/thorny-sun/prawnto.git

Now add prawn as a dependency in environment.rb.

config.gem 'prawn'

For the sake of the demo we’ll need some demo data. Let’s create a Book model with some columns that we can shove lorem ipsum into.

script/generate scaffold book title:string author:string description:text
rake db:migrate

BooksController#show Example


I ran over to The Pragmatic Programmer’s site and snagged a few titles to enter as test data. Let’s get started with something simple and add a pdf version of the show action. Open up the books controller and add format.pdf { render :layout => false } so that the action looks something like this:

def show
  @book = Book.find(params[:id])

  respond_to do |format|
    format.html # show.html.erb
    format.xml  { render :xml => @book }
    format.pdf { render :layout => false }
  end
end

Now if you visit http://localhost:3000/books/2.pdf, you’ll get a template is missing error. Let’s add the show view. The prawnto plugin adds all the wiring, so all you need to do is create the show.pdf.prawn file inside app/views/books. For now, lets hello world that mofo with the following:

pdf.text "Hello World!"

Now if you revisit that url, you’ll get a pdf that says hello world. Simple, eh? Let’s make the view specific to the book and tweak the look a bit.

pdf.font "Helvetica"
pdf.font.size = 13
pdf.text "Book: #{@book.title}", :size => 16, :style => :bold, :spacing => 4
pdf.text "Author: #{@book.author}", :spacing => 16
pdf.text @book.description

The first two lines set the default font stuff. As you can see, pdf.text takes a string and then a hash of options. :size adjust the font size, :style changes the weight, and :spacing controls the space between lines. Pretty self-explanatory, but I thought I would cover it anyway.

BooksController#index Example


Now let’s create a pdf of all the books with each book on it’s own page. Add format.pdf { render :layout => false } to the respond to block in the index action and create the following index.pdf.prawn view:

pdf.font "Helvetica"
pdf.font.size = 13

@books.each do |book|
  pdf.text "Book: #{book.title}", :size => 16, :style => :bold, :spacing => 4
  pdf.text "Author: #{book.author}", :spacing => 16
  pdf.text book.description
  pdf.start_new_page
end

So the examples I showed were pretty basic and there is a lot more you can do with prawn, but I didn’t feel like coming up with examples. Helpers work just like in views which is handy. Also, prawn does images and data tables in a pretty simple manner. Check out the prawn and prawnto websites for more.

No comments:

Post a Comment