HTML to PDF in Java, beyond CSS 2.1
The classic Java answers — Flying Saucer, openhtmltopdf — render a CSS 2.1-era subset, so CSS Grid and Flexbox layouts silently break. iText pdfHTML handles more but brings AGPL licensing into a commercial codebase. pdfkitt moves rendering to a managed Chromium pool: your service makes one HTTP call with the standard java.net.http client and ships no rendering engine.
One HttpClient call, Java 11+
No Maven rendering dependency, no font registration, no XHTML cleanup. Send HTML, stream the PDF to a file.
var client = HttpClient.newHttpClient();
var body = """
{ "html": "<h1>Invoice</h1>",
"options": { "page_size": "A4" } }
""";
var request = HttpRequest.newBuilder()
.uri(URI.create("https://api.pdfkitt.dev/v1/convert"))
.header("Authorization", "Bearer " + System.getenv("PDFKITT_API_KEY"))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(body))
.build();
var response = client.send(request,
HttpResponse.BodyHandlers.ofFile(Path.of("invoice.pdf")));Spring Boot: reuse the template you have
Render your Thymeleaf view to a String and POST it — the invoice your app serves in the browser is the invoice the PDF shows.
// Spring Boot: render your existing Thymeleaf template to a
// String first, then POST it — no template changes needed.
String html = templateEngine.process("invoices/show",
new Context(Locale.US, Map.of("invoice", invoice)));When a local library still makes sense
For manipulating existing PDFs — merging, signing, PDF/A archival output — Apache PDFBox and iText are the right tools. Air-gapped deployments rule out any API. For generating documents from modern HTML in a connected service, the API path removes the CSS ceiling and the licensing question. Compare with the self-hosted Gotenberg route if you would rather run your own container, or jump to the API docs.
FAQ
Why not Flying Saucer or openhtmltopdf?
Both are capable libraries, but both render a CSS 2.1-era subset: no CSS Grid, no Flexbox, and strict XHTML input requirements. Real-world invoice and report markup built with modern CSS either fails to parse or comes out wrong. pdfkitt renders with current Chromium, so the PDF matches what the browser shows.
What about iText pdfHTML?
iText renders more of modern CSS, but it is AGPL-licensed - using it in a closed-source product requires a commercial license. If your only need is HTML to PDF, a metered API avoids both the license question and the engine maintenance.
Does this work with Spring Boot and Thymeleaf?
Yes. Render the Thymeleaf (or Freemarker/JSP) template to a String server-side and POST it. The template you already serve as a web page becomes the PDF, including CSS Grid, Flexbox, web fonts, and print CSS.
How does it handle Unicode - Arabic, Hindi, CJK?
The render containers ship the full Noto font family including Noto CJK, and Chromium implements the Unicode bidirectional algorithm and complex script shaping. This is a common failure point in Flying Saucer and openhtmltopdf unless you embed and register fonts manually.
Does it execute JavaScript in my HTML?
Not by default. Static HTML and CSS render as-is. If your page needs its scripts to run, set javascript: true in the request and the page runs in sandboxed Chromium before capture, with a 30-second cap per render.
Is my HTML stored anywhere?
No. HTML is processed in memory to render the PDF and is never written to storage or logs. Only request metadata such as timing and status is recorded.
Try pdfkitt free — 1,000 PDFs/month, no credit card
Get an API key and send your first PDF in minutes.