Safety in Numbers
Brighter Planet's blog
Stamp PDFs with Prawn and Pdftk
In order to generate PDFs with a standard template, Brighter Planet uses a combination of Prawn and Pdftk.
First, we generate the content pages:
Here’s what the code for that looks like:
require 'prawn'
Prawn::Document.generate('content.pdf', :top_margin => 126, :right_margin => 72, :bottom_margin => 72, :left_margin => 72) do |pdf|
pdf.text "Sustainability report for Acme", :size => 18
pdf.move_down 12
pdf.text "Executive summary", :style => :bold
pdf.move_down 12
pdf.text "Lorem ipsum"
pdf.start_new_page
pdf.text "Analysis"
pdf.move_down 12
pdf.table([['Lorem', 'ipsum'], ['sit', 'amet']], :width => 468, :header => true)
pdf.number_pages "Page <page> of <total>", :at => [432, -4], :width => 100
end
Then we apply our standard template:
Which creates the final product (94Kb):
Here’s the Pdftk command to do that:
pdftk content.pdf stamp template.pdf output final.pdf
Final code
require 'prawn'
Prawn::Document.generate('content.pdf', :top_margin => 126, :right_margin => 72, :bottom_margin => 72, :left_margin => 72) do |pdf|
pdf.text "Sustainability report for Acme", :size => 18
pdf.move_down 12
pdf.text "Executive summary", :style => :bold
pdf.move_down 12
pdf.text "Lorem ipsum"
pdf.start_new_page
pdf.text "Analysis"
pdf.move_down 12
pdf.table([['Lorem', 'ipsum'], ['sit', 'amet']], :width => 468, :header => true)
pdf.number_pages "Page <page> of <total>", :at => [432, -4], :width => 100
end
require 'posix/spawn'
::POSIX::Spawn::Child.new 'pdftk', 'content.pdf', 'stamp', 'template.pdf', 'output', 'final.pdf'
Why not use Prawn’s native :template
option?
Prawn currently can’t automatically apply a template to every page.
You could force it:
Prawn::Document.generate('bigger_and_dirtier_final.pdf', [...], :template => 'template.pdf') do |pdf|
# [...]
pdf.start_new_page :template => 'template.pdf'
# [...]
end
- This is not practical for multi-page tables because you don’t control when new pages start.
- The resulting PDF is 200% bigger (180Kb) because the template data is duplicated for every page.
- Prawn’s text rendering seems less reliable when using a template. For example,
pdf.text "This should be bold", :style => :bold
sometimes won’t work (sorry for not reproducing that behavior in my example, didn’t have time.) - Finally you may run into problems with Adobe Reader.
Bottom line: Pdftk is more efficient and reliable than the current version of Prawn for stamping templates.
What blog is this?
Safety in Numbers is Brighter Planet's blog about climate science, Ruby, Rails, data, transparency, and, well, us.
Who's behind this?
We're Brighter Planet, the world's leading computational sustainability platform.