#78
Nov 04, 2007

Generating PDF Documents

In this episode I will show you how to create PDF documents using the excellent PDF::Writer gem.
Download (17.2 MB, 7:13)
alternative download for iPod & Apple TV (10.4 MB, 7:13)

Resources

# environment.rb
require 'pdf/writer'
Mime::Type.register 'application/pdf', :pdf

# products_controller.rb
def index
  @products = Product.find(:all)
  respond_to do |format|
    format.html
    format.pdf do
      send_data ProductDrawer.draw(@products), :filename => 'products.pdf', :type => 'application/pdf', :disposition => 'inline'
    end
  end
end

# product_drawer.rb
def self.draw(products)
  pdf = PDF::Writer.new
  products.each do |product|
    pdf.text product.name
  end
  pdf.render
end
<p><%= link_to 'PDF Format', formatted_products_path(:pdf) %></p>

RSS Feed for Episode Comments 39 comments

1. pimpmaster Nov 04, 2007 at 23:43

I just had to say "W00000000T!"


2. Marcello Nov 05, 2007 at 00:43

Hi Ryan!

To generate PDF reports there's also *RGhost*. It's a gem (also available as a rails plugin) that wraps PostScript with pure Ruby syntax. The gem is very stable and tested with reports over 1k pages in various OS's. The downside is that you need ghostscript libs installed.

More info: "RGhost[Rubyforge]":http://rubyforge.org/projects/rghost/


3. jurglic Nov 05, 2007 at 01:49

Hello Ryan,

I must agree with others, your screencasts are really top notch. Keep up the good work!

Regarding this one, I have one question, but it is not about writing pdf documents - I want to read and parse pdf. Is there some useful gem/plugin available for this kind of stuff? I've looked around but without any success. I would really appreciate any tip or recommendation on how to get into pdf parsing with ruby/rails.

Thanks and best regards!


4. rene Nov 05, 2007 at 02:26

Hello Marcello,

i tried to work with PDF::Writer in the last weeks, and i have to say that RGhost looks really good, but do you know about some translation, because http://rghost.rubyforge.org/doc/ looks english but is in fact Portuguese...

Or does anybody has some short sample apps to build on???

Thanks

René


5. QuBiT Nov 05, 2007 at 02:36

Hi Ryan,

1st,
thx for this one, just great as always.

2nd,
maybe you want to share your experience using other pdf-writing-tools(gems) in some words, which you mentioned to be not as easy as this one, but better.
(Additional Links in the resources of this episode would be enough)

3rd,
with the new rails (upcoming versions) you can put your mimetypes in a separate file in the folder 'configuration/initializers' which is called 'mime_types' and for example put the 'require'-stuff in a seperate file 'requirements.rb' to keep your envirements.rb file clean (no changes)

4th,
keep going ^^


6. bryanl Nov 05, 2007 at 03:56

There is nothing excellent about the PDF::Writer stuff... right now.

The Ruports[1] guys have just taken this over, and hopefully they make it the awesome package is could be.

1: http://www.rubyreports.org


7. TJ Nov 05, 2007 at 06:04

Thanks for the (as always) well-done screencast!

I've got a Rails app that I'll be adding PDF generation to soon. I've collected some links to various blog entries and tutorials. Maybe others will find them useful.

http://del.icio.us/tjstankus/pdf


8. Paul Barry Nov 05, 2007 at 08:15

Any thoughts on the rails PDF plugin?

http://railspdfplugin.rubyforge.org

Seems a lot cleaner to me to use an .rpdf view than putting a "Drawer" class in lib.


9. Brian Nov 05, 2007 at 10:16

A cool extension to this would be to also generate a flash paper doc. I'm not sure of the exact implementation, but I know a lot of the social document sharing services are doing this. That way the doc can be viewed in the browser rather than needing a separate app.


10. David Nov 05, 2007 at 16:50

Very cool extension.
Thanks!


11. Senthil Nayagam Nov 06, 2007 at 03:36

Hi Brian,

Flash paper is mostly generated via printing method not authored per se.

we have build a rails app urwords.com which uses it that way.

you can contact us in case you need any help


12. Joan Nov 06, 2007 at 10:43

Anybody got an idea how to generate a google map in PDF?


13. Ryan Bates Nov 06, 2007 at 15:27

@Marcello, I haven't tried RGhost yet. I'll have to look into it. Thanks for the suggestion!

@QuBit, a while ago I tried most of the options mentioned on this wiki page:

http://wiki.rubyonrails.org/rails/pages/HowtoGeneratePDFs

Out of those PDF::Writer was by far my favorite so I've stuck with it and haven't had any complaints. I should look into some more newer options though (RGhost).

@Paul, for simple PDFs I think a template view would work really well, but most of the PDFs I've done get fairly complex. In those cases it helps having an actual object with methods and variables.


14. iceskysl Nov 08, 2007 at 01:12

cool~thx.

and can anybody share somethings about “how to genarate reports chart in rails".


15. markus Nov 09, 2007 at 00:55

I tried out the PDF:Writer a while ago. One thing that bothered me is that it does not support Unicode. There is a hack to make it work with some European languages (documented in the rails wiki). However, Asian languages, Arabic, and so on are not supported. And since I read that Austin Ziegler isn't working on the PDF:Writer project any more there doesn't seem to be too much hope that this will change soon. Or does any one have new info on that?


16. Mario Nov 09, 2007 at 07:04

@jurglic,

FYI i just came across this... http://software.pmade.com/pdfreader

Looks like it was started in October but couldnt really find anything else on the net for reading PDFs.


17. JCD Nov 09, 2007 at 15:53

你的英语讲的很好,内容也不错,我们很喜欢!
但是,有点小遗憾,就是有些东西讲的太少了.
我看过layout那部分,partial那部分没有涉及到!


18. Nik Nov 10, 2007 at 09:17

Hi iceskysl, for charts I think you could use this:
http://elctech.com/2007/9/7/swfchart-generator

I didn't try it but like the results. It uses http://www.maani.us/xml_charts/index.php?menu=Gallery
which can be controlled also via PHP.

Nik


19. Marcello Nov 11, 2007 at 07:12

@rene and Ryan:

The translation is underway. At least the pdf manual shall be ready by the ende of the week. The code soon follows. =)


20. rene Nov 12, 2007 at 03:09

@Marcello:

this would be really great. Thanks a lot for your efforts!!!


21. iceskysl Nov 13, 2007 at 21:06

@Nik:
your are so kind~
that's cool~
thx~


22. Jaime Mora Ramones Nov 14, 2007 at 07:21

Hi Ryan,

Thanks, your screencasts, just great as always!

I wonder why you use the ProductDrawer class in lib. Why don't you use a method in the Product Model?


23. Björn Großmann Nov 17, 2007 at 04:38

Thank you so much for your great screencasts! Very inspiring and informative and quite entertaining as well:-)

I ran into problems with the encoding of German Umlaute characters, such as "äöüÄÖUß" with PDF::Writer.

I have my source code encoded in UTF-8 and PDF::Writer cannot yet display UTF-8 characters.

A great solution is to overwrite PDF::Writer's text method and have it convert the text from UTF-8 to ISO-8859-15, like so:

CONVERTER = Iconv.new( 'ISO-8859-15//IGNORE//TRANSLIT', 'utf-8')
module PDF
    class Writer
        alias_method :old_text, :text

        def text(textto, options = {})
            old_text(CONVERTER.iconv(textto), options)
        end
    end
end

All credits go to Peter Krantz and Anibal. See http://www.peterkrantz.com/2007/utf8-in-pdf-writer/


24. Knut Dec 01, 2007 at 17:48

Hi Ryan,
very nice railscast! This Railcast was very interesting.

A time extended episode about the formating seaction would be great to learn more about layout development (is this so far supported in the writer?).

In general an extend version of PDF:Writer with UTF-8 or international support planned yet?
Could this also be done easily in Ruby (asked from a beginner point of view)?


25. Anthony Ettinger Dec 06, 2007 at 08:32

Excellent...EXCELLENT....*rasps fingers*


26. Valerie Dec 11, 2007 at 23:56

Hi,

I would like to implement a PDF function into my application.
I have already installed the pdf-writer-1.1.6.

Firstly, there are several folders in this zip folder e.g. pdf, writer etc.
Where exactly should I paste this folders to?

Secondly, I added the following codes to the environment.rb:
require 'pdf/writer'
Mime:Type.register 'application/pdf',:pdf

Where should I place these codes and the should the word "application" be replaced with my project's name?
I am sure that there is something wrong with the codes in here as when i restarted WEBRICK in my command prompt, some of the errors that occurred are:
- already initialized constant OPTIONS
-no such file to load -- transaction/simple<MissingSourceFile>

Can someone please give me a solution? Because there is no way I can implement the codes if I cannot start my WEBrick successfully.
This is quite urgent as the deadline is drawing nearer. Please help!
Thank you very much!!!


27. Uzytkownik Dec 15, 2007 at 11:02

@Valerie:
1. Install by gems (not from source) - it should be a command line tools but in netbeans/eclipse plugins you have GUI
2. 'application/pdf' is mime type


28. Valerie Dec 17, 2007 at 16:24

Thanks! Error occurred...

undefined method `formatted_programmes_path'

Seriously, I don't see where i should define this.


29. James Dec 19, 2007 at 04:10

hi, i am using pdf:writer with attachment_fu and when i am trying to load an image into the pdf like so.

avatar = @villa.avatar.public_filename()
pdf = PDF::Writer.new(:paper => "A4")
pdf.select_font "Helvetica"
pdf.image avatar, :resize => 0.75

but all i get is an error.

"No such file or directory - /avatars/0000/0007/1.jpg"

so whats wrong here?

thx for the great screencast :)


30. RichCorbs Jan 10, 2008 at 20:11

Thanks for the screencast.

Is passing instance variables as arguments the only way to get instance variables into in the drawer method? I have a controller that collects/calculates a lot of information destined for output as rhtml or pdf.

Any tips or URLs I could follow would be appreciated.

Thanks again.


31. svend gundestrupo Mar 16, 2008 at 03:31

Great screencast.
But I get this error:
Routing Error

no route found to match "/reporting/index.pdf" with {:method=>:get}

Can you help me?

regards
svend


32. JJohnston Mar 21, 2008 at 07:17

@svend:

I am working on a rails 1.2.6 app that does not use RESTful routing. To get this to work for me, I added the following to routes.rb:

map.connect ':controller/:action.:format'


33. Bala Paranj May 14, 2008 at 01:26

Check out the above link for Extremely Simple PDF Generation in Rails using HTMLDOC


34. Wing May 23, 2008 at 01:18

Hi,
I wonder how i get an error " undefined method `pdf'". I think I follow all you stpes.

thanks

wing


35. kino May 23, 2008 at 01:57

By virtue of pure reason, it must not be supposed that, irrespective of all empirical conditions, the Ideal of human reason would thereby be made to contradict our sense perceptions, but the Transcendental Deduction can never furnish a true and demonstrated science, because, like the manifold, it would thereby be made to contradict disjunctive principles.


36. rrruby May 31, 2008 at 04:35

I used rfpdf since pdf-writer did not go together with activescaffold (+activescaffoldlocalize +calendar_date_select). Be sure to pick the right plugin (http://code.google.com/p/rfpdf/source/checkout), since there are two.


37. Shairon Toledo Jun 19, 2008 at 09:17

Now RGhost 0.8 with English Documentation. For PDF, PS, TIF, etc

The Ghost's speed!!

see http://rghost.rubyforge.org


38. Justin Aug 22, 2008 at 12:40

Hi, this looks great. Trying it out, but encountered an error:

uninitialized constant Mime::PDF

...
require "pdf/writer"
Mime::Type.register 'application/pdf', :pdf
...

...
          format.pdf do
            pdf = PDF::Writer.new
            pdf.text "test"
            send_data pdf.render, :filename => 'threads.pdf', :type => 'application/pdf', :disposition=> 'inline'
...
          end

Thanks for any help!


39. Scott Sep 01, 2008 at 18:26

Justin,

I am having the same problem suddenly. It seems related to using ruby enterprise instead of normal ruby. It's the only thing I've recently changed.

Anyone else notice it being related to Ruby Enterprise?

Add your comment:

(SKIP THIS ONE)

(required)

(not shown)


(use pastie or gist for code)

sponsored by:
if you want to help:
required:
Get Quicktime Player