FormatDrop
How-To Guide

How to Convert HTML to PDF

Converting HTML to PDF is essential for generating invoices, reports, certificates, and print-ready documents from web content. The key challenge is preserving layout, fonts, and images exactly as they appear in the browser. Modern headless browser tools like Puppeteer and Playwright produce pixel-perfect PDFs by actually rendering the page in Chromium.

Step-by-step instructions

  1. 1

    Browser Print to PDF (simplest — no tools needed)

    In Chrome: open the HTML file or URL → Ctrl+P (Windows) or Cmd+P (Mac) → set Destination to 'Save as PDF' → adjust margins, scale, and paper size → click Save. For headless browser consistency: File → Print → 'Open PDF in Preview' (Mac) or 'Microsoft Print to PDF' (Windows). This captures exactly what you see — fonts, CSS, background colors. Enable 'Background graphics' in More Settings to include CSS background colors.

    Go to converter
  2. 2

    Puppeteer (Node.js, programmatic PDF generation)

    Best for server-side generation: `npm install puppeteer`. Script: `const puppeteer = require('puppeteer'); const browser = await puppeteer.launch(); const page = await browser.newPage(); await page.goto('file:///path/to/file.html', {waitUntil: 'networkidle0'}); await page.pdf({path: 'output.pdf', format: 'A4', printBackground: true, margin: {top: '20mm', bottom: '20mm', left: '15mm', right: '15mm'}}); await browser.close();`. Puppeteer uses headless Chromium — identical rendering to Chrome.

  3. 3

    wkhtmltopdf (command line, fast and scriptable)

    Install: `sudo apt install wkhtmltopdf` (Ubuntu) or download from wkhtmltopdf.org (Windows/Mac). Convert a local file: `wkhtmltopdf input.html output.pdf`. Convert a URL: `wkhtmltopdf https://example.com output.pdf`. Options: `--page-size A4 --margin-top 20mm --margin-bottom 20mm --encoding utf-8`. Note: wkhtmltopdf uses an older Qt WebKit engine — it may not render modern CSS (CSS Grid, Flexbox) as accurately as Puppeteer.

  4. 4

    WeasyPrint (Python, CSS print specification-compliant)

    WeasyPrint implements the CSS Paged Media specification: `pip install weasyprint`. Convert: `weasyprint input.html output.pdf`. Via Python: `from weasyprint import HTML; HTML(filename='input.html').write_pdf('output.pdf')`. WeasyPrint understands @page CSS rules (size, margins, headers/footers) and handles @media print CSS correctly. It doesn't use a full browser engine — it's better than wkhtmltopdf for CSS3 but has some rendering differences from Chrome.

Why convert HTML to PDF?

HTML is live and interactive; PDF is frozen and portable. For invoices, certificates, reports, and archivable documents, PDF is the right output — and headless Chrome makes it pixel-perfect.

Your files never leave your device

FormatDrop runs the conversion engine entirely inside your browser using WebAssembly. No file upload. No server. Nothing stored. You can verify this by opening DevTools → Network tab and watching: zero upload requests.

Frequently asked questions

Why doesn't my HTML look the same in PDF as in the browser?
Common causes: (1) Fonts not embedded — the PDF tool uses a system font instead of the web font. Fix: serve fonts via CSS @font-face or ensure the tool can access Google Fonts CDN. (2) Background colors missing — most tools require explicit 'print background graphics' enabled. (3) CSS Media Queries not applied — some tools ignore @media print rules. (4) JavaScript not executed — wkhtmltopdf doesn't run JS; use Puppeteer with `waitUntil: 'networkidle0'` for JS-heavy pages.
How do I add headers and footers to the PDF?
Puppeteer: use the `headerTemplate` and `footerTemplate` options in page.pdf(). These accept HTML strings with special classes like `.pageNumber` and `.totalPages`. WeasyPrint: use CSS `@page { @top-center { content: 'My Header'; } @bottom-right { content: counter(page); } }`. wkhtmltopdf: `--header-html header.html --footer-html footer.html` (passing separate HTML files for header/footer).
Can I convert a website behind a login to PDF?
Yes, with Puppeteer: `await page.goto(loginUrl); await page.type('#username', 'user'); await page.type('#password', 'pass'); await page.click('button[type=submit]'); await page.waitForNavigation(); await page.goto(targetUrl); await page.pdf({path: 'output.pdf', printBackground: true});`. You can also set cookies directly: `await page.setCookie({name: 'session', value: 'token', domain: 'example.com'});` before navigation.
Convert HTML to PDF Now — Free

No account. No upload. Works in any browser.