Créer des document paginés avec Flying Saucer

Un PDF depuis un ensemble HTML + ressources

Enregistrement de la page web concernée

Le manuel utilisateur se trouve à cette adresse.

Enregistrez là en tant que page web complète, dans le dossier racine de votre projet HtmlToPdf par exemple.

Ainsi, vous avez normalement un fichier HTML ainsi qu'un dossier de ressources.

Si votre classe HtmlToPdf n'est pas créée, créez là.

Un clic droit sur le projet devrait vous permettre de créer une nouvelle classe.

Dans cette classe, insérer ce code de base :

(si nécessaire, renommer les fichiers)

1
package htmltopdf;
2
3
import org.xhtmlrenderer.pdf.ITextRenderer;
4
import org.htmlcleaner.CleanerProperties;
5
import org.htmlcleaner.HtmlCleaner;
6
import org.htmlcleaner.PrettyXmlSerializer;
7
import org.htmlcleaner.TagNode;
8
import java.io.*;
9
10
public class HtmlToPdf {
11
    static String baseFolder = System.getProperty("user.dir") + "/"; // correspond à la racine du projet Java
12
    static String entree = baseFolder+"UserGuide.html";
13
    static String sortie = baseFolder+"UserGuide.pdf";
14
    static String resourcesFolder = baseFolder+"\\UserGuide_fichiers\\";
15
    static String cleanFile = baseFolder + "clean.xhtml";
16
    
17
    public static void main(String[] args) throws Exception {
18
	   createPDF(entree, sortie);
19
    }
20
	
21
    public static void createPDF(String entree, String pdf) throws Exception {
22
        OutputStream os = null;
23
        try {
24
            //
25
            // Tout le travail reste à faire... Ensemble !
26
            //
27
        } 
28
        catch (IOException e) {
29
            System.out.println(e.getMessage());
30
        }
31
        finally {
32
            if (os != null) {
33
                try {
34
                    os.close();
35
                } catch (IOException e) {
36
                    System.out.println(e.getMessage());
37
                }
38
            }
39
        }
40
    }
41
}

Nettoyage du fichier HTML

La première étape consiste à nettoyer le fichier HTML, à l'aide de l'API HtmlCleaner.

Nous produirons alors un fichier XHTML recevable par le moteur de Flying Saucer.

La méthode clean() de la classe org.htmlCleaner.HtmlCleaner nous renvoie un élément de type TagNode, qui correspond à une arborescence de noeuds XML. Cette arborescence est ensuite inscrite dans un fichier à l'aide d'un sérialiseur XML.

Les propriétés CleanerProperties fournies aux parseurs parlent d'elles-même.

1
CleanerProperties props = new CleanerProperties();
2
// paramètres d'analyse
3
props.setTranslateSpecialEntities(true);
4
props.setOmitComments(true);
5
6
// parse le fichier html
7
TagNode tagNode = new HtmlCleaner(props).clean(new File(entree));
8
9
// sérialise le contenu bien-formé dans le fichier clean
10
new PrettyXmlSerializer(props).writeToFile(tagNode, cleanFile, "utf-8");

Création du Pdf

Il s'agit maintenant :

  1. d'instancier notre flux de sortie (os)

  2. de créer une classe d'export (renderer)

    Notez qu'il s'agit d'une classe de la bibliothèque iText...

  3. de fournir le contexte de notre fichier, c'est à dire ses ressources

  4. de lui indiquer le document à traiter : renderer.setDocument()

  5. d'effectuer le traitement : renderer.createPDF()

1
os = new FileOutputStream(pdf);
2
ITextRenderer renderer = new ITextRenderer();
3
4
// indique l'emplacement des ressources (images, css)
5
renderer.getSharedContext().getUserAgentCallback().setBaseURL(resourcesFolder);
6
7
// les 3 lignes classiques d'un rendu PDF avec Flying Saucer
8
renderer.setDocument(new File(cleanFile));
9
renderer.layout();
10
renderer.createPDF(os);
11
12
os.close();
13
os = null;

Voici la classe finale, en une seule fois :

1
2
package htmltopdf;
3
4
import org.xhtmlrenderer.pdf.ITextRenderer;
5
import org.htmlcleaner.CleanerProperties;
6
import org.htmlcleaner.HtmlCleaner;
7
import org.htmlcleaner.PrettyXmlSerializer;
8
import org.htmlcleaner.TagNode;
9
import java.io.*;
10
11
public class HtmlToPdf {
12
    static String baseFolder = System.getProperty("user.dir") + "/"; // correspond à la racine du projet Java
13
    static String entree = baseFolder+"UserGuide.html";
14
    static String sortie = baseFolder+"UserGuide.pdf";
15
    static String resourcesFolder = baseFolder+"\\UserGuide_fichiers\\";
16
    static String cleanFile = baseFolder + "clean.xhtml";
17
    
18
    public static void main(String[] args) throws Exception {
19
	createPDF(entree, sortie);
20
    }
21
	
22
    public static void createPDF(String entree, String pdf) throws Exception {
23
        OutputStream os = null;
24
        try {
25
            CleanerProperties props = new CleanerProperties();
26
            //change les paramètres par defaut
27
            props.setTranslateSpecialEntities(true);
28
            props.setOmitComments(true);
29
            
30
            // parse
31
            TagNode tagNode = new HtmlCleaner(props).clean(new File(entree));
32
            // sérialise le contenu bien-formé dans le fichier clean
33
            new PrettyXmlSerializer(props).writeToFile(tagNode, cleanFile, "utf-8");
34
35
            os = new FileOutputStream(pdf);
36
            ITextRenderer renderer = new ITextRenderer();
37
38
            // indique l'emplacement des ressources (images, css)
39
            renderer.getSharedContext().getUserAgentCallback().setBaseURL(resourcesFolder);
40
41
            // les 3 lignes classiques d'un rendu PDF avec Flying Saucer
42
            renderer.setDocument(new File(cleanFile));
43
            renderer.layout();
44
            renderer.createPDF(os);
45
46
            os.close();
47
            os = null;
48
        } 
49
        catch (IOException e) {
50
            System.out.println(e.getMessage());
51
        }
52
        finally {
53
            if (os != null) {
54
                try {
55
                    os.close();
56
                } catch (IOException e) {
57
                    System.out.println(e.getMessage());
58
                }
59
            }
60
        }
61
    }
62
}
63

Question

Ouvrez maintenant votre fichier Pdf généré, et comparez-le avec la version web. Quelles différences pouvez-vous noter ?

Quels éléments typiques d'un média paginé sont présents ?

Quels ajouts pourraient être encore appréciables ?

Solution

Les deux versions sont effectivement différentes. On retrouvera dans le document PDF :

  • Une page de garde, avec bordure

  • des compteurs de page

  • des sauts de page

  • des en-têtes et pieds de page

La gestion des veuves et orphelins pourrait être à revoir.

PrécédentPrécédentSuivantSuivant
AccueilAccueilImprimerImprimer Jean Vintache, Samuel Martineau, Fabien Michalon, 2013-2015 (Contributions : Stéphane Crozat, les étudiants de NF29) Paternité - Partage des Conditions Initiales à l'IdentiqueRéalisé avec Scenari (nouvelle fenêtre)