Skip to content

Java PDF library

Java PDF Library: PDF Generation and HTML to PDF in Java

Six real ways to produce a PDF from Java, and the catch attached to each. Apache PDFBox is Apache 2.0 and reads no HTML at all. OpenPDF is the LGPL descendant of the last iText release before the license changed. Flying Saucer and Open HTML to PDF render real CSS, but stop at CSS 2.1 and run no JavaScript. Here is which one fits your document, what each license actually permits in a closed source product, and when a rendering API is the cheaper answer. Try it on any URL below.

  • Early access, launching soon
  • No card required
  • Your HTML stays yours

Live demo

Runs in your browser. Nothing is uploaded.

Your PDF is downloading. Want this as one API call, with the page archived too?

Short answer

Choosing a Java PDF library comes down to two questions: does the document start as data or as HTML, and can you live with the license? For documents built from data, Apache PDFBox is the safest choice, because it is Apache License 2.0, the only permissive license in this comparison, with no revenue ceiling and no disclosure obligation. It has no HTML parser and no CSS engine. For documents that start as HTML, the pure Java engines are OpenPDF, whose openpdf-html module generates PDFs from HTML and CSS, and Flying Saucer and Open HTML to PDF, which render XHTML with CSS 2.1. All three are LGPL, and none of them runs JavaScript or implements flexbox and grid. iText 8 with the pdfHTML add-on is the most capable engine, but iText is dual licensed AGPL and commercial, and the AGPL requires you to publish your own application source. If your template needs a real browser, you either drive Playwright for Java yourself or call a hosted rendering API, which gives you the same Chromium output as one HTTPS call with no engine to license or host. Every license term and version on this page was read from the project own repository on 11 August 2026.

Last updated 2 September 2026. Written and fact checked by the Sitepdf team.

Every Java PDF library, what it renders and what its license permits

The Java PDF ecosystem has an unusually wide license spread, from Apache 2.0 at one end to AGPL at the other, and that spread decides more projects than any feature does. This table puts rendering ability and license side by side. Every entry was read from the project own repository on 11 August 2026.

Library or approach Accepts HTML and CSS Runs JavaScript License What it means for a closed source commercial app
Apache PDFBox No, you draw or compose the document Not applicable Apache License 2.0 Free with no conditions, no revenue ceiling and no disclosure obligation
OpenPDF Yes, through the openpdf-html module No LGPL 2.1 or MPL 2.0, your choice Free to use as an unmodified library; changes to the library itself must be shared
Flying Saucer Yes, XHTML with CSS 2.1 No LGPL 2.1 or later Free to use as an unmodified library; no obligation to publish your own code
Open HTML to PDF Yes, XHTML and some HTML5, CSS 2.1 No, stated explicitly LGPL 2.1 or 3.0 Free to use as an unmodified library; no obligation to publish your own code
iText 8 with pdfHTML Yes, the most complete of the pure Java engines No AGPL v3 or commercial AGPL requires publishing your own application source; commercial pricing is quote only
Playwright for Java or Selenium Yes, real Chromium Yes Open source wrapper Free to license, you pay in servers, memory and browser operations
Hosted rendering API
Sitepdf
Yes, managed Chromium Yes Subscription Planned from 29 USD a month, nothing to install, license or host

The honest split: if you are assembling a document out of database rows and you want the least legal friction of anything on this page, Apache PDFBox is Apache 2.0 and you can stop reading here. Use it. The LGPL engines are genuinely free for normal use too, and the distinction people miss is that the LGPL obligation attaches to changes you make to the library, not to the application that calls it. You only need a browser engine when your template uses modern CSS or JavaScript, and at that point the only question left is who runs the browser.

Apache PDFBox: the most permissive license in Java, and no HTML at all

Apache PDFBox is the library most Java developers reach for first, and for documents built from data it deserves that position. The project README describes it plainly: "The Apache PDFBox library is an open source Java tool for working with PDF documents. This project allows creation of new PDF documents, manipulation of existing documents and the ability to extract content from documents." It is published under the Apache License, Version 2.0.

That license is the quiet reason PDFBox wins so many enterprise reviews. Apache 2.0 has no revenue threshold, no headcount test, no disclosure requirement and an explicit patent grant. You can ship it inside a closed source commercial product, at any scale, and owe nothing to anybody. Nothing else in this comparison is that unconditional.

try (PDDocument doc = new PDDocument()) {
    PDPage page = new PDPage(PDRectangle.LETTER);
    doc.addPage(page);

    try (PDPageContentStream cs = new PDPageContentStream(doc, page)) {
        cs.beginText();
        cs.setFont(new PDType1Font(Standard14Fonts.FontName.HELVETICA_BOLD), 20);
        cs.newLineAtOffset(72, 700);
        cs.showText("Invoice 8842");
        cs.endText();
    }

    doc.save("invoice-8842.pdf");
}

Now the limitation that sends most people here in the first place. There is no HTML parser in PDFBox, no CSS engine, and the README does not claim one. You position text, lines and images on the page yourself in points, and you handle pagination, text measurement and line wrapping by hand. Producing a simple receipt is a pleasant afternoon. Producing a multi page invoice with a table that breaks correctly across pages is a project, and you will end up writing a layout engine badly.

PDFBox is also the standard Java answer for the reverse direction, pulling text and content back out of PDFs you receive. That is a different job from generating them, and it is worth being clear which one you are actually doing before you pick a library. The Apache PDFBox and HTML to PDF guide covers that mismatch in detail, because searching for PDFBox HTML conversion is one of the most common wrong turns in Java PDF work.

OpenPDF: the LGPL descendant of iText 4, and it does convert HTML

OpenPDF exists because of a licensing event. Its README states that it is "the LGPL/MPL open source successor of iText, and is based on some forks of iText 4 svn tag". The fork point is the whole story: iText 4.2.0 was published with LGPL and MPL headers, and iText 5.0 switched to AGPL. OpenPDF picked up the last permissively licensed code and carried it forward. If you have ever read a Stack Overflow answer from 2011 that says iText is free, OpenPDF is where that code actually lives now.

It is not a museum piece. The README describes it as "an open-source Java library for creating, editing, rendering, and encrypting PDF documents, as well as generating PDFs from HTML", and the current release is 3.0.5, which requires Java 21 or later and moved to the org.openpdf package name. That package rename matters if you are upgrading from an older version, because the imports change.

HTML conversion lives in a separate openpdf-html module, which the project describes as generating PDFs directly from HTML and CSS content, aimed at styled reports, invoices and documents built from web templates. That is exactly the job most people arrive with, and it is the reason OpenPDF is worth a look before you go anywhere near AGPL code.

The license question people get wrong: the LGPL is not the AGPL and it is not the GPL. The obligation attaches to the library. If you use OpenPDF as a dependency without modifying it, you can link it into a closed source commercial application and you are not required to publish any of your own code. If you patch OpenPDF itself, those changes have to be available under the same terms. For the overwhelming majority of teams that means OpenPDF is free to use in a commercial product, full stop. You choose either LGPL 2.1 or MPL 2.0, whichever your legal team prefers.

Flying Saucer and Open HTML to PDF: real CSS, stopping at CSS 2.1

These two are the pure Java rendering engines, and they share an ancestor. Flying Saucer describes itself as "a pure-Java library for rendering arbitrary well-formed XML (or XHTML) using CSS 2.1 for layout and formatting, output to Swing panels, PDF, and images". It is LGPL 2.1 or later, actively maintained, and version 10.0.0 requires Java 21 or later. Open HTML to PDF is the modernized descendant, handling XHTML and some HTML5, also on CSS 2.1, LGPL, and running on Java 8 and up.

Both produce genuine vector PDFs with selectable text, no browser process, no native dependencies and no cold start. On a Spring Boot service that renders invoices from a template you control, that is a very good deal, and the memory profile is a fraction of anything Chromium based.

The constraint is stated more bluntly by the Open HTML to PDF README than by any vendor comparison you will read: "it's not a web browser. Specifically, it does not run javascript or implement many modern standards such as flex and grid layout." Take that sentence literally, because it eliminates a large share of real templates. A layout built with display: flex or CSS grid will not lay out. A chart drawn by Chart.js or Recharts after page load will render as an empty container, because nothing ever executes the script that draws it. A component library that assumes modern CSS will fall apart in ways that are tedious to diagnose.

The workable pattern is to treat these engines as a separate rendering target rather than a way to reuse your existing front end. You write a dedicated print template in old fashioned CSS, with tables and floats for layout, absolute units, and every value already resolved on the server before rendering starts. Teams that do that are happy for years. Teams that try to point these engines at the marketing page they already have give up in a week and move to a browser.

iText 8 and pdfHTML: the most capable engine, and the AGPL clause

iText is the oldest and most complete PDF toolkit in Java, and with the pdfHTML add-on, described in the repository as converting XML, HTML and CSS to PDF, it handles markup that the LGPL engines choke on. The current line is iText Core 8. If capability were the only axis, this section would be short.

The iText for Java repository states that "iText is dual licensed as AGPL/Commercial software", and that the AGPL is a copyleft license under which any derivative work must be licensed on the same terms. iText own licensing pages put the practical consequence more directly: you may not deploy it on a network without disclosing the full source code of your own applications under the AGPL, and you must distribute all source code, including your own product and web based applications.

The network clause is what catches people. Unlike the GPL, the AGPL is triggered by users interacting with your software over a network, so an internal Spring Boot service that generates statements for customers can fall inside it even though you never ship a jar to anyone. Read against a normal commercial SaaS product, the conclusion is uncomfortable: if you generate PDFs with iText under the AGPL and you do not publish your source, you are out of compliance. The legitimate route is a commercial license, which iText sells as an OEM distribution license or a volume based subscription. Neither has a published price, so you cannot budget for iText without a sales conversation.

This is the same licensing story that plays out in .NET, because it is the same product and the same clause. The breakdown of what iText and its competitors actually cost works through the AGPL terms and the commercial alternatives in detail, and the analysis is stack agnostic even though the examples are in C#. If your only reason for considering iText is HTML conversion, try OpenPDF first: it costs nothing, asks nothing of your source code, and covers a large share of report and invoice templates.

The other commercial option on the JVM is Aspose.PDF for Java, which unlike iText publishes its whole rate card. The Java and .NET price lists are identical, and the tiers are scoped by how many developers work on the project and how many buildings they sit in, which is the arithmetic that decides your cost rather than your document count. We broke down every tier on our Aspose PDF pricing page.

Re-checked 2 September 2026. Nothing has moved. iText still publishes no commercial figure of any kind: the two paid routes are an OEM Distribution License, where "Pricing for this license is customized and is calculated depending on your specific use case", and a Subscription Volume License priced "based upon the quantity of PDF files you process". The AGPL route still carries the same condition that rules it out for most commercial products, "Disclosure of full source code of application needed, (including your own application)". OpenPDF was re-checked the same day and remains dual licensed, "you may choose either Mozilla Public License Version 2.0 or GNU Lesser General Public License 2.1", now at version 3.0.5.

When the PDF has to match a real browser: Playwright for Java

If your template genuinely needs modern CSS or JavaScript, no pure Java engine will save you, and the honest move is to stop trying. Playwright for Java drives real Chromium and produces exactly what the browser print pipeline produces, because that is literally the call it makes.

try (Playwright playwright = Playwright.create()) {
    Browser browser = playwright.chromium().launch();
    Page page = browser.newPage();

    page.navigate("https://app.example.com/invoices/8842",
        new Page.NavigateOptions().setWaitUntil(WaitUntilState.NETWORKIDLE));

    page.pdf(new Page.PdfOptions()
        .setPath(Paths.get("invoice-8842.pdf"))
        .setFormat("Letter")
        .setPrintBackground(true));
}

Two settings matter more than the rest. setPrintBackground(true) is off by default, and it is the single most common reason a finished invoice arrives with white boxes where the branded header should be. And waiting for network idle, or better for a specific selector that only exists once your data has rendered, is what stops you capturing a page before its content arrived.

The license is free. The operating cost is not. You now own a browser: system dependencies in your Docker image, Chromium version upgrades for security, a concurrency cap so a burst of report requests does not exhaust the heap and the container together, disposal of pages and contexts so handles do not leak, and a cold start every time a fresh instance launches its first browser. On AWS Lambda this runs into hard platform limits. The published quotas are 50 MB for a zipped deployment package and 250 MB unzipped including layers, and a full Chromium does not fit, so you end up on container images or a stripped build. None of that is unsolvable. It is simply infrastructure work that no library comparison shows you, and on a small team it usually costs more per year than the license you were avoiding.

Spring Boot: generating the PDF inside the request is the mistake

Whichever library you land on, the same architectural error shows up in nearly every first implementation: rendering the document inside the HTTP request that asked for it. A Chromium render of a real invoice takes roughly one to three seconds. Tomcat handles that fine at low volume, but under load those threads are occupied and your API latency starts tracking your PDF engine instead of your application.

The pattern that holds up is the same in every stack. Accept the request, queue the job, return a 202 with a location the client can poll or a webhook you will call, and generate the document on a worker. In Spring that is a @Async method with a bounded executor for small workloads, or Spring Batch, or a proper queue with a separate worker service for anything serious. This matters more with an in process engine than with an API, because an in process Chromium competes with your web application for the same heap on the same machine, and a memory spike during a large report takes the whole service down rather than just failing the report.

Decide early where the finished file lives, too. Writing PDFs to the local disk of a container works right up until you scale to two instances and half your download links start returning 404 because the file is on the other machine. Object storage from the start, with the document id in your database rather than a file path, saves a painful migration later. The HTML to PDF in Spring Boot page covers the framework wiring for this in detail, including the controller and worker split, while this page is about which library sits underneath it. Bulk HTML to PDF covers what changes again when you are rendering thousands of documents in a batch.

The API path: Chromium fidelity, no license to read and no browser to run

A hosted rendering API runs managed Chromium on someone else infrastructure. From Java it is an ordinary HttpClient call, so there is no Maven dependency with a license attached, no engine in your deployment artifact, no browser pool to tune, no cold start, and no Lambda package limit to work around. It behaves identically from a Spring Boot service, a container, a Lambda or a developer laptop, because from your application it is just an outbound HTTPS request.

Send a url and Chromium loads the page the way a signed in visitor would, JavaScript included, so a dashboard drawn by a charting library renders as a chart rather than an empty container. Send an html string instead when your Thymeleaf or Freemarker template is rendered in memory and never served at a public address. The output is true vector text, so it stays selectable, searchable and accessible rather than being a picture of a document.

The archive flag is the part no Maven artifact offers. It stores a timestamped snapshot of exactly what Chromium rendered, retrievable later by id, so eighteen months on you can show precisely what a given statement looked like at the moment you produced it. For finance, insurance, healthcare and anything with a records retention requirement, that dated record is usually the reason to render through an API rather than in process. See the PDF generator API page for the full call surface, website archiving for how the record works, and PDF API pricing for what every vendor in this category charges per 1,000 documents. If you are weighing a licensed library instead, our PDF SDK pricing and licensing comparison shows which vendors publish a rate card and which quote only.

The honest limit: an API is a network call, so it adds latency an in process library does not have, it needs outbound network access, and it will not work in an air gapped environment. If you generate forty invoices a month from data you already hold, PDFBox will beat this on every axis and costs nothing under any license. The case for an API strengthens with HTML source documents, with modern CSS, with volume, with serverless hosting, and with any requirement to prove what you rendered.

Choosing, in one pass

Work down this list and stop at the first line that matches you.

  • Your document is built from data and you want the least legal friction available. Apache PDFBox. Apache 2.0, no conditions of any kind, and it will outlive every other option here.
  • Your document is already HTML and the template is yours to write. OpenPDF with its openpdf-html module, or Open HTML to PDF. Both are LGPL, both are free in a commercial product, and both need a print specific template in CSS 2.1.
  • Your template uses flexbox, grid or JavaScript. No pure Java engine will render it. Go to a browser, either Playwright for Java or a rendering API, and stop trying to make CSS 2.1 do it.
  • You need the most complete pure Java engine and you can publish your application source. iText 8 with pdfHTML under the AGPL is a legitimate free option. Almost nobody shipping commercial software can accept that clause, so read it properly before assuming you can.
  • You want Chromium fidelity for free and you have infrastructure people. Playwright for Java. Set setPrintBackground(true), cap concurrency, and budget for the container work.
  • You want Chromium output without a license question, a browser or a deployment problem, or you need a dated record of what you produced. Use a rendering API.

If you are working in a specific framework rather than plain Java, the Spring Boot HTML to PDF page covers the controller and worker wiring, and the same decision in other stacks is laid out on C# PDF library, Python PDF generation and HTML to PDF in Node.js. For the head to head against the hosted tools people shortlist alongside these, see the best HTML to PDF API comparison.

From Java: render a URL or a Thymeleaf template in managed Chromium with no engine to license, and keep a dated copy of exactly what was produced.
HttpRequest req = HttpRequest.newBuilder()
    .uri(URI.create("https://api.sitepdf.com/v1/render"))
    .header("Authorization", "Bearer " + System.getenv("SITEPDF_KEY"))
    .header("Content-Type", "application/json")
    .POST(HttpRequest.BodyPublishers.ofString("""
        {
          "url": "https://app.example.com/invoices/8842",
          "format": "Letter",
          "margin": "normal",
          "archive": true
        }"""))
    .build();

HttpResponse<String> res = http.send(req, BodyHandlers.ofString());

{
  "pdf_url": "https://api.sitepdf.com/v1/documents/doc_7m2vc.pdf",
  "pages": 3,
  "rendered_in_ms": 1780,
  "archive": {
    "id": "arc_q47ne",
    "captured_at": "2026-08-11T09:14:22Z",
    "retrieve_url": "https://api.sitepdf.com/v1/archives/arc_q47ne"
  }
}

The API is in early access; this is the documented call shape it opens with. Full request and response walkthrough.

Questions about this job

What is the best Java PDF library?
There is no single best one, because they solve different problems. Apache PDFBox is the best choice for documents built from data, and its Apache 2.0 license is the most permissive here. OpenPDF and Open HTML to PDF are the best free options when your document starts as HTML. iText 8 is the most capable engine but is AGPL unless you buy a commercial license.
How do I create a PDF in Java?
Pick by where the document starts. If it starts as data, add Apache PDFBox and compose the page in code, which needs no external engine and no license review. If it starts as HTML, use OpenPDF or Open HTML to PDF for CSS 2.1 templates, or drive real Chromium through Playwright for Java or a rendering API when the template needs modern CSS or JavaScript.
Can Apache PDFBox convert HTML to PDF?
No. PDFBox creates, manipulates and extracts content from PDF documents, but it contains no HTML parser and no CSS engine, and the project does not claim one. Every tutorial showing PDFBox HTML conversion is really using a second library, usually Flying Saucer or Open HTML to PDF, to do the rendering and PDFBox only to write the file.
Is iText free for commercial use in Java?
Not for closed source software. iText for Java is dual licensed AGPL and commercial. Under the AGPL you may not deploy it on a network without disclosing the full source code of your own application, which catches ordinary server side use. Commercial licenses remove that obligation but have no published price, so you have to request a quote.
What is OpenPDF and how is it related to iText?
OpenPDF is the LGPL and MPL licensed successor of iText, forked from iText 4.2.0, the last release published with permissive headers before iText 5.0 moved to AGPL. It creates, edits, renders and encrypts PDFs, and its openpdf-html module generates PDFs from HTML. The current release is 3.0.5 and it requires Java 21 or later.
Does Flying Saucer support CSS flexbox and grid?
No. Flying Saucer renders well formed XML or XHTML using CSS 2.1, which predates both flexbox and grid. Open HTML to PDF, its modern descendant, states outright that it is not a web browser and does not implement flex or grid layout or run JavaScript. Print templates for these engines need table or float based layout.
What is the best free Java PDF library?
Apache PDFBox, if free means free with no conditions attached. It is Apache 2.0 with no revenue ceiling, no disclosure requirement and an explicit patent grant. For free HTML rendering, OpenPDF and Open HTML to PDF are LGPL, which permits use in closed source commercial products provided you do not modify the library itself.
How do I convert HTML to PDF in Java?
You need something with a CSS engine, because PDFBox has none. The pure Java routes are OpenPDF with openpdf-html, Flying Saucer, or Open HTML to PDF, all limited to CSS 2.1 and none running JavaScript. iText pdfHTML handles more CSS under an AGPL or commercial license. For modern CSS or JavaScript you need real Chromium, through Playwright for Java or a rendering API.

Early access

Get on the early-access list

The API opens to the list first, in order. Early access locks the planned launch rates for 12 months. No card required, launching soon.

Render + archive, one API