The best Java HTML-to-PDF approach depends on the HTML you have. Use Playwright with Chromium when the source is a modern webpage or JavaScript application; use OpenHTMLtoPDF for controlled, mostly static templates in a Java-only deployment; and use iText pdfHTML when you need iText’s PDF ecosystem, structured output, or a commercial support path. No library renders every browser feature identically, so select the engine before writing conversion code.
Choose the renderer first
HTML-to-PDF is not one standardized operation. A browser executes JavaScript, applies print styles, loads web fonts, and lays out CSS Grid or Flexbox. A Java PDF renderer generally parses a supported HTML/CSS subset without behaving like a browser.
| Approach | Rendering model | JavaScript | Deployment | Best fit | Main limitation |
|---|---|---|---|---|---|
| Playwright Java + Chromium | Browser engine | Yes | Java plus compatible Chromium binaries | Modern pages, authenticated routes, browser-faithful output | More CPU, memory, and operational lifecycle work |
| OpenHTMLtoPDF | Pure-Java XHTML/CSS renderer based on PDFBox | No | JVM process | Controlled invoices, reports, and templates | Not a full modern HTML5/CSS browser |
| iText pdfHTML | iText HTML/CSS conversion | Limited compared with a browser | JVM and iText dependencies | Structured PDFs, PDF/A or PDF/UA-oriented work, post-conversion PDF editing | AGPL or commercial licensing must be addressed |
| Flying Saucer | Legacy XHTML/CSS model | No | JVM | Existing legacy workflows | Modern HTML support is limited; Flying Saucer 9.5.0 requires Java 11 or later |
| wkhtmltopdf wrapper | External, older WebKit binary | Partial | Native binary management | Existing deployments that already depend on it | Older rendering model and additional process management |
For a page that already looks correct in Chrome, Playwright is usually the least surprising choice. For a deterministic template that you control, OpenHTMLtoPDF can avoid bundling a browser. For compliance or continued PDF manipulation, evaluate iText pdfHTML and its license terms.
Fastest modern route: Playwright Java
Playwright is a browser-automation library whose Chromium page API can create a PDF. The Playwright Java documentation showed version 1.61.0 on August 18, 2026; treat that as a dated example and verify the current version in the official documentation before pinning it.
#1 Best Overall
- PORTABLE SCANNER FOR USE ON-THE-GO — The fastest and lightest mobile single-sheet-fed compact document scanner in its class¹
- QUICK DOCUMENT SCANNING ― This Epson ultra-fast scanner scans a single page as quickly as 5.5 seconds²; Windows and Mac compatible
- VERSATILE PAPER HANDLING ― Portable scanner scans documents up to 8.5 x 72 in; Also easily digitizes receipts and ID cards to make accounting, bookkeeping, and organizing simpler
- INTUITIVE, HIGH-SPEED SOFTWARE — Epson ScanSmart Software³ is a smart tool allowing you to easily scan, review, and save; Stay organized easily with the help of this Epson scanner
- EASY SETUP — USB-powered connect to your computer for quick and simple scanning; No batteries or external power supply required to operate portable document scanner; Standard Connectivity: USB 2.0
1. Add the Maven dependency and browser
<dependency>
<groupId>com.microsoft.playwright</groupId>
<artifactId>playwright</artifactId>
<version>1.61.0</version>
</dependency>
Install the browser version compatible with that dependency:
mvn exec:java
-Dexec.mainClass=com.microsoft.playwright.CLI
-Dexec.args="install chromium"
On Linux, install system dependencies too:
mvn exec:java
-Dexec.mainClass=com.microsoft.playwright.CLI
-Dexec.args="install --with-deps chromium"
Playwright releases are tied to specific browser versions, so reinstall browser binaries when you upgrade Playwright. See the browser installation guide.
2. Convert a URL to an A4 PDF
import com.microsoft.playwright.*;
import java.nio.file.Paths;
public class HtmlUrlToPdf {
public static void main(String[] args) {
try (Playwright playwright = Playwright.create();
Browser browser = playwright.chromium().launch(
new BrowserType.LaunchOptions().setHeadless(true))) {
Page page = browser.newPage();
page.navigate("https://example.com");
page.pdf(new Page.PdfOptions()
.setPath(Paths.get("output.pdf"))
.setFormat("A4")
.setPrintBackground(true));
}
}
}
page.pdf() uses print media by default. To use screen styles instead:
page.emulateMedia(new Page.EmulateMediaOptions()
.setMedia(Media.SCREEN));
The default paper format is Letter unless you set a format, width, or height. Named formats include Letter, Legal, Tabloid, Ledger, and A0–A6. Unlabeled dimensions are pixels; explicit units include px, in, cm, and mm. Scaling must be between 0.1 and 2. The full option set is documented in the Page PDF API.
3. Convert an HTML string
import com.microsoft.playwright.*;
import java.nio.file.Paths;
public class HtmlStringToPdf {
public static void main(String[] args) {
String html = """
<!doctype html>
<html><head>
<meta charset="UTF-8">
<style>
@page { size: A4; margin: 20mm; }
body { font-family: Arial, sans-serif; }
</style>
</head><body>
<h1>Invoice</h1>
<p>Generated from HTML in Java.</p>
</body></html>
""";
try (Playwright playwright = Playwright.create();
Browser browser = playwright.chromium().launch()) {
Page page = browser.newPage();
page.setContent(html);
page.pdf(new Page.PdfOptions()
.setPath(Paths.get("output.pdf"))
.setFormat("A4")
.setPrintBackground(true)
.setPreferCSSPageSize(true));
}
}
}
setPreferCSSPageSize(true) gives the document’s @page size priority over PDF options such as format, width, or height.
Rank #2
- Scanner type: Document
- Connectivity technology: USB
- With Auto Scan Mode, the scanner automatically detects what you're scanning
- Digitize documents and images
4. Return PDF bytes from Spring
byte[] pdfBytes;
try (Playwright playwright = Playwright.create();
Browser browser = playwright.chromium().launch()) {
Page page = browser.newPage();
page.setContent(html);
pdfBytes = page.pdf(new Page.PdfOptions()
.setFormat("A4")
.setPrintBackground(true));
}
@GetMapping(value = "/report.pdf", produces = "application/pdf")
public ResponseEntity<byte[]> report() {
byte[] pdf = generatePdf();
return ResponseEntity.ok()
.header("Content-Disposition", "inline; filename="report.pdf"")
.body(pdf);
}
5. Wait for JavaScript-rendered content
Navigation completion does not guarantee that charts, API data, or images are ready. Wait for an application-specific marker:
page.navigate("https://example.com/report");
page.waitForSelector("#report-ready");
page.pdf(new Page.PdfOptions()
.setPath(Paths.get("report.pdf"))
.setPrintBackground(true));
Set navigation and operation timeouts, inspect console and network failures, and remember that headless Playwright does not support navigating directly to a PDF document.
Headers, footers, and page options
Playwright supports paper size, margins, landscape orientation, page ranges, background graphics, CSS page-size preference, scaling, and tagged PDF output through setTagged (documented as added in Playwright 1.42). Header and footer templates can use the injected classes date, title, url, pageNumber, and totalPages. Put styles inline: page styles are not visible inside these templates, and scripts in them are not evaluated.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
page.pdf(new Page.PdfOptions()
.setFormat("A4")
.setLandscape(true)
.setMargin(new Page.PdfMargins()
.setTop("18mm").setBottom("20mm")
.setLeft("15mm").setRight("15mm"))
.setDisplayHeaderFooter(true)
.setHeaderTemplate("<span style='font-size:9px'>Invoice</span>")
.setFooterTemplate("<span style='font-size:9px'>Page <span class='pageNumber'></span> of <span class='totalPages'></span></span>")
.setPrintBackground(true));
Production browser lifecycle
The try-with-resources example is suitable for a command-line utility. Do not launch a new Chromium process for every request in a busy service. Keep a deliberately managed browser, create isolated contexts and pages per job, cap concurrency, close contexts in a finally block, and monitor child processes. Playwright describes Browser.newPage() as a convenience API for short, single-page scenarios; production services should manage browser contexts and pages explicitly. See the Browser API guidance.
Pure-Java conversion with OpenHTMLtoPDF
OpenHTMLtoPDF is a JVM renderer based on Flying Saucer and PDFBox. Its documentation describes a reasonable subset of well-formed XML/XHTML and CSS 2.1, with selected HTML5, SVG, MathML, transforms, font fallback, PDF/A-related functions, and accessibility features. Those capabilities are not equivalent to browser compatibility: JavaScript, CSS Grid, complex Flexbox, and arbitrary modern web pages may fail.
Rank #3
- FAST SPEEDS - Scans color and black and white documents a blazing speed up to 16ppm (1). Color scanning won’t slow you down as the color scan speed is the same as the black and white scan speed.
- ULTRA COMPACT – At less than 1 foot in length and only about 1. 5lbs in weight you can fit this device virtually anywhere (a bag, a purse, even a pocket).
- READY WHENEVER YOU ARE – The DS-640 mobile scanner is powered via an included micro USB 3. 0 cable allowing you to use it even where there is no outlet available. Plug it into you PC or laptop and you are ready to scan.
- WORKS YOUR WAY – Use the Brother free iPrint&Scan desktop app for scanning to multiple “Scan-to” destinations like PC, Network, cloud services, Email and OCR. (2) Supports Windows, Mac and Linux and TWAIN/WIA for PC/ICA for Mac/SANE drivers. (3)
- OPTIMIZE IMAGES AND TEXT – Automatic color detection/adjustment, image rotation (PC only), bleed through prevention/background removal, text enhancement, color drop to enhance scans. Software suite includes document management and OCR software. (4)
Use the repository’s current Maven coordinates and version rather than copying an unverified version number.
import com.openhtmltopdf.pdfboxout.PdfRendererBuilder;
import java.io.FileOutputStream;
import java.io.OutputStream;
public class OpenHtmlToPdfExample {
public static void main(String[] args) throws Exception {
String html = """
<!doctype html>
<html><head><meta charset="UTF-8">
<style>@page { size: A4; margin: 20mm; }</style>
</head><body>
<h1>Report</h1><p>Generated with OpenHTMLtoPDF.</p>
</body></html>
""";
try (OutputStream output = new FileOutputStream("output.pdf")) {
PdfRendererBuilder builder = new PdfRendererBuilder();
builder.useFastMode();
builder.withHtmlContent(html,
"file:///absolute/path/to/resources/");
builder.toStream(output);
builder.run();
}
}
}
The second argument to withHtmlContent is the base URI. It lets images/logo.png, stylesheets, fonts, and other relative resources resolve correctly. Author well-formed markup, prefer predictable table layouts, and test floats near page boundaries. OpenHTMLtoPDF is LGPL-licensed; review the project license and all dependency licenses.
iText pdfHTML for structured or commercial workflows
iText’s pdfHTML add-on converts HTML and CSS through HtmlConverter. It accepts a string, file, or input stream and can write to a file, output stream, PdfWriter, or PdfDocument. iText positions pdfHTML for searchable, structured, tagged, PDF/A, and PDF/UA-oriented output, but a library capability does not by itself prove compliance for your document.
import com.itextpdf.html2pdf.HtmlConverter;
import java.io.FileOutputStream;
public class HtmlToPdf {
public static void main(String[] args) throws Exception {
String html = "<html><body><h1>Hello PDF</h1></body></html>";
HtmlConverter.convertToPdf(html,
new FileOutputStream("output.pdf"));
}
}
For a local file:
HtmlConverter.convertToPdf(
new java.io.File("input.html"),
new java.io.File("output.pdf"));
Resolve relative resources with a base URI
ConverterProperties properties = new ConverterProperties();
properties.setBaseUri("/absolute/path/to/document-directory");
try (FileInputStream input = new FileInputStream(
"/absolute/path/to/document-directory/input.html");
FileOutputStream output = new FileOutputStream("output.pdf")) {
HtmlConverter.convertToPdf(input, output, properties);
}
When converting an HTML string, the converter cannot infer the parent directory for img/logo.png or styles.css. Supply ConverterProperties.setBaseUri(), use reachable absolute URLs, or embed critical assets.
Add Java-generated content afterward
PdfWriter writer = new PdfWriter("output.pdf");
PdfDocument pdf = new PdfDocument(writer);
ConverterProperties properties = new ConverterProperties();
properties.setBaseUri("/absolute/path/to/document-directory");
try (FileInputStream input = new FileInputStream("input.html")) {
Document document = HtmlConverter.convertToDocument(input, pdf, properties);
document.add(new Paragraph("Additional content added from Java."));
document.close();
}
Use convertToDocument() when iText layout objects must be added after parsing. Do not copy old HTMLWorker or XML Worker tutorials for complete modern pages; iText identifies those approaches as obsolete for this use.
Rank #4
- FITS SMALL SPACES AND STAYS OUT OF THE WAY. Innovative space-saving design to free up desk space, even when it's being used
- SCAN DOCUMENTS, PHOTOS, CARDS, AND MORE. Handles most document types, including thick items and plastic cards. Exclusive QUICK MENU lets you quickly scan-drag-drop to your favorite computer apps
- GREAT IMAGES EVERY TIME, NO EXPERIENCE REQUIRED. A single touch starts fast, up to 30ppm duplex scanning with automatic de-skew, color optimization, and blank page removal for outstanding results without driver setup
- SCAN WHERE YOU WANT, WHEN YOU WANT. Connect with USB or Wi-Fi. Send to Mac, PC, mobile devices, and cloud services. Scan to Chromebook using the mobile app. Can be used without a computer
- PHOTO AND DOCUMENT ORGANIZATION MADE EFFORTLESS. ScanSnap Home all-in-one software brings together all your favorite functions. Easily manage, edit, and use scanned data from documents, receipts, business cards, photos, and more
Licensing is a design decision. iText’s installation guidance states that its open-source distribution is offered under AGPL for non-commercial use, while commercial closed-source use requires a commercial license. See the licensing documentation and the pdfHTML product page.
Print CSS that survives conversion
@page {
size: A4;
margin: 18mm 15mm 20mm;
}
@media print {
.screen-only { display: none; }
.avoid-break {
break-inside: avoid;
page-break-inside: avoid;
}
h2 {
break-after: avoid;
page-break-after: avoid;
}
.page-break {
break-before: page;
page-break-before: always;
}
}
body {
-webkit-print-color-adjust: exact;
}
With Playwright, setPrintBackground(true) enables background graphics; -webkit-print-color-adjust: exact controls color adjustment. They solve different problems. Repeating table headers, floats, and break behavior vary by renderer, so test realistic row counts rather than a three-row sample.
Troubleshooting by symptom
Images or CSS are missing
- Set a base URI in iText or OpenHTMLtoPDF.
- For Playwright, verify the URL, authentication cookies, and network requests from the server environment.
- Check file permissions, TLS trust, content-security policies, and outbound firewall rules.
- Download or embed critical assets when network availability is uncertain.
The PDF is blank or incomplete
- Wait for a readiness selector after navigation.
- Inspect browser console and failed network requests.
- For pure-Java renderers, validate markup and remove unsupported browser-only CSS.
- Do not navigate headless Playwright directly to a PDF URL.
Colors or fonts differ
- Remember that Playwright prints using print media unless you emulate screen media.
- Enable print backgrounds and use the print color-adjust property when appropriate.
- Bundle or install the exact fonts in containers and test CJK, Arabic, Hebrew, and Devanagari text.
- Check font redistribution licenses. OpenHTMLtoPDF documents font fallback but also limitations around OpenType and bidirectional text.
Page breaks split content
Use break-inside: avoid for cards and table rows where supported, keep headings with following content, and insert explicit page breaks only at known boundaries. Validate long paragraphs, long unbroken strings, empty values, landscape pages, and localized dates and numbers.
It works locally but fails in Docker
Install the matching Chromium binaries and Linux dependencies during image build, ensure fonts exist in the image, confirm outbound access and certificate trust, and log resource failures. Pin library and browser versions together.
Timeouts, memory growth, or leaked processes
Set navigation and conversion timeouts, limit concurrent jobs, reuse a managed browser instead of launching one per request, close pages and contexts on every path, and avoid oversized inline images. Monitor browser child processes and impose document-size limits.
Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallBest Value
- OUR MOST ADVANCED SCANSNAP. Large touchscreen, fast 45ppm double-sided scanning, 100-sheet document feeder, Wi-Fi and USB connectivity, automatic optimizations, and support for cloud services. Upgraded replacement for the discontinued iX1600
- CUSTOMIZABLE. SHARABLE. Select personalized profiles from the touchscreen. Send to PC, Mac, mobile devices, and clouds. QUICK MENU lets you quickly scan-drag-drop to your favorite computer apps
- STABLE WIRELESS OR USB CONNECTION. Built-in Wi-Fi 6 for the fastest and most secure scanning. Connect to smart devices or cloud services without a computer. USB-C connection also available
- PHOTO AND DOCUMENT ORGANIZATION MADE EFFORTLESS. Easily manage, edit, and use scanned data from documents, receipts, photos, and business cards. Automatically optimize, name, and sort files
- AVOIDS PAPER JAMS AND DAMAGE. Features a brake roller system to feed paper smoothly, a multi-feed sensor that detects pages stuck together, and skew detection to prevent paper damage and data loss
Security and reliability checklist
- Treat user-supplied HTML and URLs as untrusted.
- Prevent server-side request forgery by restricting navigation and resource destinations; do not let conversion reach internal services.
- Sanitize markup, restrict filesystem access, and run browser processes with least privilege.
- Pin compatible Java, library, browser, and font versions.
- Compare representative PDFs in CI, including multi-page tables, missing assets, international text, headers, footers, and large data sets.
- Validate accessibility or PDF/A claims with a document-specific validator.
- Review AGPL, LGPL, commercial, font, and transitive dependency licenses before shipping.
Or skip the browser setup
If the input is a public URL and you do not want to package Chromium, ScreenshotNeo can return a PDF or image from one GET request. It accepts cookie and consent banners like a visitor, removes more than 60 known consent platforms plus newsletter popups and chat widgets before capture, and bills only clean shots: bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing. Responses identify the result with X-Page-Verdict and X-Billed headers.
Use the ScreenshotNeo API documentation for authentication and options. A minimal call is:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Equivalent Java-side integrations can call the endpoint with an HTTP client. Python and Node.js examples are useful for mixed-language pipelines:
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)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
ScreenshotNeo also provides an MCP server with take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. The Free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots. Sign up free.
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →Which option should you ship?
- Modern, JavaScript-driven page: Playwright with a pinned Chromium version.
- Static controlled template and Java-only runtime: OpenHTMLtoPDF, authored to its supported XHTML/CSS subset.
- Structured PDFs, iText integration, compliance work, or vendor support: iText pdfHTML after a license review.
- Public URL capture without browser operations in your service: ScreenshotNeo as the hosted alternative.
Frequently Asked Questions
Can Java convert an HTML file directly to PDF?
Yes. Playwright can load a file through a browser page, iText pdfHTML accepts a File, and OpenHTMLtoPDF accepts HTML content with a base URI. Choose the renderer according to the file’s JavaScript and CSS requirements.
Why does my HTML-to-PDF output not match Chrome?
The renderer, browser version, fonts, print versus screen media, asset timing, and PDF options can all differ. Use Playwright for closer browser behavior and test with the same fonts and print CSS used in production.
Is iText pdfHTML free for a commercial application?
iText’s open-source distribution is offered under AGPL for non-commercial use; commercial closed-source use requires a commercial license according to iText’s installation guidance.
Does OpenHTMLtoPDF execute JavaScript?
No. It is a Java HTML/CSS renderer, not a browser. JavaScript-generated content must be rendered before conversion or handled with a browser engine such as Playwright.
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Scan for outdated or missing drivers - takes under a minute3Clear out junk files and repair common Windows errorsQuick Recap
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.

