wkhtmltopdf
A drop-in replacement for wkhtmltopdf that uses headless Google Chrome to generate PDFs. Accepts wkhtmltopdf-compatible CLI arguments and translates them into Chrome flags.
Python 3 stdlib only. Zero external dependencies.
Why
The original wkhtmltopdf is based on a deprecated Qt WebKit engine. This wrapper delegates to headless Chrome for superior PDF rendering while maintaining full CLI compatibility with existing tools like Odoo.
Requirements
- Python 3.6+
- Google Chrome or Chromium installed
See INSTALL-chrome-headless.md for Chrome installation on headless servers.
Installation
# Clone or copy the wkhtmltopdf directory
git clone https://git.preeper.org/ppreeper/wkhtmltopdf.git
# Make the binary available on PATH
sudo ln -s $(pwd)/wkhtmltopdf/wkhtmltopdf /usr/local/bin/wkhtmltopdf
Or simply copy the wkhtmltopdf directory to your desired location and ensure the wkhtmltopdf shell script is on your PATH.
Quick Start
wkhtmltopdf input.html output.pdf
wkhtmltopdf --page-size A4 --margin-top 20 input.html output.pdf
wkhtmltopdf --orientation landscape input.html output.pdf
Usage
wkhtmltopdf [OPTIONS] INPUT [INPUT ...] OUTPUT
Page/Layout
| Flag |
Description |
--page-size <size> |
A4, Letter, Legal, Tabloid, A3, A5, B4, B5 |
--page-width <mm> |
Custom page width in mm |
--page-height <mm> |
Custom page height in mm |
--orientation <orient> |
Portrait or Landscape |
--margin-top <mm> |
Top margin in mm |
--margin-bottom <mm> |
Bottom margin in mm |
--margin-left <mm> |
Left margin in mm |
--margin-right <mm> |
Right margin in mm |
Rendering
| Flag |
Description |
--dpi <dpi> |
Output DPI (default: 96) |
--zoom <factor> |
Zoom factor (e.g., 1.5) |
--disable-smart-shrinking |
Disable auto-fit-to-page |
--print-media-type |
Use print CSS media queries |
| Flag |
Description |
--header-html <file> |
HTML file for page header |
--footer-html <file> |
HTML file for page footer |
--header-spacing <mm> |
Space between header and content |
--header-line |
Draw line under header |
Cookies
| Flag |
Description |
--cookie-jar <file> |
Netscape cookie jar file |
Timing
| Flag |
Description |
--javascript-delay <ms> |
Wait time before printing (milliseconds) |
--timeout <sec> |
Max wait time for Chrome (seconds) |
File Access
| Flag |
Description |
--disable-local-file-access |
Block local file references |
--enable-local-file-access |
Allow local file references (default) |
Viewport
| Flag |
Description |
--viewport-size <WxH> |
Browser viewport size (e.g., 1920x1080) |
Chrome Control
| Flag |
Description |
--chrome-path <path> |
Path to Chrome binary |
--extra-chromium-args |
Additional Chrome flags |
Output
| Flag |
Description |
--quiet, -q |
Suppress non-error output |
--version |
Show version |
--help |
Show help |
Environment Variables
| Variable |
Description |
Default |
WKHTMLTOPDF_CHROME_PATH |
Override Chrome binary path |
Auto-detect |
WKHTMLTOPDF_TIMEOUT |
Default timeout in seconds |
60 |
WKHTMLTOPDF_STRICT |
Fail on unsupported flags |
false |
Config File
Optional JSON config at ~/.wkhtmltopdf.json:
{
"chrome_path": "/usr/bin/chromium",
"timeout": 120,
"default_paper_size": "A4",
"strict": false
}
Priority: CLI flag > env var > config file > hardcoded default.
Exit Codes
| Code |
Meaning |
| 0 |
Success |
| 1 |
PDF generated with warnings |
| 2 |
Memory error / Chrome crash |
| 3 |
Timeout |
| 4 |
Input file not found |
| 5 |
Output file error |
| 6 |
Chrome binary not found |
| 7 |
Invalid arguments |
Odoo Integration
Replace the wkhtmltopdf binary in your Odoo installation:
# Backup original
sudo mv /usr/bin/wkhtmltopdf /usr/bin/wkhtmltopdf.orig
# Install wrapper
sudo ln -s /path/to/wkhtmltopdf/wkhtmltopdf /usr/bin/wkhtmltopdf
# Verify
wkhtmltopdf --version
# Should output: wkhtmltopdf 0.12.6.1 (with patched qt)
No Odoo configuration changes needed. The wrapper is a drop-in replacement.
Running Tests
python3 -m unittest discover -s tests -v
License
See LICENSE.