Wicked PDF is a popular tool for converting HTML to PDF in Ruby. You can stick to the familiar world of HTML to design your content and Wicked PDF provides a Ruby interface for the wkhtmltopdf
command line tool to render that content as a PDF. It's quick and easy. So why change?
wkhtmltopdf
uses Qt WebKit 4 which is deprecated and hasn't been updated since 2012. If you try to use modern JavaScript syntax that didn't exist in 2012 it can crash while rendering, leaving portions of your PDF incomplete. It also doesn't handle modern HTML and CSS.
In January 2023 the wkhtmltopdf
repository was archived. And the core contributor to the Wicked PDF gem now tries to steer people to alternatives:
No plans on sunsetting WickedPDF, or even stopping development, but I have started to try and steer people to alternatives, especially for those just starting out.
In addition to this, wkhtmltopdf
consumes a lot of memory. As your PDF content expands or your PDF volume increases, you may find that wkhtmltopdf
processes are crashing regularly because they've run out of memory. This alone may force you to seek out alternatives.
Why use a complicated HTML-to-PDF tool at all? Why not use a solution like Prawn?
Prawn doesn't use a browser engine at all so for simple text-based PDFs it is very fast and efficient. If you just need to print text on a page with relatively simple positioning, Prawn might be a great option. But if you need to do anything more complicated—even just presenting text in a table format—then things become more difficult.
If you need to render tables in your PDF, there are add-ons like prawn-table
to help out. But tables are surprisingly difficult to get right. Even with simple tables with 2 columns and a small amount of text, you can start to see problems where text wraps in the middle of words even when there should be plenty of width on the page to prevent this.
Also, if you need to provide a PDF download for an HTML page that uses a JavaScript library to present charts and graphs, this will be a hard problem in Prawn. You'd either need to find a way to execute JavaScript and export your graphs to images or find a way to recreate your entire JS graphing library in Prawn syntax.
Presenting content in tables and graphs is something that is easy to do with a browser engine. If you need to support these features, converting from Wicked PDF to a completely different HTML-to-PDF tool might end up being easier than trying to get these features to work in Prawn.
One alternative solution to Wicked PDF is Grover. Grover is a Ruby gem that uses Puppeteer to render PDFs in Chromium. Chromium is the browser engine used by Google Chrome and Microsoft Edge so it will likely be supported long into the future.
There is a Remote Chromium option which allow you to keep an external Chromium processing running at all times and Grover can send PDF-rendering requests to it. As each request is made, Chromium will spin up a new renderer process to render the HTML, similar to opening a new browser tab. Once it is done, this process will go away. This keeps memory consumption much lower than Wicked PDF.
The main area where Grover is more limited than Wicked PDF is in header and footer generation. If you have a complicated header/footer then Grover may not be able to handle it. In Wicked PDF, you are allowed to execute arbitrary JavaScript within the header and footer templates. In Grover, this isn't possible. There's an open question on StackOverflow without any good answers. And there are suggestions in GitHub comments on ways to force it using things like onload
attributes, but none of these worked for me so I think Chromium has made this more restrictive in recent years.
The header and footer are rendered together and use this template. This template is rendered in a different WebFrame than the body and has a larger scale. Images must be base64-encoded instead of using paths. Fonts in the header/footer must use a data URI and need to be used within the PDF body.
You may also notice that PDFs rendered by Grover are larger than Wicked PDF. This can be caused because Chromium uses PDF tagging by default. Depending on your content, this can cause files to be several MB larger than when they were rendering in Wicked PDF. If you don't need tagging, it can be disabled by passing tagged: false
into the Grover config options. This will produce files that are roughly the same size or smaller than what Wicked PDF generates.
wkhtmltopdf
wkhtmltopdf
, History, Repo