Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

For a simple local HTML file, xhtml2pdf is the shortest Python route: read the file, pass its contents to pisa.CreatePDF(), and check the returned error status. Choose WeasyPrint when you need a richer document API or specialized PDF variants, and choose Playwright when the output must follow browser print behavior or depend on a browser page. None of the reviewed project documentation establishes a universal speed or fidelity winner, so test a representative document before committing to an engine.

Choose the renderer before writing code

HTML-to-PDF conversion is not one standardized rendering operation. Each engine supports a different subset of HTML and CSS and handles fonts, images, JavaScript, pagination and remote resources differently.

Engine Best fit Documented capabilities Important qualification
xhtml2pdf Compact scripts, batch jobs and a command-line workflow Pure-Python converter based on ReportLab, html5lib and pypdf; HTML5, CSS 2.1 and some CSS 3 It is not a full browser. Confirm that your CSS and layout are supported.
WeasyPrint Long-lived Python services and document-oriented output Python API, PDF bytes or files, rendered-page access, links, bookmarks, attachments and forms; documentation covers PDF/A, PDF/UA, PDF/X and Factur-X/ZUGFeRD use cases Conformance options do not prove conformance. Your markup and the finished file still need validation.
Playwright Browser-like printing, modern page behavior and pages that need a browser context page.pdf(), print or screen media, paper sizes, margins, headers and footers, backgrounds, scaling, tagged output and page ranges PDF generation uses print CSS by default and requires a browser page context.

The xhtml2pdf documentation appears under several release labels, including 0.2.17, 0.2.20 and 0.2.21. Check the version installed in your environment and use the matching documentation before relying on a version-specific option. WeasyPrint and Playwright documentation can also change.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Convert an existing file with xhtml2pdf

Install and run a minimal conversion

Install the package in the virtual environment used by your application:

#1 Best Overall
PDF Converter Ultimate - Convert PDF files into Word, Excel, PowerPoint and others - PDF converter software with OCR recognition compatible with Windows 11 / 10 / 8.1 / 8 / 7
  • Convert your PDF files into Word, Excel & Co. the easy way
  • Convert scanned documents thanks to our new 2022 OCR technology
  • Adjustable conversion settings
  • No subscription! Lifetime license!
  • Compatible with Windows 11, 10, 8.1, 7 - Internet connection required
python -m pip install xhtml2pdf

This script reads invoice.html, writes invoice.pdf, and fails loudly if the converter reports errors:

from pathlib import Path
from xhtml2pdf import pisa

source_path = Path("invoice.html")
output_path = Path("invoice.pdf")

html = source_path.read_text(encoding="utf-8")
with output_path.open("w+b") as output:
    status = pisa.CreatePDF(html, dest=output)

if status.err:
    raise RuntimeError("xhtml2pdf reported an error while creating the PDF")

print(f"Wrote {output_path}")

Use a complete document when possible. Declare the character set, include the CSS needed for print, and make image and stylesheet references resolvable from the file’s directory.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <style>
    @page { size: A4; margin: 18mm; }
    body { font-family: sans-serif; font-size: 11pt; }
    h1 { color: #163a63; }
  </style>
</head>
<body>
  <h1>Invoice</h1>
  <p>Content to be printed.</p>
</body>
</html>

Resolve relative assets

Relative URLs such as css/print.css, images/logo.png and local fonts depend on a base directory. When the source is supplied through a stream or standard input, use xhtml2pdf’s base-path support (the CLI calls this option --base) so links are resolved against the intended directory. The API distinguishes source data from the path used to resolve resources; do not assume the process’s current working directory is the HTML file’s directory.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use the command line for one-off jobs

xhtml2pdf invoice.html invoice.pdf

The CLI can read HTML from standard input. When doing so, provide --base for relative resources. Treat warnings about refused or missing resources as conversion defects: xhtml2pdf may continue and omit an image or stylesheet, producing a PDF that technically exists but is incomplete.

Rank #2
Doxillion Free Document Converter – Converts DOCX, DOC, PDF, WPS and Many More Files Quickly [Download]
  • Convert over 50 document file formats.
  • Preview your files from Doxillion before converting them.
  • Use batch conversion to convert thousands of files at once.
  • Enjoy an easy-to-use, intuitive interface with a Drag and Drop file option.
  • Burn your converted or original files directly to disc.

Use WeasyPrint for a document-focused Python API

Write a file or return PDF bytes

WeasyPrint accepts a filename, URL, readable file object or named HTML string. A basic file conversion is:

from weasyprint import HTML

HTML(filename="invoice.html").write_pdf("invoice.pdf")

Calling write_pdf() without a destination returns bytes, which is useful for an HTTP response or object-storage upload:

from weasyprint import HTML

pdf_bytes = HTML(filename="invoice.html").write_pdf()
with open("invoice.pdf", "wb") as file:
    file.write(pdf_bytes)

For repeated conversions, keep a long-lived process and reuse the application setup rather than starting a new Python process for every document; the project describes this as the preferred pattern for many documents.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Inspect pages and plan specialized output

HTML.render() returns a document object with page-level information for workflows that need to inspect or post-process pages. WeasyPrint documents hyperlinks, bookmarks, attachments and forms, as well as PDF/A, PDF/UA and PDF/X-related output variants. Selecting an option is not a compliance certificate: PDF/UA, for example, depends on semantic structure and reading order. Include a meaningful <title> and a lang attribute on <html>, then validate the resulting file with a conformance tool appropriate to your target.

Rank #3
PDF Extra 2024| Complete PDF Reader and Editor | Create, Edit, Convert, Combine, Comment, Fill & Sign PDFs | Lifetime License | 1 Windows PC | 1 User [PC Online code]
  • EDIT text, images & designs in PDF documents. ORGANIZE PDFs. Convert PDFs to Word, Excel & ePub.
  • READ and Comment PDFs – Intuitive reading modes & document commenting and mark up.
  • CREATE, COMBINE, SCAN and COMPRESS PDFs
  • FILL forms & Digitally Sign PDFs. PROTECT and Encrypt PDFs
  • LIFETIME License for 1 Windows PC or Laptop. 5GB MobiDrive Cloud Storage Included.

Use Playwright when browser printing is the requirement

Install Chromium and the Python package

python -m pip install playwright
python -m playwright install chromium

Convert a local file with print CSS

from pathlib import Path
from playwright.sync_api import sync_playwright

html_path = Path("invoice.html").resolve()
output_path = Path("invoice.pdf").resolve()

with sync_playwright() as playwright:
    browser = playwright.chromium.launch()
    page = browser.new_page()
    page.goto(html_path.as_uri(), wait_until="networkidle")
    page.pdf(
        path=str(output_path),
        format="A4",
        print_background=True,
        margin={"top": "18mm", "right": "18mm", "bottom": "18mm", "left": "18mm"},
    )
    browser.close()

page.pdf() uses the print media type by default. To print the screen stylesheet instead, call page.emulate_media(media="screen") before generating the PDF. The API also supports explicit paper formats, header and footer templates, scaling, page ranges and tagged output. Browsers modify colors for printing by default; use the CSS property -webkit-print-color-adjust when exact color reproduction is required and verify the result on your target browser version.

Wait for dynamic content deliberately

networkidle is useful for pages that load assets asynchronously, but it is not a guarantee that application rendering is finished. For a known widget, wait for its selector; for a fixed animation or chart, use a bounded delay. Avoid an unbounded wait that can make a worker hang when a third-party request never completes.

Make relative resources and untrusted input safe

Resource resolution is part of correctness

  • Use absolute, intentional base paths for local CSS, images and fonts.
  • Prefer packaging required assets with the job rather than depending on a developer machine’s working directory.
  • Record missing-resource warnings and inspect a sample PDF, not just the process exit code.
  • For remote assets, decide which hosts are allowed and what happens when a request times out.

Do not treat a converter as a security boundary

xhtml2pdf’s security guidance notes that a URI-rewriting link_callback is not authorization by itself. WeasyPrint warns that untrusted HTML and CSS can read files available to the process or trigger excessive work. For user-controlled documents, run conversion in a sandbox with a restricted user, minimal filesystem visibility, controlled or disabled network access, CPU and memory limits, and an execution timeout. Implement a custom URL-fetch policy that allows only the resource schemes and hosts your application needs. Never expose private service credentials through HTML, CSS or request headers.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Troubleshoot common failures

Symptom Likely cause Fix
PDF is created but images or CSS are missing Wrong base directory, blocked URL or a refused resource Resolve paths from the HTML file location, configure the documented base option or fetch policy, and review warnings.
Layout differs from the browser Engine support differs; xhtml2pdf and WeasyPrint are not Chromium Reduce unsupported CSS, add print-specific rules, or move the template to Playwright and compare a representative page.
Playwright output is unstyled Print media rules override screen styles Inspect @media print and call page.emulate_media(media="screen") when screen styling is intended.
Colors look washed out Browser print color adjustment Set -webkit-print-color-adjust: exact where appropriate and verify printer/PDF viewer behavior.
Fonts or non-ASCII text are wrong Font unavailable to the worker or encoding is unspecified Declare UTF-8, install/package the font, use a fallback family and test the deployed environment.
Conversion hangs or consumes excessive memory Unbounded external resources, hostile CSS or very large documents Sandbox the job, restrict fetches, impose time and memory limits, and split or reject oversized input.
PDF/A or PDF/UA validation fails Output mode alone cannot repair nonconforming content Fix metadata, semantics, reading order and other specification requirements, then run a validator.

Performance, reliability and operating cost

The available project documentation describes APIs and behavior, not neutral benchmarks. Measure your own templates for startup time, conversion time, peak memory, page count and failure rate. For batch work, a persistent WeasyPrint process can avoid repeated startup overhead; Playwright workers should reuse a browser where safe while isolating pages and recycling workers that grow unhealthy. Cache immutable inputs when your application can prove that a cached PDF is still valid, and log the engine version, template revision, asset failures and output size for reproducibility.

Rank #4
MobiPDF Lifetime - Professional PDF Editor for Windows | Edit, Sign & Convert PDFs | Best Adobe Acrobat Pro Alternative | Lifetime License
  • Edit PDFs with Ease. Modify text, images, and layouts directly within your PDF documents.
  • Convert & Organize. Export PDFs to Word, Excel, or ePub, and organize files with ease.
  • Read & Annotate. Enjoy intuitive reading modes and powerful tools to comment, highlight, and mark up PDFs.
  • Create & Manage PDFs. Create new PDFs, combine multiple files, scan documents, and compress for easy sharing.
  • Fill & Sign Forms. Complete forms and digitally sign documents with secure e-signature tools.

Choose the smallest engine that meets the document requirement. xhtml2pdf may simplify deployment for static, supported layouts; WeasyPrint offers document-oriented APIs and page access; Playwright adds browser behavior and therefore a browser installation and lifecycle to operate. Validate representative documents after dependency upgrades.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

If your goal is simply to obtain a clean PDF or screenshot from a URL rather than manage a local rendering stack, ScreenshotNeo provides a hosted website screenshot API and MCP server. Its PDF endpoint is a single GET request; the same service can render PNG, JPEG or WebP.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

Python:

import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)

Node.js:

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

See the ScreenshotNeo documentation for PDF parameters and response details. Before capture, it accepts cookie or consent banners and removes more than 60 known consent platforms, newsletter popups and chat widgets; each step can be disabled. Bot checks, blank pages, timeouts, failed loads and cache hits are not billed, and response headers identify the page verdict and whether it was billed. An MCP server exposes take_screenshot, get_page_info and capture_pdf to Claude, Cursor and other MCP clients. The Free plan includes 1,000 shots per month without a card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account to try it.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

FAQ

Can I convert HTML to PDF without opening a browser?

Yes. xhtml2pdf and WeasyPrint provide Python APIs that write PDF files or bytes without a browser. Use Playwright only when browser print behavior or browser-dependent page logic is part of the requirement.

Which library supports PDF/A or PDF/UA?

WeasyPrint documents PDF/A and PDF/UA output variants, but selecting one does not establish compliance. Check the markup requirements and validate the generated file.

Best Value
PDF Pro 3 - PDF editor to create, edit, convert and merge PDFs - 100% Compatible with Adobe Acrobat - for Windows 11, 10, 8.1, 7
  • ALL-IN-ONE SOLUTION – read, edit, convert, merge and protect your PDF files
  • MAXIMUM FUNCIONALITY – create interactive forms, compare PDFs, bates numbering, find and replace text or colors, convert documents, OCR engine, comment, highlight, fill out and print forms, document protection and others
  • EASY TO INSTALL AND USE – well-structured user-interface, in-program instructions, free tech support whenever you need it
  • GREAT VALUE FOR MONEY - why spend a fortune if you can have maximum functionality at a reasonable price - this also fits the requirements of companies very well

Why does a local image work in a browser but not in my PDF?

The converter is resolving the URL from a different base directory or refusing the resource. Set an explicit base path or URL-fetch policy and inspect conversion warnings.

Should I use a URL or inline HTML as the input?

Use a local filename or file URL when you control the document and its assets. Inline HTML is convenient for generated content, but you must still define how relative resources are resolved and what external access is permitted.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Frequently Asked Questions

Can I convert HTML to PDF without opening a browser?

Yes. xhtml2pdf and WeasyPrint provide Python APIs that write PDF files or bytes without a browser. Use Playwright only when browser print behavior or browser-dependent page logic is part of the requirement.

Which library supports PDF/A or PDF/UA?

WeasyPrint documents PDF/A and PDF/UA output variants, but selecting one does not establish compliance. Check the markup requirements and validate the generated file.

Why does a local image work in a browser but not in my PDF?

The converter is resolving the URL from a different base directory or refusing the resource. Set an explicit base path or URL-fetch policy and inspect conversion warnings.

The Bottom Line

Start with xhtml2pdf for a small, static file; use WeasyPrint for document APIs and specialized output; use Playwright when browser printing is the specification. Whichever route you select, control resource paths, sandbox untrusted input and validate real representative PDFs.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Quick Recap

Bestseller No. 1
PDF Converter Ultimate - Convert PDF files into Word, Excel, PowerPoint and others - PDF converter software with OCR recognition compatible with Windows 11 / 10 / 8.1 / 8 / 7
PDF Converter Ultimate - Convert PDF files into Word, Excel, PowerPoint and others - PDF converter software with OCR recognition compatible with Windows 11 / 10 / 8.1 / 8 / 7
Convert your PDF files into Word, Excel & Co. the easy way; Convert scanned documents thanks to our new 2022 OCR technology
$29.99
Bestseller No. 2
Doxillion Free Document Converter – Converts DOCX, DOC, PDF, WPS and Many More Files Quickly [Download]
Doxillion Free Document Converter – Converts DOCX, DOC, PDF, WPS and Many More Files Quickly [Download]
Convert over 50 document file formats.; Preview your files from Doxillion before converting them.
Bestseller No. 3
PDF Extra 2024| Complete PDF Reader and Editor | Create, Edit, Convert, Combine, Comment, Fill & Sign PDFs | Lifetime License | 1 Windows PC | 1 User [PC Online code]
PDF Extra 2024| Complete PDF Reader and Editor | Create, Edit, Convert, Combine, Comment, Fill & Sign PDFs | Lifetime License | 1 Windows PC | 1 User [PC Online code]
READ and Comment PDFs – Intuitive reading modes & document commenting and mark up.; CREATE, COMBINE, SCAN and COMPRESS PDFs
$99.99
Bestseller No. 4
MobiPDF Lifetime - Professional PDF Editor for Windows | Edit, Sign & Convert PDFs | Best Adobe Acrobat Pro Alternative | Lifetime License
MobiPDF Lifetime - Professional PDF Editor for Windows | Edit, Sign & Convert PDFs | Best Adobe Acrobat Pro Alternative | Lifetime License
Edit PDFs with Ease. Modify text, images, and layouts directly within your PDF documents.; Convert & Organize. Export PDFs to Word, Excel, or ePub, and organize files with ease.
$99.99
Bestseller No. 5
PDF Pro 3 - PDF editor to create, edit, convert and merge PDFs - 100% Compatible with Adobe Acrobat - for Windows 11, 10, 8.1, 7
PDF Pro 3 - PDF editor to create, edit, convert and merge PDFs - 100% Compatible with Adobe Acrobat - for Windows 11, 10, 8.1, 7
ALL-IN-ONE SOLUTION – read, edit, convert, merge and protect your PDF files
$29.99

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.