Converting HTML to PDF on the command line

I recently needed to convert some HTML to PDF on the command line and went hunting down the options.

There numerous posts saying “X is great” “Y works great for me” but no-one gives examples that show you anything.

I’ve tried WeasyPrint, wkhtmltopdf, Pandoc and Google Chrome (yes via the command line). The test was simple. Take a simple color chart, made from pre-formatted text and render it as a pdf. This doesn’t test any fancy CSS grid layout, or sizing or … anything. Just straight pre-formatted text with some spans that only define colors.

Here is the original html and here’s what the conversions looked like.

3 pdfs from the same HTML

The version rendered from Chrome is perfect. I have zero complaints.

The version from WeasyPrint is cut off on the right edge. Note that it is not the window that’s cutting it off. That’s the edge of the PDF itself.

The wkhtmltopdf is perfect if you zoom waaaaaay into it. Realistically though it’s unusable crap because it’s so small. Note that it has also added a border

Pandoc (not included in the screenshot above) seems to be really focused on text. The result was completely devoid of color, used a different font, and was centered in the page. It did maintain the formatting within the table though.

The winner, for me, is clearly Chrome. The magic incantation is as follows. Save it in a file called html_to_pdf and then you can convert your html with

html_to_pdf path/to/my/html_file.html

It will generate an output.pdf file in the current directory.

#!/bin/sh

# on linux everything before --headless can be replaced with just
# chrome
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome \
  --headless \
  --disable-gpu \
  --no-margins \
  --print-to-pdf $1

This all came about because I’d recently written oho (an app for converting your colorful terminal output to HTML), and I wanted to convert that HTML to PDF to more easily share with my coworkers over Slack. Oho is perfect for sharing terminal output on a blog though. ;)