PDF Generation in Rails with Prawn and Prawn-to: John McCaffrey


Published on

breakdown of the most commonly used pdf libraries in rails projects,and an in depth review of prawn

example pdfs and code can be seen at prawn.heroku.com
More info at www.RailsPerformance.com

Published in: Technology
No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide
  • What I want you to walk away with: an understanding of the types of libraries out there, and the general strengths/weaknesses of each What prawn can and can’t do General pdf testing techniques some advanced examples and libraries
  • Ask them to turn in and introduce them selves to at least one new person Bring up the ‘Used it’, ‘Still Using it’ papers
  • PDFs are the defacto standard for reports, invoices and print friendly documents Sometimes its just easier than making the HTML print friendly The Pdf spec is quite large and complicated, you can do a lot with pdfs. One of the projects we had a Pathfinder was a PDF annotation tool for the Construction space But today I’m going to focus on the more common uses of PDF, for reports and basic print-friendly content
  • Not all PDFs are created equally. When I started looking into PDF generation in ruby I had some basic requirements, but pdfs can be complicated, and not all the tools will handle your needs. Let’s take a look at what’s out there
  • To me the libraries fall in three main categories Taking rendered html and converting or printing it as a pdf Creating a static pdf file and binding data against it Writing the code that creates the pdf components from scratch (now there are other pdf manipulation tools out there, but we’re talking about creation, not editing)
  • Show example of kocg form, bluebook blueprint, Mention that the library may be os specific which could affect the deployment process
  • May also depend on the team skills While its great to be able to reuse something you’ve already built, its pretty common to want the PDFs to have some additional element, be it security styling, etc
  • Get more details of these types Just because a library is commercial doesn’t mean you shouldn’t use it. Evaluate the true cost of your time In the case of HTMLDOC, its not like you are taking your full site and instantly getting pdfs out of it. Mostly you will be altering your view or creating a second view that looks the way you want it without external css. Htmlconverter – haven’t used it http:// github.com/dcu/htmlconverter/tree/master Pd4ml - http:// www.extonrails.com/?q =node/26 similar to prince, but costs less
  • Show example of kocg form. Now this is an example of a pdf that is better suited in the template style, but we’re going to be focusing more on regular reporting style pdfs
  • What other libraries are there to do this? Both pdftk and iText go beyond just template binding. They are great libraries and if you are not looking for an open source, but not necessarily pure-ruby solution, you should check them out Is pdftk tcl based? Pragmatic uses iText to insert the ‘this book licensed only to Darth Vader’ footer
  • You want to be mindful of the document size, because you are building so much. Not sure if there is any way to cache fragments. Prawn-to has a concept of compiled templates, but I’m not sure what that’s about
  • http://www.cnblogs.com/hardrock/archive/2006/07/24/458184.html RubyFpdf – php port Pdflib and rfpdf wrapper for it Does jasper reports just call out to iText? What about Flyingsaucer java How much faster is prawn than pdf writer? 40 times? And even faster on ruby 1.9
  • Prawn seemed to be the only one that had good test coverage
  • RBP will go creative-commons free in march 2010 Ruport is an interesting framework, and if you have to output reports in more than one format (csv, html, pdf) you should take a look at it. Currently the pdf side of it isn’t using prawn under the covers, but it will be soon
  • For positioning: you create your bounding box, then do all commands relative to that space Prawn was good for me, and depending on what you are doing, there’s a good chance it will be good for you too. Let’s take a look under the hood and see what it can do. Even if you feel that Prawn is not the right library for you, I’m hoping you’ll still get some good ideas for general pdf structure, testing and maintenance Prawn is moving fast, and there are a lot of related sub projects going on. So while it might not cover your needs right now, there’s a good chance it will soon, so keep an eye out.
  • Show a screen shot of the tests passing
  • Text – type it out and show how simple the initial syntax is Images – show just local file images first Bounding box – show the relative coordinates, and how easy it is Overflow – show how the page flow is taken care of Orientation – show landscape, portrait, and mixing the two within a document (how does that print?)
  • http://groups.google.com/group/pdf-writer/browse_thread/thread/5bc8de74e1a7d3c5 Groupon recently started using prawn to render the coupons, and they were able to get a good looking first cut in less than a day, and finished the final version pretty quickly They are using prawn in production to serve up over 8k pdfs a day Most of the pdfs I’ve shown you today are generated in less than 3 secods
  • Also mention image comparisons like bluebook
  • Also mention image comparisons like bluebook
  • http://cracklabs.com/prawnto/
  • Using prawn-to can help you stick to a pure MVC pattern, and not jumbling too much logic into the pdf creation
  • When it becomes easy to make pdfs, you can start to see creative things you never would have before
  • Now you might not want to call out to a 3 rd party for charts in production, but using google charts can allow you to make a quick prototype and move from concept to delivery faster
  • Great way to leverage your existing style concepts Make a script to parse css file and register those styles No support for div or table
  • Is susan Potter here? Sorry for not using twitter4r, it looks great, but I just found this one first I have this up at prawn.heroku.com, but I’m having an issue with one of the gems at the moment
  • Prawn-js for scripting within the pdf http://github.com/yob/prawn-js/tree/master http:// wiki.github.com /sandal/prawn/development-roadmap
  • PDF Generation in Rails with Prawn and Prawn-to: John McCaffrey

    1. 1. Rails PDF Generation John McCaffrey
    2. 2. What we’re going to cover <ul><li>Agenda </li></ul><ul><ul><li>PDF Types and Libraries </li></ul></ul><ul><ul><li>Prawn </li></ul></ul><ul><ul><li>General PDF Testing </li></ul></ul><ul><ul><li>Advanced Prawn examples </li></ul></ul><ul><ul><li>Prawn-to </li></ul></ul><ul><ul><li>Q&A </li></ul></ul>
    3. 3. Intro: after_me
    4. 4. <ul><li>John McCaffrey Presented at WindyCityRails 08 </li></ul><ul><li>Using Prawn since 10/08 </li></ul><ul><li>http://www.pathf.com/blogs/author/john-mccaffrey / </li></ul>
    5. 5. <ul><li>And you are? :include => :first_name </li></ul> Col 1 Col 2 Col 3 Col 4
    6. 6. Why users Love PDFs <ul><li>They are great for: </li></ul><ul><ul><li>Reports </li></ul></ul><ul><ul><li>Static data </li></ul></ul><ul><ul><li>Forms </li></ul></ul><ul><ul><li>Invoices </li></ul></ul><ul><ul><li>Tightly controlled formatting </li></ul></ul><ul><ul><li>Print friendly </li></ul></ul><ul><ul><li>Portable </li></ul></ul><ul><ul><li>Looks the same for everyone </li></ul></ul>
    7. 7. PDF types and libraries
    8. 8. <ul><li>PDF Library types </li></ul><ul><li>HTML to PDF </li></ul><ul><li>PDF Template binding </li></ul><ul><li>Dynamic </li></ul>
    9. 9. What type should I use? <ul><ul><li>What is the content? (tax form, invoice, eBook, product list) </li></ul></ul><ul><ul><li>How large will the files be? </li></ul></ul><ul><ul><li>How complex is the formatting? </li></ul></ul><ul><ul><li>Do they need to be generated ‘on demand’, or would it be a batch or background job? </li></ul></ul><ul><ul><li>Do you mind calling out to a library or command line tool? </li></ul></ul><ul><ul><li>Character encoding, utf-8, internationalization, etc </li></ul></ul><ul><ul><li>Who will be in charge of maintaining them? (developer or designer?) </li></ul></ul>
    10. 10. Use HTML to PDF if.. <ul><ul><li>You already have an html view that is structured the way you want it. </li></ul></ul><ul><ul><li>You don’t want to mess with any ‘pdf syntax’ </li></ul></ul><ul><ul><li>Don’t mind requiring a native library, or command line invocation. </li></ul></ul><ul><ul><li>Don’t mind the licensing agreements or cost of commercial tools </li></ul></ul><ul><ul><li>Your team skill set is more aligned with HTML/CSS </li></ul></ul>
    11. 11. HTML to PDF Libraries <ul><li>PrinceXML </li></ul><ul><ul><li>Best in class html to pdf. Passes Acid2 test </li></ul></ul><ul><ul><li>Princely ruby wrapper </li></ul></ul><ul><ul><li>Commercial: $3800 server license </li></ul></ul><ul><li>HTMLDOC </li></ul><ul><ul><li>Has been around for awhile </li></ul></ul><ul><ul><li>Supports a subset of html (no css, no xhtml or html 4.0) </li></ul></ul><ul><ul><li>Supports basic UTF-8/Unicode for ‘western’ languages </li></ul></ul><ul><li>wkhtmltopdf </li></ul><ul><ul><li>Based on WebKit rendering engine </li></ul></ul><ul><ul><li>Might be some issues in different OSes (windows) </li></ul></ul><ul><ul><li>Relatively new library </li></ul></ul>
    12. 12. Use PDF Templates if.. <ul><ul><li>The document is a form to be filled in (text fields, checkboxes, etc) </li></ul></ul><ul><ul><li>The structure is mostly static </li></ul></ul><ul><ul><li>The document is very large </li></ul></ul><ul><ul><li>The formatting is complex </li></ul></ul><ul><ul><li>You don’t mind calling out to a library </li></ul></ul>
    13. 13. PDF Template binding <ul><li>pdftk </li></ul><ul><ul><li>Build document with any tool that can output as pdf </li></ul></ul><ul><ul><li>Add in the form fields with Acrobat editor </li></ul></ul><ul><ul><li>Bind fdf data against pdf template </li></ul></ul><ul><ul><li>Very powerful pdf manipulation features </li></ul></ul><ul><li>iText </li></ul><ul><ul><li>Java library </li></ul></ul><ul><ul><li>Very powerful </li></ul></ul><ul><ul><li>Well known with lots of examples/tutorials, and books </li></ul></ul><ul><ul><li>Can also merge/split pdf files, add watermarks, etc </li></ul></ul><ul><ul><li>Pdf Form Binding example </li></ul></ul>
    14. 14. Use PDF Generation if.. <ul><ul><li>The content/structure is dynamic </li></ul></ul><ul><ul><li>The document is not too large </li></ul></ul><ul><ul><li>The formatting is not too complex </li></ul></ul><ul><ul><li>You prefer a pure ruby library </li></ul></ul><ul><ul><li>You prefer an open source solution </li></ul></ul>
    15. 15. PDF Generation Libraries <ul><li>JasperReports </li></ul><ul><ul><li>Well known java library, multiple outputs </li></ul></ul><ul><ul><li>May complicate dev/deployment dependencies </li></ul></ul><ul><li>PDF::WRITER </li></ul><ul><ul><li>Pure Ruby. Has been around for awhile </li></ul></ul><ul><ul><li>Many examples out there </li></ul></ul><ul><ul><li>Powerful, but ‘tedious’ syntax for positioning, styling, etc </li></ul></ul><ul><li>Prawn </li></ul><ul><ul><li>Lightweight, easy to learn syntax </li></ul></ul><ul><ul><li>Newer library, still in alpha, but very promising </li></ul></ul><ul><ul><li>Faster than PDF::Writer </li></ul></ul><ul><ul><li>Continues to get faster and better </li></ul></ul>
    16. 16. I chose Prawn <ul><li>Because… </li></ul><ul><ul><li>Lots of clear examples </li></ul></ul><ul><ul><li>Worked well for the report style that I needed (dynamic structure, simple table-based layout) </li></ul></ul><ul><ul><li>Quick to generate pdfs on demand </li></ul></ul><ul><ul><li>Fastest pure ruby pdf tool out there </li></ul></ul><ul><ul><li>Code was well tested and easy to follow </li></ul></ul><ul><ul><li>Forum/mailing list was active and helpful </li></ul></ul>
    17. 17. Prawn history <ul><li>Gregory Brown </li></ul><ul><ul><li>Mendicant project, raised $10k to work on open-source projects </li></ul></ul><ul><ul><li>Goal was to improve report and pdf generation for ruby </li></ul></ul><ul><ul><li>Ruport reporting framework (multiple report types) </li></ul></ul><ul><ul><li>Prawn </li></ul></ul><ul><ul><li>Just released Ruby Best Practices book </li></ul></ul>
    18. 18. Prawn 101 <ul><li>What it can’t do </li></ul><ul><ul><li>Complex formatting, nested tables </li></ul></ul><ul><ul><li>Edit existing pdfs </li></ul></ul><ul><ul><li>Encryption/security (coming soon – 9/15) </li></ul></ul><ul><li>What it can do </li></ul><ul><ul><li>Very easy to learn syntax </li></ul></ul><ul><ul><li>Easy Image embedding </li></ul></ul><ul><ul><li>Easy to manage table-based layouts </li></ul></ul><ul><ul><li>Simplified positioning commands </li></ul></ul>
    19. 19. Prawn examples
    20. 20. Examples <ul><li>Install </li></ul><ul><ul><li>Gem install prawn </li></ul></ul><ul><ul><li>Or git clone git://github.com/sandal/prawn.git </li></ul></ul><ul><ul><li>Make sure the tests pass </li></ul></ul><ul><ul><ul><li>May have to install another submodule or two </li></ul></ul></ul>
    21. 21. Examples <ul><li>Methods </li></ul><ul><ul><li>PDF </li></ul></ul><ul><ul><li>Text </li></ul></ul><ul><ul><li>Bounding_box </li></ul></ul><ul><ul><li>Font </li></ul></ul><ul><ul><li>Move_down </li></ul></ul><ul><ul><li>Mask </li></ul></ul><ul><ul><li>Page </li></ul></ul><ul><ul><li>Image </li></ul></ul><ul><ul><li>Stroke </li></ul></ul>
    22. 22. Examples <ul><li>Basic syntax examples </li></ul><ul><ul><li>Text </li></ul></ul><ul><ul><li>Images </li></ul></ul><ul><ul><li>Overflow </li></ul></ul><ul><ul><li>Orientation </li></ul></ul>
    23. 23. Text & Image Text_image_sample
    24. 24. Text overflow Text_overflow_sample
    25. 25. Page Orientation orientation sample
    26. 26. Examples <ul><li>Intermediate </li></ul><ul><ul><li>Table </li></ul></ul><ul><ul><li>Utf-8 </li></ul></ul><ul><ul><li>Drawing </li></ul></ul><ul><ul><li>Bounding box </li></ul></ul><ul><li>Install </li></ul><ul><ul><li>Gem install prawn-layout </li></ul></ul>
    27. 27. Tables table sample
    28. 28. Utf-8 UTF-8 sample
    29. 29. Drawing & bounding_box bounding
    30. 30. Prawn Performance <ul><li>Numbers </li></ul><ul><ul><li>Around 20 times faster than PDF::Writer </li></ul></ul><ul><ul><li>Even faster on ruby 1.9 </li></ul></ul><ul><ul><li>Well designed (seems to scale linearly) </li></ul></ul><ul><ul><li>Images are only loaded once </li></ul></ul>
    31. 31. PDF TESTING
    32. 32. How do I test a PDF? <ul><li>Tools </li></ul><ul><ul><li>Basic file and attachment testing </li></ul></ul><ul><ul><li>PDF::Reader </li></ul></ul><ul><ul><li>PDF::Inspector </li></ul></ul><ul><ul><li>Oragami library </li></ul></ul><ul><ul><li>Convert to Image and do a bit diff </li></ul></ul>
    33. 33. How do I test a PDF? <ul><li>Poor-man techniques </li></ul><ul><ul><li>Nothing blew up </li></ul></ul><ul><ul><li>File is present </li></ul></ul><ul><ul><li>Mocks were invoked as expected </li></ul></ul><ul><ul><li>Generate your pdfs and look at them </li></ul></ul><ul><li>PDF toolkits </li></ul><ul><ul><li>Assert page size </li></ul></ul><ul><ul><li>Open PDF and read its contents </li></ul></ul><ul><ul><li>Grep for objects </li></ul></ul><ul><ul><li>Assert order of objects </li></ul></ul>
    34. 34. Testing PDF structure
    35. 35. Testing PDF contents
    36. 36. Prawn-to
    37. 37. Prawn in your view <ul><li>All the good stuff </li></ul><ul><ul><li>script/plugin install git://github.com/thorny-sun/prawnto.git </li></ul></ul><ul><ul><li>Render pdf template with .pdf.prawn extension </li></ul></ul><ul><ul><li>DRY up common pdf configuration settings </li></ul></ul><ul><ul><li>Access to helpers (useful for currency, dates, text) </li></ul></ul>
    38. 38. Prawn-to: controller
    39. 39. Prawn-to: view Prawn-to sample
    40. 40. Advanced Prawn with_reckless_abandon
    41. 41. Advanced examples <ul><li>What else can we do? </li></ul><ul><ul><li>Grid based layout </li></ul></ul><ul><ul><li>Labels & Calendars </li></ul></ul><ul><ul><li>Annotations & Links </li></ul></ul><ul><ul><li>Google charts </li></ul></ul>
    42. 42. Grid Layout Grid sample
    43. 43. Grids & Labels Labels sample
    44. 44. Google Charts api Charts sample
    45. 45. Prawn-Format Nice and easy, just got nicer, and easier
    46. 46. Prawn-format <ul><li>Use HTML and style syntax </li></ul><ul><ul><li>Basic tags </li></ul></ul><ul><ul><li>Alter existing styles </li></ul></ul><ul><ul><li>Create new styles </li></ul></ul><ul><ul><li>Links </li></ul></ul>
    47. 47. Prawn-format: html and style Format
    48. 48. Putting it all together <ul><li>Mash up </li></ul><ul><ul><li>Prawn, prawn-layout </li></ul></ul><ul><ul><li>Prawn-to </li></ul></ul><ul><ul><li>Prawn-format </li></ul></ul><ul><ul><li>Google charts api </li></ul></ul><ul><ul><li>Twitter- search </li></ul></ul><ul><ul><li>Heroku & git </li></ul></ul>Twitter_Timelines
    49. 49. More to come <ul><li>Roadmap & projects </li></ul><ul><ul><li>Security & encryption ( prawn-security) </li></ul></ul><ul><ul><li>Prawn-js </li></ul></ul><ul><ul><li>Clean up </li></ul></ul><ul><ul><li>Improved grid/table support </li></ul></ul><ul><ul><li>Improved docs and examples </li></ul></ul>
    50. 50. Questions? speakerrate.com /jmccaffrey
    51. 51. Links <ul><li>Prawn: prawn.majesticseacreature.com / </li></ul><ul><li>Prawn-to: cracklabs.com/prawnto </li></ul><ul><li>Google Charts: chart.apis.google.com / </li></ul><ul><li>Twitter-Search: github.com/dancroak/twitter -search </li></ul><ul><li>Blog: http://www.pathf.com/blogs/author/john-mccaffrey / </li></ul>PDF Generation in Rails John McCaffrey