how to create multi page pdf from html - ruby-on-rails

We need to print thousands of invoices that are in this format -
http://example.com/orders/n
where n = thousands of orders
Going through each order and then clicking on "print" is taking us a loooong time. Is there a way to create a multipage pdf from each of those URLs that we can download as one pdf so we can hit "print" once?

You could try a ruby script using the PDFkit gem (wraps wkhtmltopdf).
I would suggest splitting your pdf's into probably 50 to 100 pages each, don't like the thought of a 1000 page pdf in memory... probably fall over.
Example script, concats pages into one big html string with page break divs and saves to file:
require 'rubygems'
require 'open-uri'
require 'pdfkit'
PDFKit.configure do |config|
config.wkhtmltopdf = '/path/to/wkhtmltopdf'
end
invoice_numbers = (1..1000) #replace with actual numbers
html = ""
invoice_numbers.each do |n|
html << open("http://example.com/orders/#{n}").read + "<div style='page-break-before:always'></div>"
end
pdf = PDFKit.new(html, :page_size => 'Letter')
pdf.to_file('/path/to/invoices.pdf')

Consider to use wkhtmltopdf.
Its a very nice command line util that uses Webkit rendering engine to produce pdf pages.

For invoices I like to use htmldoc - it renders a little nicer than wkhtmltopdf, but the downside is that you can't use a stylesheet.
So for htmldoc you would probably have to re-code your invoice view to use a more tabular layout with inline styles.

Related

Convert html to pdf using prawn in ruby on rails

I am working on a Rails project and I need to convert the HTML page to a PDF page but it's writing HTML as it is on a pdf page. PDF page is not showing like a webpage. How can I generate a proper PDF from an HTML file?
Prawn::Document.generate("test.pdf") do
filepath = ${filepath}"file.html"
data = File.read(filepath);
text data
end
prawn is not really an HTML to PDF generator - see https://github.com/prawnpdf/prawn#should-you-use-prawn
You'll need to use another tool, for example wicked_pdf - see https://github.com/mileszs/wicked_pdf#super-advanced-usage
In your case, to quote from the README, you'll need something like
# create a pdf file from a html file without converting it to string
# Path must be absolute path
pdf = WickedPdf.new.pdf_from_html_file('/your/absolute/path/here')

Is it possible to have different stylesheets for the different locales that my site is translated (localized) to?

I'm in the process of abstracting the strings out of the views of my project. As I'm doing so I'm testing out what different languages look like.
In languages that are rendered in the Latin-style alphabet I want to have a style that prevents orphans (a single word on the last line of a wrapping string). And in some places I want to trigger wrapping so that things consistently appear on two lines or one line.
However, I'm pretty sure (not definitely sure since I don't speak chinese) that I don't want to wrap Chinese. Ideally, I'd even like to display the Chinese in right-to-left reading order.
Is it possible to have different display code for different languages (locales)?
Yes.
You can target elements per language with the :lang pseudo selector, there is also an experimental :dir selector but support is limited.
In Rails you could load an additional locale specific stylesheet like this:
# app/helpers/style_helper.rb
module StyleHelper
def locale_stylesheet_link_tag(locale = I18n.locale)
path = Rails.root.join('app', 'assets', 'stylesheets')
if Dir.glob(path + "#{locale}.{css, scss, sass, less}").any?
stylesheet_link_tag(locale.to_s)
end
end
end
# app/layouts/application.html.erb
<head>
...
<%= locale_stylesheet_link_tag %>
</head>
What this does is load en.css if the locale is en and an en.css file exists in app/assets/stylesheets.

How to save a full html page in Rails

I'm trying to save a webpage from my rails 4 application to disk, using
send_data(render_to_string, :filename => "foo.html").
The file is saved alright, but the css is missing.
I tried adding the type attribute, like so:
send_data(render_to_string, :filename => "foo.html", :type => "text/html")
but it didn't help.
How can I save the file with all the css (and other assets potentially), so that if I click on the saved file I'll see the same thing that I attempted to save?
render_to_string renders only the html part. That returns exact the same string like the browser receives when he loads a html page. Stylesheets and other assets will be loaded in additional requests. Therefore I only see one possible way: render_to_string a html layout with all assets inlined.
An other option might be to open the save as dialog with Javascript. But there seems no standardized way to do so.

Best pdf library for rails

I have a requirement to create pdfs with tables. I started it by using prawn. But it was too slow and kept utilizing 100% CPU. Now I moved to wicked_pdf.
This is much faster than prawn but still could be faster. One of my friend recommended TCPDF.
I found rfpdf gem which is TCPDF plugin for rails. Have anyone here used it before? How fast is it?
I also found fpdf. Are they better than wicked_pdf?
You can use 'wicked_pdf' gem. It provides very good support to generate pdf using html code.
https://github.com/mileszs/wicked_pdf
In controller:
def show
#report = Report.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.pdf do
render :pdf => "report",:template => "reports/show"
end
end
end
Create a show.pdf.erb and you can write simple html.
<%= wicked_pdf_stylesheet_link_tag "application" %>
<h1> Report </h1>
<p>
<%= #report.details %>
.................................
</p>
Try PdfKIT, it's awesome and very simple to use. Here is a screencast for it.
You don't state the format of your source material. If you are starting from simple text documents, HTML, or other simple markup formats, then you may wish to have a look at Pandoc. This tool will let you convert simple document types into a number of publication-type formats, including PDF.
Since you have a requirement to produce tables in your PDF files, one easy option would be to create your documents in Markdown format, which includes simple rules for creating tables. See this cheat sheet for an example.
Finally, here is a blog post I read recently that discusses converting Markdown documents to PDF files.
Since you are working with Rails there also exists a lightweight wrapper for Pandoc that might prove useful.
Have a look also on another gem: https://github.com/igorkasyanchuk/rails_pdf
It's using chrome headless to create PDF.

Strip Inline CSS and JavaScript in Rails

I'm working on a Rails application and I would like to know what's the best way to strip blocks of CSS or JavaScript.
<style>
...
</style>
-or-
<script>
...
</script>
I'm using the strip_tags helper to take care of most of the HTML, but it leaves a bunch of CSS when the content contains inline CSS. Thanks
Try to use Nokogiri library:
require 'nokogiri'
str = " ... " # some html from user
doc = Nokogiri::HTML(str)
doc.css("style,script").remove # remove all tags with content
new_string = doc.to_s
Nokogiri can much more, but this is what you asked for in questions :-)
The recommended way to do this is using the sanitize method. The strip_tags method is somewhat limited and less secure:
[strip_tags] Strips all HTML tags from the html,
including comments. This uses the
html-scanner tokenizer and so its HTML
parsing ability is limited by that of
html-scanner.
If you use sanitize, you will be much more secure, just come up with a white list of tags you intend to allow first.
If you need user-provided CSS for your application, you can try using http://github.com/courtenay/css_file_sanitize/tree/master as well.

Resources