DISQUS

ADS Blog: Easy PDF Generation with Ruby, Rails, and HTMLDOC

  • robbert shell · 2 years ago
    Lovely approach, used the same in my projects. Only really problem Have had is with embedded, generated images which are sometime lost as if htmldoc expects file paths and not urls. Have on todo to look at fixing this with some pre caching.

    Tried a number of other approaches before this and definitely the best and really easy to implement

    Robert.
  • Chris Kaukis · 2 years ago
    Robert,

    I had the same problem with images, but have not looked into it yet as it was not of primary concern.
    Chris
  • Jamie Hill · 2 years ago
    Looks a nice alternative to PDF Writer. Does is take into account CSS?
  • Chris Kaukis · 2 years ago
    Jamie,

    I am not entirely sure. I believe the website states the nightly builds have at least some support for CSS.


    Chris
  • Dan Kubb · 2 years ago
    Would you mind posting an example of what the example view renders to when rendered as PDF?

    I've got some code using PDF::Writer, and managing the templates is a pain. If I could design the templates using normal HTML views, and then render them as PDF with some reasonable control over the style, I'd be a happy man.
  • Chris Kaukis · 2 years ago
    Dan,

    I will try and post an example PDF tomorrow morning. However, I can tell you it looks pretty close to what a normal HTML page would look like.

    @Robert Shell: I tested images and you give it the full path. For example /Users/chris/Projects/railsapp/public/images/logo.gif


    Chris
  • Chris W · 2 years ago
    If you have to have css support and don't mind spending some money, check this solution out.

    HTML / CSS to PDF using Ruby on Rails
    http://sublog.subimage.com/articles/2007/05/29/...
  • Dave · 1 year ago
    WTF is formatted_items_path? I can't find documentation on this anywhere.
  • Chris Kaukis · 1 year ago
    @Dave:

    It comes from restful routes. Example:

    map.resources :posts

    gives you:

    posts_path as well as formatted_posts_path(:format)

    Try rake routes within in your project directory to see all your routes.

    Chris
  • Dave · 1 year ago
    also, how do you name the pdf
  • Dave · 1 year ago
    Chris, thanks for the clarification on the routing for me. Much obliged.
  • Chris Kaukis · 1 year ago
    @Dave:

    send_data has an option for filename.

    send_data render_to_pdf({ :action => 'index.rpdf', :layout => 'pdf_report' }), :filename => "foobar.pdf"


    Chris
  • Nidhika · 1 year ago
    Whem I am puting
    " Mime::Type.register 'application/pdf', :pdf
    require 'htmldoc'"

    In config/enviroment.rb file in the last webrick server not restart. How am I solve this issue.
    Is anybody help me

    Thanks
    Nidhika
  • Robert Dempsey · 1 year ago
    @Nidhika: ensure that you are using the ' mark and not the full quotation mark if you copy/pasted from the post.
  • Matt · 1 year ago
    Hi all, am I the only one who can't ever get images to be included in the document using PDF::HTMLDoc?

    If I run HTMLDOC from the command line with supposedly the same arguments (basically just --webpage) then it works a treat, even if I point it at the URL for my dynamically generated rails page. However if I call it using the Rails GEM then it renders everything except the images.

    It's driving me bonkers and pretty urgent. I've tried all sorts of things including the pdf_image_tag helper above with numerous modifications (eg. adding file:/// at the start).

    Cheers,
    Matt
  • Chris Kaukis · 1 year ago
    Matt,

    I found that I had to use absolute path to the image. Thus, for example:

    /Users/chris/src/my_rails_app/public/images/some_image.png


    I hope that helps.
  • Matt · 1 year ago
    Hi Chris,

    Thanks for that. The trouble is (and I should have mentioned) that it's on Windoze. If I set it to 'c:\rails\project\public\images\some_image.jpg', load the page directly and save it to disk and then load the page in explorer it looks fine (that is, it loads the image/s from disk). But the Ruby htmldoc plugin still doesn't get them.

    I've also tried prepending file:/// and a few other things.

    //matt
  • Kelly · 1 year ago
    Hi Chris. Say quick question.. I have everything wired up but I'm actually calling the render_to_pdf from another controller in my app. It work fine but give me this error.
    undefined method `size' for false:FalseClass
    I walk thru it with the debugger and it seems that data is nil so it can't do a size. I assume that is because the model for my control is not an option to post to the render_as_pdf but not sure.
  • Kelly · 1 year ago
    As an addition when I debug it I get here in the streaming and I see data is null..

    ********************
    def send_data(data, options = {}) #:doc:
    logger.info "Sending data #{options[:filename]}" unless logger.nil?
    send_file_headers! options.merge(:length => data.size)
    @performed_render = false
    ********************
    is there a way to pass the record I have when I call this?
    right now we do send_data render_to_pdf but is there a way to say @object so I can pass the object created by the finder? send_data @object.render_to_pdf does not work either as I get a missing method render_to_string that way
  • Christoph · 1 year ago
    same error here, false class when using an image... any solution?
  • Chris Kaukis · 1 year ago
    It sounds like you are missing something. I would have to see your code to help more I think. Sorry.
  • Christoph · 1 year ago
    I tracked it down to some weird htmldoc output, which contains whitespaces sometimes.

    Here is a patch that solves my problem:
    http://textmode.at/2008/5/14/ruby-htmldoc-gem-f...

    Not sure if it's the same problem as the user above has.
    I contacted the author htmldoc people.

    greetings
  • kajinski · 1 year ago
    Christoph, YOU ROCK.

    Thanks for the patch!

    I was getting the exact same error when using the pdf_image_tag helper. Applied the patch and viola! Image renders perfect.
  • Chris · 1 year ago
    sorry to ask what may be a simple answer, but how do you apply that patch?

    thx...
  • srishti · 1 year ago
    How can we use html doc in rails 1.2.3
  • Webagentur · 1 year ago
    Hey, that has me very helped. Thanks!
  • dafinn · 1 year ago
    First of all, Great work! Due to the Patch of Christoph printing Images with a complete path is working now!
    BUT... I am storing Articles in my Database. I use FCKEditor for the User-interface - the text is stored HTML formatted and the path for Images is stored in the HTML Code in form of "/public/uploads/Images" and so on. I have explored that HTMLDOC needs the full path(as some People above). For Example http://0.0.0.0:3000/public/uploads/Images ...
    Has anyone an idea how to fix this? I have seen the pdf_image_tag but i am not sure how it works...
  • Eric Wagoner · 1 year ago
    dafinn:

    I've got an app that does the same. I wrote a very simple helper that expands the image paths.

    def write_full_image_path(text)
    newtext = text.gsub('img src="', 'img src="' + File.expand_path(RAILS_ROOT) + '/public/')
    newtext
    end

    Then, in my .rpdf files, I call for write_full_image_path(model.formatted_text)
  • Francesco · 1 year ago
    Just a note for Ubuntu users: HTMLDOC must be installed by hand (configure, make, make install as stated here by author): if you install it with apt-get then HTMLDOC is not working in rails :)
    With Debian is fine to install htmldoc with apt-get install.

    The patch for images is necessary in both Debian and Ubuntu.

    Thank you *very much* to all the people who shared their knowledge here :)
  • Robert · 1 year ago
    def self.generate_pdf(url, links=false)
    doc = Document.new
    doc.mime = 'application/pdf'
    pdf = PDF::HTMLDoc.new
    pdf.set_option :bodycolor, :white
    pdf.set_option :links, links
    pdf.set_option :webpage, true
    pdf.set_option :path, "#{RAILS_ROOT}/public/"
    pdf << url
    pdf.footer ".1."
    if pdf.generate
    puts "Successfully generated a PDF file"
    doc.body = pdf.generate
    else
    puts "ERROR!--------------------------------------------"
    for error in pdf.errors
    puts error
    end
    end
    doc
    end

    The important line is the pdf.set_option :path, #{RAILS_ROOT}/public/"

    It tells htmldoc to look in your public folder for images.

    If you manually create the img tag this will work and the images will be the same on the web as in the pdf. Using image_tag however will not work, because rails adds on the uid to each image.

    If you were adventurous, you could parse out the uid from the tags with gsub. Now if I could just figure out how to keep the errors without having to generate twice.
  • Robert · 1 year ago
    saving for later
  • bharati · 1 year ago
    getting file does not begin with '%pdf-' error.. Can anyone help me..
  • kams · 10 months ago
    Hello,

    getting error as for rails application.
    "'htmldoc' is not recognized as an internal or external command,\noperable program or batch file.\n"

    Thank you
  • Fernando · 9 months ago
    Hi, I want to know how can I set the page as landscape.
  • Yves-Eric · 9 months ago
    Nice article, I had things up and running in a few minutes...

    But show stopper for me: HTMLDOC does not support CJK (Chinese, Japanese, Korean) languages.
  • Robert Hall · 7 months ago
    Having some issues with HTMLDoc, Rails 2.2.2 and Phusion Passenger - Apache. With the GEM installed, passenger refuses to start up with an "Unknown error" and doesn't log anything so debugging is tough. Have you had any successful implementations on Rails 2.2.2 with Passenger? Suggestions on how to proceed?
  • Robert Dempsey · 7 months ago
    Hi Robert. We haven't tried HTML doc with passenger. We have successfully used Prawn with that setup though. I'd give that a try.
  • Nuno Prata · 4 months ago
    Hello m8. In first place thank you for the great gem/plugin.

    I'm currently having a problem. I'm trying to apply a body image to my pdf's using the method:
    pdf.set_option :bodyimage, "report_bg.jpg"

    It's not that the image doesn't display right, it just doesn't display at all...

    Any ideas? Tks in advance
  • sildur · 3 months ago
    A suggestion: if you are dealing with an UTF-encoded website, you should replace the line:
    data = render_to_string(options)
    with the following line:
    data = Iconv.conv('ISO-8859-15//IGNORE//TRANSLIT', 'utf-8', render_to_string(options))
    This is needed because htmldoc (at least v1.8) doesn't support UTF
  • Torpedo · 3 months ago
    Thank You!!!

    Torpedo Gratis
  • Wolfram · 3 months ago
    Nice article, thanks a lot!
    I'm trying to include special htmldoc comments, such as <!-- NEW PAGE -->, <!-- FOOTER LEFT "foo" --> and so on, but failed so far. Does anyone have a hint?
  • Wolfram · 3 months ago
    Sorry this one got messed up. So, the special comments are > !-- NEW_PAGE-- <, > !-- FOOTER LEFT "foo" -- <.
  • itjobs1 · 3 weeks ago
    I've got some code using PDF::Writer, and managing the templates is a pain. If I could design the templates using normal HTML views, and then render them as PDF with some reasonable control over the style, I'd be a happy man.
    www.staffingpower.com