Convertir un EPUB en PDF avec Java
Convertir un livre au format EPUB (un zip contenant XHTML + CSS + images) vers PDF est un besoin récurrent : archivage, impression, distribution. Java ne propose aucune API native, mais plusieurs bibliothèques open source s'en chargent très bien.
Stack recommandée : epublib + Flying Saucer
Deux bibliothèques éprouvées :
- epublib (nl.siegmann.epublib) lit et extrait le contenu XHTML de l'EPUB.
- Flying Saucer (org.xhtmlrenderer) rend du XHTML en PDF via iText.
Dépendances Maven
<dependencies>
<dependency>
<groupId>nl.siegmann.epublib</groupId>
<artifactId>epublib-core</artifactId>
<version>3.1</version>
</dependency>
<dependency>
<groupId>org.xhtmlrenderer</groupId>
<artifactId>flying-saucer-pdf-openpdf</artifactId>
<version>9.5.0</version>
</dependency>
</dependencies>
Conversion basique
import nl.siegmann.epublib.domain.*;
import nl.siegmann.epublib.epub.EpubReader;
import org.xhtmlrenderer.pdf.ITextRenderer;
import java.io.*;
import java.nio.charset.StandardCharsets;
public class EpubToPdf {
public static void convert(File epubFile, File pdfFile) throws Exception {
Book book;
try (InputStream in = new FileInputStream(epubFile)) {
book = new EpubReader().readEpub(in);
}
StringBuilder html = new StringBuilder();
html.append("<html><head><meta charset='UTF-8'/>");
html.append("<style>body{font-family:serif;line-height:1.5;} h1,h2{page-break-before:always;}</style>");
html.append("</head><body>");
for (Resource chapter : book.getContents()) {
String chapterHtml = new String(chapter.getData(), StandardCharsets.UTF_8);
// On garde uniquement le contenu du <body>
int start = chapterHtml.indexOf("<body");
int end = chapterHtml.lastIndexOf("</body>");
if (start >= 0 && end > start) {
chapterHtml = chapterHtml.substring(chapterHtml.indexOf('>', start) + 1, end);
}
html.append(chapterHtml);
}
html.append("</body></html>");
try (OutputStream out = new FileOutputStream(pdfFile)) {
ITextRenderer renderer = new ITextRenderer();
renderer.setDocumentFromString(html.toString());
renderer.layout();
renderer.createPDF(out);
}
}
public static void main(String[] args) throws Exception {
convert(new File("livre.epub"), new File("livre.pdf"));
System.out.println("Conversion terminée");
}
}
Gérer le XHTML strict
Flying Saucer exige du XHTML bien formé. Les fichiers EPUB le respectent généralement, mais certains contiennent des balises HTML5 que Flying Saucer ne connaît pas (<nav>, <section>, <figure>). Solution : passer par jsoup pour nettoyer avant rendu :
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Entities;
Document doc = Jsoup.parse(chapterHtml);
doc.outputSettings().syntax(Document.OutputSettings.Syntax.xml);
doc.outputSettings().escapeMode(Entities.EscapeMode.xhtml);
String propre = doc.html();
Gérer les images
Flying Saucer ne charge pas les images embarquées dans l'EPUB automatiquement. Deux options :
- Extraire les images dans un dossier temporaire et mettre à jour les chemins
src="...". - Embarquer en base64 directement dans le HTML :
src="data:image/jpeg;base64,...".
for (Resource img : book.getResources().getAll()) {
if (img.getMediaType().getName().startsWith("image/")) {
Path out = Paths.get("/tmp/epub-images/", img.getHref());
Files.createDirectories(out.getParent());
Files.write(out, img.getData());
}
}
Gérer les polices
Par défaut Flying Saucer n'intègre que Helvetica, Courier et Times. Pour des polices personnalisées (dont les caractères accentués), enregistrez-les :
renderer.getFontResolver().addFont(
"/usr/share/fonts/truetype/dejavu/DejaVuSerif.ttf",
"DejaVu Serif",
"UTF-8",
true,
null
);
Et dans votre CSS :
body { font-family: 'DejaVu Serif', serif; }
Alternatives
Appeler Calibre en ligne de commande
Calibre est l'outil de référence, plus complet que n'importe quelle bibliothèque Java. Il peut être invoqué depuis Java via ProcessBuilder :
Process p = new ProcessBuilder("ebook-convert", "livre.epub", "livre.pdf")
.inheritIO()
.start();
p.waitFor();
Très bonne qualité de rendu, mais dépendance externe et démarrage plus lent.
Pandoc + LaTeX
Pour une qualité typographique optimale (livres publiés) :
pandoc livre.epub -o livre.pdf --pdf-engine=xelatex
iText 8 (solution commerciale)
iText 8 possède des modules capables de convertir HTML/EPUB vers PDF avec un excellent rendu, mais nécessite une licence commerciale au-delà des usages open source (AGPL).
Limites à connaître
- Les EPUB 3 avec composants interactifs (JavaScript, audio) perdent leurs fonctions en PDF.
- Les tables des matières ne sont pas toujours recréées automatiquement — il faut les régénérer à partir du fichier
toc.ncxounav.xhtml. - Les fichiers protégés par DRM (Adobe ADEPT, Barnes & Noble) ne peuvent pas être convertis.
Pour un besoin ponctuel, Calibre en ligne de commande est imbattable. Pour un service automatisé en production, epublib + Flying Saucer offre un compromis solide entre indépendance et qualité.