Suche…


Bemerkungen

In iText 5 haben wir das Konzept der Seitenereignisse eingeführt, damit Entwickler beim Öffnen eines Dokuments, beim Öffnen einer neuen Seite, beim Beenden einer Seite und beim Schließen eines Dokuments ein bestimmtes Verhalten hinzufügen können.

In der Dokumentation haben wir deutlich gemacht, dass das Hinzufügen von Inhalten in der onStartPage() -Methode verboten ist . Inhalt kann nur in der onEndPage() -Methode hinzugefügt werden. Wir haben auch deutlich gemacht, dass das Document Objekt, das an die Seitenereignismethoden übergeben wurde, nur zu schreibgeschützten Zwecken übergeben wurde. Es war verboten , document.add() auch in der onEndPage() -Methode zu verwenden.

Leider ignorieren viele Entwickler die Dokumentation vollständig. Dies führte zu Problemen wie:

Ich kann mich nicht erinnern, wie oft ich aufgeregt wurde, weil ein anderer Entwickler ein Duplikat dieser Fragen veröffentlicht hat. Die Leute fragen sich oft, warum sie eine scharfe Antwort bekommen, aber sie wissen nicht, dass ein Minimum an Anstrengung von ihrer Seite allen, einschließlich sich selbst, viel Zeit gespart hätte. Alle diese Fragen könnten beantwortet werden, indem Sie sagten: "Lesen Sie das (Sie wissen, was) Handbuch."

Eine weitere Option war eine vollständige Überarbeitung von iText, um diese Art von Problemen zu vermeiden.

Aufgrund des organischen Wachstums von iText wurde die Seitenereignisklasse auch um Funktionen erweitert, die sich nicht auf Seitenereignisse beziehen. Es enthielt generische Chunk- Funktionen, registrierte den Anfang und das Ende von Absätzen und so weiter.

Was wir in iText 7 behoben haben:

Wir haben die Seitenereignisfunktion entfernt.

Für alle Ereignisse in Bezug auf Seiten implementieren wir nun die IEventHandler Schnittstelle und verwenden den addEventHandler , um diesen Handler als PdfDocumentEvent zum PdfDocument . Im Beispiel verwenden wir ein END_PAGE Ereignis, wir hätten aber auch ein START_PAGE Ereignis verwenden können. Es spielt keine Rolle mehr, ob Sie am Anfang oder am Ende Inhalte hinzufügen. Weitere Informationen hierzu finden Sie unter Ereignisse behandeln. Festlegen von Viewer-Einstellungen und Schreiber-Eigenschaften. Dies ist Kapitel 7 des Tutorials zu iText 7: Building Blocks .

Wir haben die Bausteine ​​dahingehend verbessert, dass wir sie hierarchischer gemacht haben (siehe Bevor wir beginnen: Überblick über die Klassen und Schnittstellen, das ist die Einführung des Tutorials iText 7: Bausteine ). Wir haben auch eine Reihe von Renderer-Klassen eingeführt, eine für jeden Baustein. Außerdem können Entwickler diese Renderer so anpassen, dass ein Baustein beim Rendern ein anderes Verhalten zeigt. Siehe zum Beispiel das Renderer-Beispiel in Hinzufügen von AbstractElement-Objekten (Teil 1), das sich in Kapitel 7 des Tutorials zu iText 7: Building Blocks befindet .

Diese Änderungen vereinfachen die Funktionalität für Entwickler, die sich mit PDF und iText nicht auskennen (wollen), und bieten gleichzeitig eine enorme Flexibilität für Entwickler, die keine Angst haben, tief in den iText - Code einzugreifen, um eine PDF genau so, wie sie es wollen.

Möchten Sie mehr wissen? Holen Sie sich das kostenlose E-Book!

Text2PdfPageEvents.java (iText 5)

Angenommen, wir haben die folgende Textdatei: jekyll_hyde.txt

Wie konvertieren wir es in ein PDF, das so aussieht:

Geben Sie hier die Bildbeschreibung ein

Beachten Sie den blauen Rand, der den Titeln hinzugefügt wird, und die Seitennummer unten auf jeder Seite. In iText 5 werden diese Elemente mithilfe von Seitenereignissen hinzugefügt:

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();
    }
}

Wir können den Code zum Konvertieren einer Textdatei aus dem Beispiel Text2Pdf.java (iText 5) in eine PDF-Datei wiederverwenden und das Seitenereignis in den 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();
}

Quelle: developer.itextpdf.com

Text2PdfPageEvents1.java (iText 7)

Angenommen, Sie haben die folgende Textdatei: jekyll_hyde.txt

Wie konvertieren wir es in ein PDF, das so aussieht:

Geben Sie hier die Bildbeschreibung ein

Notieren Sie sich die Seitennummern unten auf jeder Seite. Diese werden mithilfe einer IEventHandler Implementierung hinzugefügt:

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);
    }
}

Das Beispiel für Text2Pdf.java (iText 7) kann mit nur zwei geringfügigen Änderungen wiederverwendet werden:

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();
}

Wir fügen einen Ereignishandler hinzu, der die handleEvent() Methode der Footer Klasse jedes Mal auslöst, handleEvent() eine Seite endet. Wir definieren auch einen Rahmen für die Paragraph , die für einen Titel verwendet werden.

Quelle: developer.itextpdf.com und das Tutorial zu iText 7: Bausteine .

Text2PdfPageEvents2.java

Angenommen, Sie haben die folgende Textdatei: jekyll_hyde.txt

Wie konvertieren wir es in ein PDF, das so aussieht:

Geben Sie hier die Bildbeschreibung ein

Beachten Sie, dass dies dem vorher sehr ähnlich ist, aber der Rand der Titel hat jetzt abgerundete Ecken. Wir haben einen benutzerdefinierten ParagraphRenderer , um dies zu erreichen, und ein TitleParagraph Objekt erstellt, das diesen Renderer verwendet:

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();
            }
        };
    } 
}

Unser Code zum Konvertieren von Text in PDF ist jetzt sehr einfach. Wir müssen die Schriftart für die Titel nicht mehr fett setzen, und wir müssen keinen Rahmen mehr definieren:

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();
}

Quelle: developer.itextpdf.com und das Tutorial zu iText 7: Bausteine .



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow