Comparison
A Java alternative to Flying Saucer (xhtmlrenderer)
Flying Saucer (the xhtmlrenderer project) was a popular Java library for converting XHTML to PDF. It works by wrapping iText 2.x, an unmaintained version of iText from before the license changed to AGPL. The library requires well-formed XHTML (not regular HTML), supports only CSS 2.1, and has had no significant development since the early 2010s. PDFPipe accepts any HTML and renders it with a current browser engine from a standard HTTP call.
Comparison
| PDFPipe | Flying Saucer | |
|---|---|---|
| Input format | Any HTML | Well-formed XHTML only |
| CSS support | Modern CSS (Flexbox, Grid, variables) | CSS 2.1 subset |
| Underlying library | None needed | iText 2.x (unmaintained LGPL) |
| Active maintenance | Yes | No (last significant release ~2012) |
| Web fonts | Any URL | Local font files only |
| JavaScript | Yes | No |
| Maven dependency | None | org.xhtmlrenderer:flying-saucer-pdf |
The XHTML requirement
Flying Saucer requires valid XHTML: every tag must be closed, all attributes must be quoted, and the document must have a valid DOCTYPE and namespace declarations. HTML generated by most template engines (Thymeleaf, Freemarker, JSP) is HTML5, not XHTML. Getting it to parse cleanly in Flying Saucer often means running it through an HTML-to-XHTML converter like JTidy first, adding another dependency and another failure point. PDFPipe accepts any HTML5 markup.
Spring Boot replacement
// Spring Boot controller — no extra Maven dependency needed.
@GetMapping(value = "/invoices/{id}.pdf", produces = "application/pdf")
public ResponseEntity<byte[]> invoicePdf(@PathVariable String id) {
String html = templateEngine.process("invoice", buildContext(id));
RestTemplate rest = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setBearerAuth(apiKey);
headers.setContentType(MediaType.APPLICATION_JSON);
Map<String, Object> body = Map.of(
"html", html,
"options", Map.of("format", "A4")
);
byte[] pdf = rest.postForObject(
"https://api.pdfpipe.xyz/v1/pdf",
new HttpEntity<>(body, headers),
byte[].class
);
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=invoice-" + id + ".pdf")
.body(pdf);
}More Java examples on the Spring Boot guide.
See pricing →