Rails: Convert HTML to PDF?

Ruby on-RailsPdf

Ruby on-Rails Problem Overview


What is the best and easiest way of taking HTML and converting it into a PDF, similar to use CFDOCUMENT on ColdFusion?

UPDATE: I really appreciate all the comments and suggestions that people have given so far, however I feel that people leaving their answers are missing the point.

  1. the solution has to be free or open sourced. one person suggested using pricexml and the other pd4ml. both of these solutions costs money (pricexml costing an arm and a leg) which i'm not about the fork over.

  2. they must be able to take in html (either from a file, url or a string variable) and then produce the pdf. libraries like prawn, rprf, rtex are produced using their own methods and not taking in html.

please don't think i'm ungrateful for the suggestions, it's just that pdf generation seems like a really problem for people like me who use ColdFusion but want to convert to Rails.

Ruby on-Rails Solutions


Solution 1 - Ruby on-Rails

The gem, WickedPDF, does exactly that.

Solution 2 - Ruby on-Rails

The greatest thing nowaday is PDFKit for this job:

Solution 3 - Ruby on-Rails

Try WickedPDF, PDF generator (from HTML) plugin.

Here is example

gem 'wicked_pdf'  
gem 'wkhtmltopdf-binary' 
#wicked_pdf is a wrapper for wkhtmltopdf, you'll need to install that, too

In Your Controller(I supposed you are in show method):

    respond_to  do |format|
      format.html
      format.pdf do
        pdf = render_to_string :pdf => 'test',
                         layout: 'pdf.html.erb',
                         template: 'show.pdf.slim',
                         header: { :right => '[page] of [topage]'},
                         margin: {top: 0,
                                  bottom: 0,
                                  left: 0,
                                  right: 0},
                         outline: {outline: true,
                                   outline_depth: 2}
        end
     end

In your view for PDF link

= link_to 'Download Pdf', you_show_path(@uour_object, format: :pdf)

If you want to send pdf in email attachment, first save your pdf file in public or temp folder then in mailer class (e.g. in mailers/e_mailer.rb)

attachments["test.pdf"] = File.read(Rails.root.join('public',"test.pdf"))
mail(:to => to, :cc => cc , :subject => "subject")

After sending email you can delete file

File.delete(Rails.root.join("public", "test.pdf"))

Solution 4 - Ruby on-Rails

I know this question is almost 5 years old at this point. However, new options are available.

Try Shrimp! https://github.com/adeven/shrimp

Solution 5 - Ruby on-Rails

After After a lot of blood sweat and tears I managed to write a pretty simple rails app that allows the user to write letter templates via TinyMce, these are then saved and can be viewed as pdf documents.

I decided to restrict the options in the wysiwyg editor as much as possible as some of the options don't work exactly as expected, but that's nothing a little gsub-ing couldn't solve if needed.

There is a ruby gem that wraps HTMLDOC which you'll need: PDF::HTMLDoc

Once you've got that, register the mime type, then you can do something like:

@letter_template = LetterTemplate.find(params[:id])

respond_to do |format|
      format.html
      format.pdf { send_data render_to_pdf({:action => 'show.rpdf',  :layout => 'pdf_report'}), :filename => @letter_template.name + ".pdf",  :disposition => 'inline' }
    end

In the application controller i've added the render_to_pdf method like:

def render_to_pdf(options =nil)
    data = render_to_string(options)
    pdf = PDF::HTMLDoc.new
    pdf.set_option :bodycolor, :white
    pdf.set_option :toc, false
    pdf.set_option :portrait, true
    pdf.set_option :links, false
    pdf.set_option :webpage, true
    pdf.set_option :left, '2cm'
    pdf.set_option :right, '2cm'
    pdf.set_option :footer, "../"
    pdf.set_option :header, "..."
    pdf.set_option :bottom, '2cm'
    pdf.set_option :top, '2cm'
    pdf << data
    pdf.generate
  end

You'll find more documentation on HTMLDOC site that Travis Beale Linked to. Hope this helps get you on your way and unless your documents are really complicated it should suffice. Let us know how you get on.

Solution 6 - Ruby on-Rails

The closest thing I found as a "solution" to this is by using JRuby and then using The Flying Saucer Project. I just wish that it would get ported over to Ruby so it could be a native solution. God I wish I was better at Java.

Solution 7 - Ruby on-Rails

  • There is RPDF in which you describe your pdf's in as a view.
  • There also is RTEX which uses (La)TeX to generates pdf's.

Solution 8 - Ruby on-Rails

The project may have stagnated, but Pisa (aka XHTML2PDF) is a Python lib which does CSS+HTML to PDF. used it in a (low-traffic) Rails app a while back by driving it as a commandline tool -- worked pretty well.

Solution 9 - Ruby on-Rails

I would like to suggest you the HTML to PDF solution by https://grabz.it.

They have a very flexible and simple-to-use screenshot API which can be used by any type of Ruby application.

If you want to try it, at first you should get the authorization app key + secret and the development free SDK

Then, in your app, the implementation steps would be:

//initialization    
require 'grabzit'
grabzItClient = GrabzIt::Client.new("APPLICATION KEY", "APPLICATION SECRET")

//capturing the url to PDF
grabzItClient.url_to_pdf("http://www.google.com")	

Next is the saving. You can use one of the two save methods, save if accessible callback handle available:

grabzItClient.save("http://www.example.com/handler/index") 	

And save_to if you need a synchronous save (which will force your application to wait while the screenshot is created):

filepath = "images/result.jpg"
grabzItClient.save_to(filepath) 

Check the documentation for details about the saving.

That's all. It's possible to get other kinds of screenshots such as image screenshots as well.

Solution 10 - Ruby on-Rails

If you want to have really good quality (think, proper layout/CSS etc) you need to create a process embedding a real webbrowser rendering it offscreen and printing it via PDF printer driver.

Solution 11 - Ruby on-Rails

There is for sure no direct way to do this in Ruby (at least there wasn't when I was trying to do it couple of months ago). If you really can't avoid generating your pdfs from html, you should probably look around for some external tools or services for this purpose.

Good luck!

Solution 12 - Ruby on-Rails

I am trying the library from www.pd4ml.com

here is a code snip....

I pull in the html into the String content. Then I do a couple things like replace the radio buttons with checkboxes and then run it through the pd4ml library to render the pdf.
The result looks pretty much like the original page....

	String content = nextPage.generateResponse().contentString();
	
	content = content.replace("Print", "");
	content = content.replace("Back", "");
	
	content = content.replace("border=\"1\"", "border=\"0\"");
	content = content.replace("radio", "checkbox");
	
	java.net.InetAddress i = java.net.InetAddress.getLocalHost();
	String address =  i.getHostAddress()+":53000";
	
	content = content.replace("img src=\"/cgi-bin", "img src=\"http://"+address+"/cgi-bin");

	System.out.println(content);
	
    PD4ML html = new PD4ML();
	html.setPageSize( new java.awt.Dimension(650, 700) );
	html.setPageInsets( new java.awt.Insets(30, 30, 30, 30) );
	html.setHtmlWidth( 750 );
	html.enableImgSplit( false );
	html.enableTableBreaks(true);

	StringReader isr = new StringReader(content);
	baos = new ByteArrayOutputStream();
	html.render( isr, baos);
	PDFRegForm pdfForm = (PDFRegForm)pageWithName("PDFRegForm");
	pdfForm.baos = baos;
	pdfForm.generateResponse();

Solution 13 - Ruby on-Rails

Have you tried looking at html2pdf? the home page is http://html2pdf.seven49.net/Web/

There is also a sourceforge project of it.

Alan

Solution 14 - Ruby on-Rails

HTMLDOC?

  • converts HTML to PDF;

  • Free and Open Source (commercial support available);

  • can be used as...

  • ...standalone application,

  • ...for batch document processing,

  • ...or run as a web-based service;

  • interface is CLI or GUI.

Solution 15 - Ruby on-Rails

Not specific to Ruby, but the best solution I've found to this is the open source [HTMLDOC][1].

[1]: https://www.msweet.org/projects.php?Z1 "HTMLDOC"

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionrip747View Question on Stackoverflow
Solution 1 - Ruby on-RailsSebastianView Answer on Stackoverflow
Solution 2 - Ruby on-Railsfl00rView Answer on Stackoverflow
Solution 3 - Ruby on-RailsSajjad MurtazaView Answer on Stackoverflow
Solution 4 - Ruby on-RailsMichaelView Answer on Stackoverflow
Solution 5 - Ruby on-RailstsdbrownView Answer on Stackoverflow
Solution 6 - Ruby on-Railsrip747View Answer on Stackoverflow
Solution 7 - Ruby on-RailsmatView Answer on Stackoverflow
Solution 8 - Ruby on-RailsThomasView Answer on Stackoverflow
Solution 9 - Ruby on-RailsJohnnyView Answer on Stackoverflow
Solution 10 - Ruby on-RailsJohan DahlinView Answer on Stackoverflow
Solution 11 - Ruby on-RailsMilan NovotaView Answer on Stackoverflow
Solution 12 - Ruby on-RailsAdam YocumView Answer on Stackoverflow
Solution 13 - Ruby on-RailsapolinskyView Answer on Stackoverflow
Solution 14 - Ruby on-RailsKurt PfeifleView Answer on Stackoverflow
Solution 15 - Ruby on-RailsTravis BealeView Answer on Stackoverflow