
PDFs in Pure Ruby - jmonegro
http://prawn.majesticseacreature.com/
======
patio11
Without Prawn I probably wouldn't have been able to do the web version of my
software in an acceptable amount of time. It is amazing software -- far
superior to every other way I have found to render PDFs, and I come from
Enterprise Java where that is practically a religious calling.

Incidentally, although this use is quite off-label: Prawn exposes a very nice
API for drawing arbitrary geometrical objects. ImageMagick/GraphicsMagick can
convert PDF files to image files in your favorite format. This means you can
use prawn to draw, e.g., an org chart for about a fiftieth of the pain it
would take to draw it using graphics primitives in ImageMagick or what have
you.

That reminds me -- I tried to throw money at the developers and they requested
I send it to Heifer International. Somebody is getting a cow because I didn't
have one writing my print jobs.

~~~
sandal
I think that our users might appreciate a magick-prawn extension that allows
Prawn::Document#to_svg (or other formats).

And also, thanks for donating!

~~~
patio11
I'd be happy to make you one, but it is literally one line of code after you
generate the PDF. I think my commit message for that feature was "PDF -> GIF.
I get paid for this!?"

~~~
sandal
Yeah, I guess it's easy enough to do on your own if you have RMagick handy.
Good point.

~~~
patio11
RMagick leaks memory like a sieve. I do this in a pair of worker threads that
just fire off system calls to the GraphicsMagick command. (Hat tip to HN: I
learned about it here and saved 50% on conversion time versus doing it with
ImageMagick.)

~~~
sandal
Ah, interesting. Yeah, I'm certainly aware of RMagick's memory issues,
fortunately, haven't had a need for it.

------
pjhyett
We use Prawn to generate GitHub's PDF receipts and FI invoices, it's a great
library.

~~~
bradediger
Sweet. We're working on a rewrite of the table layout engine (github:
bradediger/prawn-layout@refactor -- whoa, that is meta) so chime in if there's
anything that seems missing from the current API. cheers.

[edit: fix github project reference]

------
ChrisRicca
<http://pdf-render.heroku.com/> \- here's hello world in Sinatra with prawn,
to give you a sense of how fun it is to use :)

require 'rubygems' require 'sinatra' require 'prawn'

get '/' do "<h1>This is a simple pdf rendering webservice. GET <a
href='/hello%20world.pdf'>/hello%20world.pdf</a> to get a pdf back!</h1>" end

get '/*' do content_type('application/pdf') headers['Cache-Control'] =
"public, max-age=6000000000000000000"

    
    
      pdf = Prawn::Document.new
      pdf.text(params[:splat][0].gsub(/.pdf\z/,''))
      pdf.render

end

~~~
ChrisRicca
Sorry about that - <http://pastie.org/789318>

------
rubeng
Prawn is pretty neat, but what I'd really like to see is HTML to PDF in pure
Ruby. I had to use a Java library wrapped in a Ruby module to do this.
Complicates my server configuration (needs the JVM) more than I'd like.

~~~
oomkiller
Try Princely (blog post: [http://jimneath.org/2009/02/16/creating-pdf-
documents-in-rub...](http://jimneath.org/2009/02/16/creating-pdf-documents-in-
ruby-on-rails/)) <http://github.com/mbleigh/princely>

~~~
rubeng
That's just a wrapper over Prince XML, I ended up writing my own wrapper over
Flying Saucer: <https://xhtmlrenderer.dev.java.net/>

------
plinkplonk
I am not a Ruby programmer so this might be a dumb question, but how does
Prawn compare to Itext(Java)?

~~~
patio11
wc -l Print(ASTERIX_BORKS_HN).java #6 files, 1,800 lines

wc -l print_job.rb #1 file, 125 lines

This is not, strictly speaking, a fair comparison. In addition to being a
superior version of everything the Java version does, the Ruby version also
does GIF export, caching on the web server, and basic feature-wide analytics.
The Java just barely staggers its way to generating a NxM grid and putting
pleasingly aligned text in it. It is also littered with comments like:

// DO NOT EDIT. WILL NOT BE ABLE TO FIX. See r47 for what happened last time.
(See r53.) (See r128.)

Do it in Prawn. I seriously have attempted to get my company to run a one-
controller Rails app just to do PDF generation, because it would be cheaper
going forward than the _prodigious_ amount of effort we spend on report
generation in Java. (This was, sadly, not approved.)

~~~
sandal
Prawn should run perfectly in JRuby, and will be officially supported by its
1.0 release. Sneak it in a .jar :)

~~~
patio11
I actually considered doing just that, for weeks. As much as I would have
_loved_ to do it, the Java application is a desktop app, and putting in JRuby
would have added something like 15 MB to the installer.

I did propose that to work, though (we do generation on the server so the size
doesn't matter), and we have done it if we had an acceptable supply of Ruby-
speaking engineers. Bad news for them, good news for me: I would hate to have
their business hobbled when I leave.

------
RyanMcGreal
While you're at it, check out this PDF creator in pure javascript:

<http://code.google.com/p/jspdf/>

~~~
sandal
Whoa! Awesome. Prawn is "fast for Ruby" but still not fast when compared to
lower level implementations. How is performance here? (If it's decent, I'll
definitely need to steal some ideas :)

------
blasdel
I've been using prawn recently on a project, the only feature I'm missing is
the ability to read its own output so I can compose operations independently.

It looks like it would be pretty difficult to add -- prawn is implemented as a
clever DSL for writing postscript.

~~~
sandal
Prawn does not write postscript, it writes PDF. Though possibly similar in
appearance, two different beasts, for sure.

And actually, we have support for reading arbitrary PDF on edge, expect a
release in a few weeks :)

<http://github.com/yob/prawn/tree/templates_2010>

~~~
randy_parker
I use the soon-to-be integrated yob-templates_2010 fork to fill in existing
PDF forms. All you have to do is add a ":template => filename" in "pdf =
Prawn::Document.new()". You can also supply the template name to the prawn
document instance after creating it: "pdf(:template => filename)". (see the
prawn forum for details I posted there)

------
sandal
Some additional relevant links:

# source, wikis, bug tracker <http://github.com/sandal/prawn>

# mailing list <http://groups.google.com/group/prawn-ruby>

# my twitter account (I announce all Prawn releases and other stuff there --
mixed in with personal stuff)

<http://twitter.com/seacreature>

~~~
ThinkWriteMute
Please please please switch to Librelist :(

~~~
rufugee
At least Google Groups doesn't expose your email address to the world, while
it appears Librelist does (check out the archives here:
<http://librelist.com/browser/>). If you're on a librelist list, you're asking
to be spammed.

~~~
ichverstehe
Get a proper spam filter. Your mail address probably is out there already.

------
plinkplonk
Ok so another question for sandal. How do you begin to work on a pdf gen
library in your favorite language? read the pdf standard?

~~~
sandal
This would be a good discussion for the Prawn mailing list. Post there and
I'll reply with some details (and the other devs will likely chime in as
well).

Just let us know what sort of feature set you want to implement, and we can
point you to the relevant spec sections and supporting materials.

Prawn's source is pretty readable, and will be even more so as we refactor. A
trip through the source might help, too:

<http://github.com/sandal/prawn>

------
Shamiq
There's also - _require 'spreadsheet'_ \- for generating .xls files on the
fly:

<http://spreadsheet.rubyforge.org/Spreadsheet.html>

------
oomkiller
For generating PDFs with Ruby, Prince sure does look great, but it's a little
high for my tastes!

------
farrel
So... am I old fashioned for using ERb and LaTex?

~~~
MartinMond
Don't worry, I do it too. I'll wait for the day when Prawn can compete with
LaTeX's layouting :)

~~~
sandal
It never will. LaTeX is the right tool for layout, for now, at least. If
someone wants to implement something like that on top of Prawn, awesome. But
our goal isn't to be a layout tool, it's to provide all the low level tools
necessary to implement PDF features to specification.

The difference is the toolchain. All you need to do to run Prawn is dump the
files into your project.

