Saving a Prawn PDF to File

09Sep09

On a recent project I was generating a PDF using Prawn and feeding it out to the user via send_data.  Then requirements changed (of course), and we needed to show past invoices.  To improve response times I was asked to save the generated PDFs as they wouldn’t change and the storage of them is not an issue.

Unfortunately Prawn doesn’t seem to support this functionality on it’s own, and there weren’t too many guides for how to do this out there.

Fortunately, it turned out to be pretty easy to implement.  I set up a static method in my Invoices class that takes in teh desired file name, and the list of invoices:


def self.create_pdf(invoices, filename)
   pdf = Prawn::Document.new
   eval(Invoice.get_pdf_markup(invoices))
   pdf.render_file(filename)

 end

And another static method to get the PDF markup.  Mine’s pretty long and complicated since it’s a formatted invoice.  Just put what would normally be in your prawn.pdf file here.


 def self.get_pdf_markup(invoices)
 return <<-EOS
 if invoices.blank?
 pdf.text "There has been no account activity this month"
 else
 point = [pdf.bounds.right-50, pdf.bounds.bottom + 648]
 page_counter = pdf.lazy_bounding_box(point, :width => 10) do
 pdf.text pdf.page_count, :size => 9, :align => :right
 end

 pdf.header [pdf.margin_box.top_left] do
 pdf.fill_color "299f6f"
 pdf.text "STATEMENT", :align => :center, :size => 9

 pdf.bounding_box [300,670], :width=>100 do
 pdf.text "Customer No:", :size => 9
 pdf.text "Date: ", :size => 9
 pdf.text "Page: ", :size => 9
 end

 pdf.bounding_box [400, 670], :width=> 100 do
 pdf.fill_color "000000"
 pdf.text invoices.first.invoice.accpac_customer.IDCUST.strip, :align => :right, :size => 9
 pdf.text Date.today.strftime("%m/%d/%Y"), :align => :right, :size => 9
 end

 logo_header = "#{RAILS_ROOT}/public/images/logo.png"
 pdf.image logo_header, :width => 225, :at => [5, 680]

 pdf.bounding_box [50,600], :width => 200 do
 pdf.fill_color "299f6f"
 pdf.text "Sold To:", :size => 9
 pdf.bounding_box [10, 0], :width => 190 do
 pdf.fill_color "000000"
 pdf.text invoices.first.invoice.accpac_customer.display_address.split("
")* "\n", :size => 9
 pdf.text invoices.first.invoice.accpac_customer.TEXTPHON1, :size => 9
 end
 end

 pdf.bounding_box [300,600], :width => 200 do
 pdf.fill_color "299f6f"
 pdf.text "Remit To Address:", :size => 9

 pdf.bounding_box [10, 0], :width => 190 do
 pdf.fill_color "000000"
 pdf.text REMIT_TO_ADDRESS * "\n", :size => 9
 end
 end
 page_counter.draw
 end

 data = invoices.collect{|arobl| [arobl.IDINVC, Date.strptime(arobl.DATEINVC.to_s, '%Y%m%d').strftime('%Y/%m/%d'),
 arobl.TRXTYPETXT, "", Date.strptime(arobl.DATEDUE.to_s, '%Y%m%d').strftime('%Y/%m/%d'), sprintf("%0.2f", arobl.AMTDUETC) ]}
 pdf.fill_color "000000"
 pdf.bounding_box [0,500], :width => 500 do
 pdf.table data,
 :position => :center,
 :header_text_color => "299f6f",
 :border_color => "299f6f",
 :headers => ["Document No.", "Doc. Date", "Ty.", "Reference/Applied No.", "Due Date", "Amount" ],
 :font_size => 9,
 :width => 500,
 :vertical_padding => 1
 end

 end
 EOS
 end

And to return that from your controller all you have to do is a send_data (or send_file, I opted for send_data) call with the file:


 send_data(File.read(filename), :type => "application/pdf",
 :filename => "#{Date::MONTHNAMES[params[:month]]}#{params[:year]}.pdf")

About these ads


No Responses Yet to “Saving a Prawn PDF to File”

  1. Leave a Comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


Follow

Get every new post delivered to your Inbox.

%d bloggers like this: