Autres versions

Vous êtes ici : Développer dans K-SupPersonnalisationFront-officeImpression PDF

Mise en place du mécanisme d'impression PDF sur une fiche

Guide pas à pas pour générer une impression PDF personnalisée d'une fiche

Le traitement d'impression PDF est disponible sur l'ensemble des fiches de votre application. Cependant, le flux HTML utilisé par la fonctionnalité étant dédié, il est nécessaire de définir un certain nombre d'éléments pour exploiter la fonctionnalité :
  • Un service qui va permettre d'activer la fonctionnalité pour une fiche et de personnaliser les données qui seront mises à disposition du mécanisme d'impression PDF
  • Un template FreeMarker qui va permettre de définir le flux HTML qui servira de contenu au PDF
  • Une feuille de style CSS qui va permettre de définir la mise en forme du flux HTML et son rendu en PDF
À NOTER
Par défaut, seule la fiche Formation de la nouvelle extension Offre de formation implémente le nouveau mécanisme d'impression PDF.
Pour la suite, nous allons prendre comme exemple la mise en place de l'impression PDF de la fiche Article.
 

Définition du service

  1. Créer la classe ServicePDFArticle
    package com.kosmos.pdf;
    
    import java.time.LocalDateTime;
    import java.time.format.DateTimeFormatter;
    import java.util.Map;
    
    import com.kosmos.service.ServiceSpecifiqueBean;
    import com.kportal.pdf.ExportPDFContexte;
    import com.kportal.pdf.service.ServicePDF;
    import com.univ.objetspartages.bean.ArticleBean;
    
    public class ServicePDFArticle extends ServicePDF implements ServiceSpecifiqueBean<ArticleBean> {}
    L'héritage de la classe ServicePDF permet de bénéficier du mécanisme standard de gestion de l'impression PDF.
    L'implémentation de l'interface ServiceSpecifiqueBean permet la découverte automatique des implémentations de l'impression PDF pour une fiche.
  2. Définir le bean Spring permettant de référencer le service dans un fichier qui sera chargé par Spring (par exemple le fichier ExtensionContext.xml de votre application)
    <bean id="servicePDFArticle" class="com.kosmos.pdf.ServicePDFArticle" parent="servicePDF" />
Voilà qui est suffisant pour définir le service qui permettra d'activer l'impression PDF. Par défaut, le bean Java contenant les données de la fiche (dans notre cas, l'instance de com.univ.objetspartages.om.Article) est mis à disposition du mécanisme d'impression PDF, via le modèle de données, pour être exploité lors de la construction du flux.
Il est néanmoins possible d'enrichir ce modèle de données pour lui fournir des informations supplémentaires, par exemple la date de génération du PDF. Il suffit pour cela de surcharger la méthode ServicePDF#ajouterDonneesSpecifiques :
package com.kosmos.pdf;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Map;

import com.kosmos.service.ServiceSpecifiqueBean;
import com.kportal.pdf.ExportPDFContexte;
import com.kportal.pdf.service.ServicePDF;
import com.univ.objetspartages.bean.ArticleBean;

public class ServicePDFArticle extends ServicePDF implements ServiceSpecifiqueBean<ArticleBean> {

    @Override
    protected void ajouterDonneesSpecifiques(final ExportPDFContexte exportPDFContexte, final Map<String, Object> modele) {
        // Ajoute la date courante dans le modèle
        modele.put("date_edition", DateTimeFormatter.ofPattern("'Édité le' dd/MM/yyyy 'à' hh:mm").format(LocalDateTime.now()));
    }
}

Un objet date_edition pourra alors être exploité au sein du template FreeMarker qui permet de définir le flux.
 

Définition du template FreeMarker

Plus d'infos
Pour acquérir les bases de FreeMarker, il est recommandé de consulter le guide Getting Started with FreeMarker
  1. Créer le fichier src/main/resources/pdf/template/article.ftl, qui contiendra le template FreeMarker permettant la génération du flux HTML :
    <?xml version="1.0" encoding="utf-8"?>
    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr">
        <head>
            <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
            <title>${article.titre}</title>
            <link rel="stylesheet" media="print" type="text/css" href="resources/styles/pdf/article/base.css"/>
        </head>
        <body>
        </body>
    </html>
    À ce stade, on génère le squelette HTML d'une simple page vide.
    On peut néanmoins noter l'utilisation du modèle de données pour afficher le titre de l'article via la syntaxe FreeMarker (${article.titre}).
    On note également la nécessité de référencer un fichier CSS qui sera explicité par la suite.
  2. Définir les champs que l'on souhaite afficher et le flux HTML afférent :
    <?xml version="1.0" encoding="utf-8"?>
    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr">
        <head>
            <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
            <title>${article.titre}</title>
            <link rel="stylesheet" media="print" type="text/css" href="resources/styles/pdf/article/base.css"/>
        </head>
        <body>
            <main>
                <article>
                    <#if article.titre?has_content>
                     <h1>${article.titre}</h1>
                    </#if>
                    <h2>${article.sousTitre}</h2>
                    <p class="chapeau">${article.chapeau}</p>
                    <div class="contenu">${article.formatedCorps}</div>
                </article>
            </main>
        </body>
    </html>
    Notre contenu commence à prendre forme mais cela reste un peu léger pour un beau rendu imprimable.
  3. Ajouter un en-tête et un pied de page :
    <?xml version="1.0" encoding="utf-8"?>
    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr">
        <head>
            <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
            <title>${article.titre}</title>
            <link rel="stylesheet" media="print" type="text/css" href="resources/styles/pdf/article/base.css"/>
        </head>
        <body>
            <header>
                <div class="logo"></div>
            </header>
            <main>
                <article>
                    <#if article.titre?has_content>
                     <h1>${article.titre}</h1>
                    </#if>
                    <h2>${article.sousTitre}</h2>
                    <p class="chapeau">${article.chapeau}</p>
                    <div class="contenu">${article.formatedCorps}</div>
                </article>
            </main>
            <footer>
                ${date_edition}
                <span class="current_page"></span> / <span class="total_pages"></span>
            </footer>
        </body>
    </html>
    L'en-tête permettra de renseigner un logo.
    Le pied de page contiendra la donnée personnalisée, définie précédemment, qui présente la date d'édition ainsi qu'un motif permettant d'intégrer une numérotation sur le PDF grâce à des règles définies dans la feuille de style permettant de définir le rendu.

Définition de la feuille de style CSS

  1. Créer le fichier src/main/webapp/resources/styles/pdf/article/base.css, qui contiendra les règles CSS permettant la mise en page du PDF :
    body {
        font-size: 75%;
        margin: 0;
    }
    
    @page {
        margin: 1cm 1cm 1cm 1cm;
        size: A4 portrait;
    }>
  2. Ajouter les règles de mise en forme du flux HTML :
    h1 {
        font-size: 2rem;
        line-height: 1.2;
    }
    
    h2 {
        font-size: 1.25rem;
        line-height: 1;
    }
    
    .chapeau {
        font-style: italic;
        background-color: #eee;
    }
    Ce ne sont ici que des exemples, à adapter à vos besoins.
  3. Intégrer les règles pour l'en-tête et la gestion de la numérotation dans le pied de page :
    @page {
        counter-increment: page;
        margin: 1cm 1cm 2cm 1cm;
        size: A4 portrait;
    
        @bottom-center {
            content: element(footer);
        }
    }
    
    header {
        display: block;
        min-height: 5em;
        background-color: #ED1A3B;
    }
    
    header .logo {
        background: url("https://www.kosmos.fr/uas/kosmos/LOGO/Kosmos_blanc_BD.png") no-repeat;
        height: 5em;
    }
    
    footer {
        position: running(footer);
    }
    
    .current_page:before {
        content: counter(page);
    }
    
    .total_pages:before {
        content: counter(pages);
    }
    On notera la gestion de la numérotation qui nécessite l'ajout d'une propriété counter-increment au niveau de la règle @page et l'utilisation de la fonction counter au moment de l'affichage.

Mis à jour le 11 avril 2018