Recherche…


Remarques

Dans iText 5, nous avons introduit le concept d'événement de page pour permettre aux développeurs d'ajouter un comportement spécifique à l'ouverture d'un document, à l'ouverture d'une nouvelle page, à la fermeture d'un document.

Dans la documentation, nous avons clairement indiqué qu’il était interdit d’ajouter du contenu dans la méthode onStartPage() ; le contenu ne peut être ajouté que dans la méthode onEndPage() . Nous avons également indiqué très clairement que l'objet Document transmis aux méthodes d'événement de page a été transmis uniquement à des fins de lecture seule. Il était interdit d'utiliser document.add() même dans la méthode onEndPage() .

Malheureusement, de nombreux développeurs ignorent complètement la documentation, ce qui a entraîné des problèmes tels que:

Je ne me souviens plus combien de fois je me suis agitée parce qu'un autre développeur avait posté une copie de ces questions. Les gens se demandent souvent pourquoi ils obtiennent une réponse dure, mais ils ne réalisent pas qu'un minimum d'effort de leur part aurait permis à tout le monde, y compris eux-mêmes, de gagner du temps. On aurait pu répondre à toutes ces questions en disant "Lire le manuel (vous savez quoi)."

Une autre option consistait en une refonte complète d’iText afin d’éviter ce genre de problèmes.

En raison de la croissance organique d’iText, la classe d’événements de page a également été étendue avec des fonctionnalités sans rapport avec les événements de page. Il contenait une fonctionnalité de bloc générique , il enregistrait le début et la fin des paragraphes, etc.

Ce que nous avons corrigé dans iText 7:

Nous avons supprimé la fonctionnalité d'événement de page.

Pour tous les événements IEventHandler aux pages, nous implémentons maintenant l'interface IEventHandler et nous utilisons addEventHandler pour ajouter ce gestionnaire en tant que PdfDocumentEvent au PdfDocument . Dans l'exemple, nous utilisons un événement END_PAGE , mais nous aurions également pu utiliser un événement START_PAGE . Que vous ajoutiez du contenu au début ou à la fin importe peu. Vous pouvez en savoir plus à ce sujet dans Gestion des événements; définir les préférences du lecteur et les propriétés du rédacteur, qui est le chapitre 7 du didacticiel iText 7: Building Blocks .

Nous avons amélioré les éléments constitutifs dans le sens où nous les avons rendus plus hiérarchiques (voir Avant de commencer: aperçu des classes et des interfaces qui constituent l’introduction du didacticiel iText 7: Building Blocks ). Nous avons également introduit un ensemble de classes Renderer, une pour chaque bloc de construction, et nous permettons aux développeurs d’adapter ces moteurs de rendu pour qu’un bloc de construction affiche un comportement différent lors du rendu. Voir par exemple l'exemple de rendu dans Ajouter des objets AbstractElement (partie 1) qui est le chapitre 7 du didacticiel iText 7: Building Blocks .

Ces modifications simplifient la fonctionnalité pour les développeurs qui (ne veulent pas) en savoir plus sur PDF et iText, tout en offrant une grande flexibilité aux développeurs qui n’ont pas peur de se plonger dans le code iText pour créer un PDF exactement comme ils le souhaitent.

Veulent en savoir plus? Obtenez l'ebook gratuit!

Text2PdfPageEvents.java (iText 5)

Supposons que nous ayons le fichier texte suivant: jekyll_hyde.txt

Comment pouvons-nous le convertir en PDF qui ressemble à ceci:

entrer la description de l'image ici

Notez la bordure bleue qui est ajoutée aux titres et le numéro de page au bas de chaque page. Dans iText 5, ces éléments sont ajoutés à l'aide des événements de page:

class MyPageEvents extends PdfPageEventHelper {

    protected float startpos = -1;
    protected boolean title = true;

    public void setTitle(boolean title) {
        this.title = title;
    }

    @Override
    public void onEndPage(PdfWriter writer, Document document) {
        Rectangle pagesize = document.getPageSize();
        ColumnText.showTextAligned(
            writer.getDirectContent(),
            Element.ALIGN_CENTER,
            new Phrase(String.valueOf(writer.getPageNumber())),
            (pagesize.getLeft() + pagesize.getRight()) / 2,
            pagesize.getBottom() + 15,
            0);
        if (startpos != -1)
            onParagraphEnd(writer, document,
                pagesize.getBottom(document.bottomMargin()));
        startpos = pagesize.getTop(document.topMargin());
    }

    @Override
    public void onParagraph(PdfWriter writer, Document document,
        float paragraphPosition) {
        startpos = paragraphPosition;
    }

    @Override
    public void onParagraphEnd(PdfWriter writer, Document document,
        float paragraphPosition) {
        if (!title) return;
        PdfContentByte canvas = writer.getDirectContentUnder();
        Rectangle pagesize = document.getPageSize();
        canvas.saveState();
        canvas.setColorStroke(BaseColor.BLUE);
        canvas.rectangle(
            pagesize.getLeft(document.leftMargin()),
            paragraphPosition - 3,
            pagesize.getWidth() - document.leftMargin() - document.rightMargin(),
            startpos - paragraphPosition);
        canvas.stroke();
        canvas.restoreState();
    }
}

Nous pouvons réutiliser le code pour convertir un fichier texte en format PDF à partir de l'exemple Text2Pdf.java (iText 5) et introduire l'événement de page dans PdfWriter :

public void createPdf(String dest)
throws DocumentException, IOException {
    Document document = new Document();
    PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(dest));
    MyPageEvents events = new MyPageEvents();
    writer.setPageEvent(events);
    document.open();
    BufferedReader br = new BufferedReader(new FileReader(TEXT));
    String line;
    Paragraph p;
    Font normal = new Font(FontFamily.TIMES_ROMAN, 12);
    Font bold = new Font(FontFamily.TIMES_ROMAN, 12, Font.BOLD);
    boolean title = true;
    while ((line = br.readLine()) != null) {
        p = new Paragraph(line, title ? bold : normal);
        p.setAlignment(Element.ALIGN_JUSTIFIED);
        events.setTitle(title);
        document.add(p);
        title = line.isEmpty();
    }
    document.close();
}

Source: developers.itextpdf.com

Text2PdfPageEvents1.java (iText 7)

Supposons que vous ayez le fichier texte suivant: jekyll_hyde.txt

Comment pouvons-nous le convertir en PDF qui ressemble à ceci:

entrer la description de l'image ici

Notez les numéros de page au bas de chaque page. Ceux-ci sont ajoutés à l'aide d'une implémentation IEventHandler :

protected class Footer implements IEventHandler {

    @Override
    public void handleEvent(Event event) {
        PdfDocumentEvent docEvent = (PdfDocumentEvent) event;
        PdfDocument pdf = docEvent.getDocument();
        PdfPage page = docEvent.getPage();
        Rectangle pageSize = page.getPageSize();
        PdfCanvas pdfCanvas = new PdfCanvas(
            page.getLastContentStream(), page.getResources(), pdf);
        Canvas canvas = new Canvas(pdfCanvas, pdf, pageSize);
        float x = (pageSize.getLeft() + pageSize.getRight()) / 2;
        float y = pageSize.getBottom() + 15;
        canvas.showTextAligned(
            String.valueOf(pdf.getPageNumber(page)),
            x, y, TextAlignment.CENTER);
    }
}

Nous pouvons réutiliser l'exemple Text2Pdf.java (iText 7) avec seulement deux modifications mineures:

public void createPdf(String dest) throws IOException {
    PdfDocument pdf = new PdfDocument(new PdfWriter(dest));
    pdf.addEventHandler(PdfDocumentEvent.END_PAGE, new Footer());
    Document document = new Document(pdf)
        .setTextAlignment(TextAlignment.JUSTIFIED);
    BufferedReader br = new BufferedReader(new FileReader(TEXT));
    String line;
    PdfFont normal = PdfFontFactory.createFont(FontConstants.TIMES_ROMAN);
    PdfFont bold = PdfFontFactory.createFont(FontConstants.TIMES_BOLD);
    boolean title = true;
    Border border = new SolidBorder(Color.BLUE, 1);
    while ((line = br.readLine()) != null) {
        document.add(new Paragraph(line)
            .setFont(title ? bold : normal)
            .setBorder(title ? border : Border.NO_BORDER));
        title = line.isEmpty();
    }
    document.close();
}

Nous ajoutons un gestionnaire d'événement qui déclenchera la méthode handleEvent() de la classe Footer chaque fois qu'une page se termine. Nous définissons également une bordure pour les objets Paragraph utilisés pour un titre.

Source: developers.itextpdf.com et le tutoriel iText 7: Building Blocks .

Text2PdfPageEvents2.java

Supposons que vous ayez le fichier texte suivant: jekyll_hyde.txt

Comment pouvons-nous le convertir en PDF qui ressemble à ceci:

entrer la description de l'image ici

Notez que ceci est très similaire à ce que nous avions auparavant, mais la bordure des titres a maintenant des coins arrondis. Nous avons créé un objet ParagraphRenderer personnalisé pour y parvenir, et nous avons créé un objet TitleParagraph utilisant ce moteur de rendu:

public class TitleParagraph extends Paragraph {

    public TitleParagraph(String line) {
        super(line);
        try {
            setFont(PdfFontFactory.createFont(FontConstants.TIMES_BOLD));
        }
        catch (IOException ioe) {
        }
    }

    @Override
    protected IRenderer makeNewRenderer() {
        return new ParagraphRenderer(this) {
            @Override
            public void drawBorder(DrawContext drawContext) {
                Rectangle occupiedAreaBBox = getOccupiedAreaBBox();
                float[] margins = getMargins();
                Rectangle rectangle = applyMargins(occupiedAreaBBox, margins, false);
                PdfCanvas canvas = drawContext.getCanvas();
                canvas.roundRectangle(rectangle.getX() - 1, rectangle.getY() - 1,
                rectangle.getWidth() + 2, rectangle.getHeight() + 2, 5).stroke();
            }
        };
    } 
}

Notre code pour convertir du texte en PDF est très simple maintenant. Il n'est plus nécessaire de définir la police en gras pour les titres et il n'est plus nécessaire de définir une bordure:

public void createPdf(String dest) throws IOException {
    PdfDocument pdf = new PdfDocument(new PdfWriter(dest));
    pdf.addEventHandler(PdfDocumentEvent.END_PAGE, new Footer());
    Document document = new Document(pdf)
        .setTextAlignment(TextAlignment.JUSTIFIED);
    BufferedReader br = new BufferedReader(new FileReader(TEXT));
    String line;
    PdfFont normal = PdfFontFactory.createFont(FontConstants.TIMES_ROMAN);
    boolean title = true;
    Border border = new SolidBorder(Color.BLUE, 1);
    while ((line = br.readLine()) != null) {
        if (title)
            document.add(new TitleParagraph(line));
        else
            document.add(new Paragraph(line).setFont(normal));
        title = line.isEmpty();
    }
    document.close();
}

Source: developers.itextpdf.com et le tutoriel iText 7: Building Blocks .



Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow