Recipe 15.5. Generating PDF Documents


Problem

You have an application that generates a report, a receipt, or some other output that you'd like users to be able to save. You'd like to generate this output as PDF documents for consistent formatting and convenient distribution.

Solution

Use Ruby FPDF to create PDF documents from within your Rails application.

First, download Ruby FPDF from http://brian.imxcc.com/fpdf/rfpdf153c.tar.gz. Extract the archive, and move the file called fpdf.rb to the your application's lib directory for it to be available to your controllers.

Next, create a Reports Controller that calls require to include the PDF creation library in your lib directory. This controller defines a private method called pdf_report_card and a public method or action called pdf_report.

app/controllers/reports_controller.rb:

class ReportsController < ApplicationController   require 'fpdf'   def index   end   def pdf_report     # Data     col_sizes = [40,20,20,20]     data = [['Course','Exam 1','Exam 2','Final'],             ['ENGLISH 101','90','87','B'],             ['MUSIC 5A','97','100','A'],             ['CALC 2','98','91','A'],             ['SWIM','89','84','B'],             ['HIST 110','91','81','B']]     send_data pdf_report_card(col_sizes, data),               :filename => "report.pdf",                :type => "application/pdf"    end   private     def pdf_report_card(col_sizes, data)       pdf = FPDF.new       pdf.AddPage       pdf.SetFont('Arial','B')       pdf.SetFontSize(10)       pdf.SetFillColor(50,50,50)       pdf.SetTextColor(255)       pdf.SetDrawColor(0)       pdf.SetLineWidth(0.2)       # Table Header       i = 0          col_sizes.each do         pdf.Cell(col_sizes[i],7,data[0][i],1,0,'C',1)         i += 1       end       pdf.Ln()       pdf.SetFillColor(218,206,255)       pdf.SetTextColor(0)       pdf.SetFont('Arial')       fill = 0       # Table Data       data[1..-1].each do |row|           pdf.Cell(col_sizes[0],6,row[0],'LR',0,'L',fill)           pdf.Cell(col_sizes[1],6,row[1],'LR',0,'L',fill)           pdf.Cell(col_sizes[2],6,row[2],'LR',0,'L',fill)           pdf.Cell(col_sizes[3],6,row[3],'LR',0,'C',fill)           pdf.Ln()           fill = (fill-1).abs % 2       end       # Bottom Table Border       total = 0       col_sizes.each {|x| total += x}       pdf.Cell(total,0,'','T');       pdf.Output     end end

The index.rhtml simply creates a link that generates a PDF report card:

app/views/reports/index.rhtml:

<h1>Report</h1> <%= link_to 'Make PDF', :action => 'pdf_report' %>

Discussion

The solution displays a 'Make PDF' link. Clicking this link calls the pdf_report action of the Reports Controller when clicked. pdf_report defines an array of four integers that are the column widths of the table to be generated. The actual data to be output is defined as a two-dimensional array and stored in data. The PDF version of the report is returned to the user with the send_data method, which itself calls pdf_report_card to create the PDF. send_data also takes the :filename and :type options, which help browsers render or save the file.

pdf_report_card takes two array arguments; the column widths and a structure of the data to be output. The function creates a new FPDF object and then sets up display properties for the table header, including font and background color. The contents of data is then iterated over, and the body of the table is created. The final call to pdf.Cell draws the bottom border to the table.

Figure 15-2 shows the solution's PDF output.

Figure 15-2. A PDF containing a list of classes with exam scores


See Also

  • Documentation for Ruby FPDF doesn't exist other than the examples included in the source download. This is because the PHP version of FPDF's documentation http://www.fpdf.org/en/doc/index.php is almost completely applicable to Ruby FPDF's API.




Rails Cookbook
Rails Cookbook (Cookbooks (OReilly))
ISBN: 0596527314
EAN: 2147483647
Year: 2007
Pages: 250
Authors: Rob Orsini

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net