It has been amazing working for a project using Ruby on rails framework. And with the awesome support from its community, the experience has been always smooth. In this post I will be introducing you with a wonderful gem/plugin for Rails to generate PDF's. Generating PDF's has never been this easy. When I was asked to generate PF reports in my current project, the hunt for the best plugin began and after testing a few plugins I came across a gem called 'prawn'.
"Prawn takes the pain out of generating beautiful printable documents, while still remaining fast, tiny and nimble."
And Prawnto is a rails plugin which leverages the new prawn library to produce compiled pdf views.
In this post , I will provide simple step by step instruction to install and configure prawn/prawnto and hence will be walking through a simple PDF generating demo application.
Installing Prawn and Prawnto:
To begin with, we have to install prawn gem. From your command prompt(windows OS)
gem install prawn
Once we have successfully installed prawn gem, we need to install Prawnto plugin. Before installing the plugin, lets create the demo application which will be using MySQL database..
From the command prompt
C:\>rails pdf_demo -d mysql
After the project folder structure is created, move into the project folder:
C:\>cd pdf_demo
And now we will be installing the Prawnto plugin
C:\pdf_demo>ruby script/plugin install http://github.com/thorny-sun/prawnto.git/
After we have succesfully installed this plugin, we need to add the following line inside the environment.rb file of our project.
config.gem 'prawn'within "Rails::Initializer.run do |config|"
Next, lets go ahead and create the Controller named Book
C:\pdf_demo>ruby script/generate controller Book exists app/controllers/ exists app/helpers/ create app/views/book exists test/functional/ create test/unit/helpers/ create app/controllers/book_controller.rb create test/functional/book_controller_test.rb create app/helpers/book_helper.rb create test/unit/helpers/book_helper_test.rb
Next lets create the model named book
C:\pdf_demo>ruby script/generate model book exists app/models/ exists test/unit/ exists test/fixtures/ create app/models/book.rb create test/unit/book_test.rb create test/fixtures/books.yml create db/migrate create db/migrate/20091211170948_create_books.rb
Our project contains one database table(books) with two columns namely name and author.So add the following code inside your migration file (20091211170948_create_books.rb)
class CreateBooks < ActiveRecord::Migration def self.up create_table :books do |t| t.string :name t.string :author t.timestamps end end def self.down drop_table :books end end
Before we go further with any more code, if you open up your database.yml file, it says
development: adapter: mysql encoding: utf8 reconnect: false database: pdf_demo_development pool: 5 username: root password: host: localhost
So we need to create "pdf_demo_development" named database. We can do that from the command prompt itself as shown below
C:\>mysql -u root
Here I have assumed that the username is "root" and password is nil.
If you have got password then use the following command
C:\>mysql -u root -p (password)
Once you get inside the mysql, we can go ahead and create the required database using following command
mysql> CREATE DATABASE pdf_demo_development;
Once this is successfull, we move ahead and migrate the database for our project.
C:\pdf_demo>rake db:migrate (in C:/pdf_demo) == CreateBooks: migrating ==================================================== -- create_table(:books) -> 0.0630s == CreateBooks: migrated (0.0630s) ===========================================
Next we will be adding some dummy data's into our newly created database table namely 'books'
Use the following command to add data to the table. First select the database from mysql using
mysql> use pdf_demo_development;
Next lets add the dummy data
mysql> INSERT INTO books (name,author) VALUES ("The Rails Way", "Obie Fernandez"); Query OK, 1 row affected (0.06 sec) mysql> INSERT INTO books (name,author) VALUES ("Agile Web Development with Rails", "David"); Query OK, 1 row affected (0.01 sec)
So finally we write the codes for generating the PDF and showing the datas entered into the database.
Add the following codes into your app/controllers/book_controller.rb
class BookController < ApplicationController def index end def show @book = Book.find(:all) respond_to do |format| format.pdf { render :layout => false } end end end
Here we have created a method called 'show' and created a variable called '@book' which contains all the record from the 'books' table.
Next lets create a view(.rhtml file) for the index method within the books folder and add the following line of code inside this file, which is just a link to generate the PDF file.
app/views/book/index.rhtml
<%= link_to "(PDF Report)", :controller=>"book", :action=>"show", :id=>"2", :format=>'pdf' %>
And one final step before we run our server to view the result is to create a file with extension .pdf.prawn
This is the file where we write the code to display the contents in the PDF file. So create a 'show.pdf.prawn' file and add the following code
app/views/book/show.pdf.prawn
pdf.move_down(30) books = @book.map do |item| [ item.name, item.author ] end pdf.table books, :border_style => :grid, :row_colors => ["FFFFFF", "DDDDDD"], :headers => ["book", "author"], :align => { 0 => :left, 1 => :right, 2 => :right, 3 => :right }
Now lets go ahead and run the server
C:\pdf_demo>ruby script/server
And in your favorite browser go to => http://localhost:3000/book/index
and you will be taken to a page with your (PDF report) link and on clicking on this link you can get your PDF report.
You can visit prawn and prawnto websites to view their documentations and generate PDF's with various effects.
I wish I knew about prawn and prawnto when I was writing creating PDFs for fedena. I chose PDF::Writer instead and hated the fact that I would have to put all view logic for the pdf in the controller. Having seen you work on prawnto, I'm impressed by how easy it to generate PDFs. Also, I love the fact that it separates the view from the controller logic. Thanks for the tutorial. I might need it the next time I need a PDF plugin.
ReplyDeletecan a make double line table outter border for pdf.table
ReplyDeletei m usig prawnto ,but i want some more properties of pdf.table
ReplyDeletewhere i have to show difference from outter border to in border
and outter font size to inner font size for the table
thanks for u response RALU
ReplyDeletehow can I show the difference b/w header text and body text in
ReplyDeletefont or font style or size when i m using pdf.table,can i give header_font_size for header text in table properties it is not working ,kindly plz help me
pdf.table data,
:position => :center,
:font_size => 8,
:header_text_color => "0000CC",
:border_style => :grid,
:headers => [ "Room No", "Room "],
:align => { 0 => :left, 1 =>:center,},
:align_headers => { 0 => :left,1 =>:left)
@vara
ReplyDeleteHi
You can surely show the difference between the table header and the table body using header background color or header text color.
The entire header cells can be given background color using :header_color=>"#000000" (Entire header row will be having black background)
The header text color can be set using :header_text_color=>"#ffffff"
thanks for u response TechSlam
ReplyDeletebut i want to show the entire header cells with some specified
font_size and body text with another font_size
can u plz suggest me
@vara
ReplyDeleteu giv the header and the content as different tables , with diferent font size
align it well...
i think there is no other straight way, if u got any pls post it :)
@Vara
ReplyDeleteYea, what Ralu has suggested would be the best idea to get this worked out. I could not find any option to get the header font size and body font size changed in prawn to either.
if i use two different tables means for data which having more than one page the header vil not come in next page and the width of the header table also vil not set correctly to the width of other table data.for my case this vil not.
ReplyDeletevery very thankful for ur responses
i have seen in google groups these properties in
ReplyDeletepdf.table .to show variations in columns font size
i.e
:column_font_sizes => { 0 => 8, 2 => 12 }
but it is not working ,if it work means some what my work vil go cool.
here is link:
http://groups.google.com/group/prawn-ruby/browse_thread/thread/72bf44b3f7eab333
if u have any suggestions plz give me
Excellent tutorial, thank you!
ReplyDeleteHi is there a way to display different colors for text in tables.
ReplyDeleteEG. I have a table with some fields and due date field.
i want to display the text in red if due_date > Date.today and in green color if due_date < Date.today.
Thanks
Aj