Skip to content

§ Spring Boot HTML to PDF

HTML to PDF Spring Boot: Convert a Thymeleaf Template to a Real PDF

Turn a Thymeleaf template or any URL into a searchable, pixel accurate PDF with one call from your Spring Boot service. Managed Chromium renders your real template with full CSS, web fonts and JavaScript charts, so there is no AGPL license to buy, no PDF engine in your JAR and no browser to scale. Try it on any URL or HTML 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

To convert HTML to PDF in Spring Boot, render your Thymeleaf template to an HTML string with TemplateEngine.process, then pass that string to something that lays it out. The classic JVM route is Flying Saucer or OpenHTMLtoPDF, which are free and run in-process but support only a subset of CSS and no JavaScript at all. iText html2pdf handles far more CSS, but it is AGPL, so using it in a closed-source product requires a paid commercial license. When your document needs modern CSS, web fonts or JavaScript charts, or you would rather not add a rendering engine to your service, POST the HTML to a rendering API instead. Sitepdf renders it in managed Chromium and returns a true, selectable vector PDF, plus an optional timestamped archive of exactly what it rendered.

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

§ 00

Three ways to make a PDF in Spring Boot, compared

Spring Boot ships no PDF support, so every project bolts on one of these. They differ most in CSS coverage, whether JavaScript runs at all, and what the license costs you in a commercial product.

Approach How it works CSS and JavaScript License Best for
Flying Saucer, OpenHTMLtoPDF
in-process
Parses your XHTML and CSS and draws the PDF inside the JVM, no browser CSS 2.1 with some CSS 3, plus paged media; no JavaScript engine Flying Saucer is LGPL; OpenHTMLtoPDF is LGPL and community maintained Server-rendered invoices and reports with disciplined, simple CSS
iText html2pdf
commercial engine
A mature HTML and CSS to PDF converter with strong paged-media support Much broader CSS than Flying Saucer; still no JavaScript execution AGPL v3, so a closed-source product needs a paid commercial license Teams that need heavy CSS fidelity and can budget the license
Managed Chromium API
Sitepdf
You POST your rendered Thymeleaf HTML or a URL, a managed browser prints it Full modern CSS and JavaScript, it is a real current browser Billed per render, nothing to license or host Production documents, JavaScript charts, exact fidelity, a dated record

The honest read: if your PDFs are plain, server-rendered invoices with tables and no JavaScript, Flying Saucer or OpenHTMLtoPDF will do the job for free and keep everything in one process, which is a real advantage. A rendering API earns its place in three cases: the template uses modern layout like flexbox or grid, or draws content with JavaScript; you want output identical to Chrome; or you want to avoid the AGPL question entirely without paying for a commercial engine.

§ 01

The Thymeleaf half is easy, the rendering half is the decision

Every Spring Boot PDF tutorial starts the same way, because the first step is genuinely trivial: you already have a template engine, so you render the template to a string outside the usual HTTP response cycle and hand the string to a PDF library. Thymeleaf is completely decoupled from whatever renders the PDF, which is why you can swap the second half without touching the template.

@Service
public class InvoicePdfService {

    private final TemplateEngine templateEngine;

    public String renderHtml(Invoice invoice) {
        Context context = new Context();
        context.setVariable("invoice", invoice);
        return templateEngine.process("invoices/invoice", context);
    }
}

That HTML string is the handoff point, and everything interesting happens after it. The engine you pass it to decides three things you cannot change later without a rewrite: how much CSS survives, whether JavaScript runs at all, and what the license obliges you to do. Most teams pick the library first and discover those constraints three sprints in, when a designer sends a template built with flexbox.

§ 02

Flying Saucer and OpenHTMLtoPDF: free, in-process, CSS-limited

Flying Saucer is the long-standing JVM answer, and it is still actively maintained: version 10 shipped in December 2025, though recent releases require Java 21 or newer. OpenHTMLtoPDF grew out of it and adds SVG support and accessible, tagged PDF output for WCAG and PDF/UA work. The original OpenHTMLtoPDF repository went quiet around 2022, but a community fork under the io.github.openhtmltopdf coordinates picked it up, moved to PDFBox 3 and has kept shipping releases through 2026.

Both are excellent at what they do and cost nothing. The constraint to plan around is CSS. They implement roughly CSS 2.1 with pieces of CSS 3, and they expect well-formed XHTML, so a template that leans on flexbox, CSS grid, or modern color functions will not lay out the way it does in a browser. Neither has a JavaScript engine, so a Chart.js graph or anything drawn client side renders as an empty box. For a table-based invoice with careful, conservative CSS, none of that matters and you get a fast, dependency-light render inside your own JVM.

§ 03

The iText license question, stated plainly

iText comes up in nearly every Spring Boot PDF thread, usually without the license attached, so it is worth being direct. Since version 5.0.0 iText has been distributed under the AGPL v3, alongside a paid commercial license. AGPL is a strong copyleft license: if you use it in software you distribute or expose over a network, the obligation extends to your own source. That is why iText sells commercial licenses, and it is exactly the case most SaaS products fall into. Note also that iText 8 reaches end of life in October 2026, so a version decision is due for teams already on it.

None of that makes iText a bad tool. Its html2pdf module handles considerably more CSS than Flying Saucer, and for print-heavy documents it is genuinely strong. It just is not free for a commercial closed-source product, and a fair comparison should say so before your legal review does. If the reason you were reaching for iText was CSS fidelity rather than PDF manipulation, a browser gives you more fidelity than any HTML-parsing library and sidesteps the license question completely.

§ 04

The browser path: render your real template in Chromium

When the template uses modern CSS, or draws part of the page with JavaScript, or simply has to match what users see in Chrome, let a real browser do the layout. Nothing about your Thymeleaf setup changes. You render the template to a string as usual, then POST it, or point the API at a live route in your service and let it load the page, run the scripts and wait for the charts.

String html = invoicePdfService.renderHtml(invoice);

MultiValueMap<String, String> form = new LinkedMultiValueMap<>();
form.add("html", html);
form.add("format", "Letter");
form.add("archive", "true");

RenderResult result = WebClient.create()
        .post()
        .uri("https://api.sitepdf.com/v1/render")
        .header("Authorization", "Bearer " + apiKey)
        .body(BodyInserters.fromFormData(form))
        .retrieve()
        .bodyToMono(RenderResult.class)
        .block();

Because a current browser lays it out, your CSS grid, web fonts, background colors and JavaScript charts all render the way they do on screen, and the text stays real and searchable rather than becoming an image. There is no rendering engine in your JAR, no native library on the host, and no browser process competing with your service for heap. The same call works from a @Scheduled job or a batch step. Our HTML to PDF in Java guide covers the plain-Java library options in more depth, and the PDF generator API page lists every parameter, including margins, page size and the wait signal for charts.

§ 05

Keep a dated copy of every document you generated

An invoice, a statement or a compliance report leaves your service and nothing verifiable stays behind. Add archive=true to the render call and Sitepdf also stores a timestamped, immutable snapshot of exactly what it rendered, retrievable by id later, so you can show what a given document said on a given date. For regulated JVM shops that provenance is often the reason to render server side at all. The website archiving page explains how the record works, and if you are weighing running headless Chromium in your own cluster instead, the Gotenberg alternative page walks that trade off honestly. Renders are transient by default; leave archiving off and we return the PDF and store nothing.

Post your rendered Thymeleaf HTML, or point the API at a live Spring Boot route. A real browser prints it.
curl https://api.sitepdf.com/v1/render \
  -H "Authorization: Bearer $SITEPDF_KEY" \
  -F url=https://app.example.com/invoices/8842 \
  -F format=Letter \
  -F wait_for="#invoice-total" \
  -F archive=true

{
  "pdf_url": "https://api.sitepdf.com/v1/documents/doc_sb63m.pdf",
  "pages": 3,
  "rendered_in_ms": 1704,
  "archive": {
    "id": "arc_sb90t",
    "captured_at": "2026-07-19T21:41:07Z",
    "retrieve_url": "https://api.sitepdf.com/v1/archives/arc_sb90t"
  }
}

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

§ 06

Questions about this job

How do I convert HTML to PDF in Spring Boot?
Render your Thymeleaf template to an HTML string with TemplateEngine.process, then pass that string to a renderer. Flying Saucer or OpenHTMLtoPDF do it in-process for free with limited CSS and no JavaScript. For modern CSS or JavaScript charts, POST the HTML to a rendering API that runs managed Chromium and returns a searchable PDF.
How do I generate a PDF from a Thymeleaf template?
Build a Thymeleaf Context, set your model variables on it, and call templateEngine.process("template-name", context) to get the finished HTML as a String. Thymeleaf is decoupled from PDF generation, so that same string can go to Flying Saucer, OpenHTMLtoPDF, iText html2pdf or a rendering API without changing the template.
Is iText free to use for HTML to PDF in Spring Boot?
Only under the AGPL v3. iText is dual licensed, and AGPL is strong copyleft, so using it in a closed-source or network-served commercial product generally requires buying a commercial license. Flying Saucer and OpenHTMLtoPDF are LGPL alternatives, and a hosted rendering API avoids the licensing question entirely since nothing ships in your build.
Does Flying Saucer support JavaScript or flexbox?
No to both. Flying Saucer and OpenHTMLtoPDF implement roughly CSS 2.1 with parts of CSS 3, so flexbox and CSS grid do not lay out correctly, and neither has a JavaScript engine, so client-side charts render blank. Templates for them should use conservative, table-based CSS, or the render should happen in a real browser instead.
How do I render a Spring Boot page with charts to PDF?
If the chart is drawn by JavaScript, no in-process JVM library will run it, so either pre-render the chart to an SVG or image on the server, or render the page in a real browser. A rendering API loads your route in managed Chromium, runs the JavaScript, waits for the chart to finish, then prints it, so the graph appears exactly as on screen.

§ 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