Zoeken…


Opmerkingen

In iText 5 hebben we het concept van pagina-evenementen geïntroduceerd waarmee ontwikkelaars specifiek gedrag kunnen toevoegen wanneer een document wordt geopend, wanneer een nieuwe pagina wordt geopend, wanneer een pagina eindigt en wanneer een document wordt gesloten.

In de documentatie hebben we heel duidelijk gemaakt dat het verboden was om inhoud toe te voegen in de methode onStartPage() ; inhoud kan alleen worden toegevoegd met de methode onEndPage() . We hebben ook heel duidelijk gemaakt dat het Document is doorgegeven aan de pagina-gebeurtenismethoden alleen voor alleen-lezen doeleinden is doorgegeven. Het was verboden om document.add() te gebruiken document.add() zelfs niet in de methode onEndPage() .

Helaas negeren veel ontwikkelaars de documentatie volledig, wat leidde tot problemen zoals:

Ik kan me niet herinneren hoe vaak ik geagiteerd raakte omdat nog een andere ontwikkelaar een duplicaat van deze vragen plaatste. Mensen vragen zich vaak af waarom ze een hard antwoord krijgen, maar ze realiseren zich niet dat een minimale inspanning van hun kant iedereen, inclusief zichzelf, veel tijd zou hebben bespaard. Al deze vragen hadden kunnen worden beantwoord door te zeggen: "Lees de (je weet wel welke) handleiding."

Een andere optie was een volledige revisie van iText zodat dit soort problemen kunnen worden vermeden.

Vanwege de organische groei van iText werd de pagina-eventklasse ook uitgebreid met functionaliteit die niet gerelateerd was aan pagina-events. Het bevat generieke chunk- functionaliteit, het registreerde het begin en het einde van paragrafen, enzovoort.

Wat we hebben opgelost in iText 7:

We hebben de functionaliteit van de pagina-gebeurtenis verwijderd.

Voor alle gebeurtenissen met betrekking tot pagina's implementeren we nu de interface IEventHandler en gebruiken we addEventHandler om deze handler als een PdfDocumentEvent aan het PdfDocument toe te voegen. In het voorbeeld gebruiken we een END_PAGE gebeurtenis, maar we hadden ook een START_PAGE gebeurtenis kunnen gebruiken. Het maakt niet meer uit of u aan het begin of aan het einde inhoud toevoegt. Meer hierover leest u in Gebeurtenissen afhandelen; voorkeuren voor kijkers en eigenschappen van de schrijver instellen zoals beschreven in hoofdstuk 7 in de tutorial iText 7: bouwstenen .

We hebben de bouwstenen verbeterd in die zin dat we ze hiërarchischer hebben gemaakt (zie Voordat we beginnen: Overzicht van de klassen en interfaces , de introductie van de tutorial iText 7: Bouwstenen ). We hebben ook een set Renderer-klassen geïntroduceerd, één voor elke bouwsteen, en we staan ontwikkelaars toe deze renderers aan te passen zodat een bouwsteen een ander gedrag vertoont wanneer deze wordt weergegeven. Zie bijvoorbeeld het renderer-voorbeeld in AbstractElement-objecten toevoegen (deel 1) dat hoofdstuk 7 is in de tutorial iText 7: Bouwstenen .

Deze wijzigingen vereenvoudigen de functionaliteit voor ontwikkelaars die niet veel willen (willen) weten over PDF en iText, terwijl ze tegelijkertijd een overvloed aan flexibiliteit bieden aan die ontwikkelaars die niet bang zijn om diep in de iText-code te graven om een PDF precies zoals ze het willen.

Wil meer weten? Ontvang het gratis ebook!

Text2PdfPageEvents.java (iText 5)

Stel dat we het volgende tekstbestand hebben: jekyll_hyde.txt

Hoe converteren we het naar een PDF die er als volgt uitziet:

voer hier de afbeeldingsbeschrijving in

Let op de blauwe rand die aan de titels wordt toegevoegd en het paginanummer onderaan elke pagina. In iText 5 worden deze elementen toegevoegd met behulp van pagina-evenementen:

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

We kunnen de code opnieuw gebruiken om een tekstbestand te converteren naar een PDF uit het Text2Pdf.java (iText 5) -voorbeeld en de pagina-gebeurtenis introduceren in de 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();
}

Bron: developers.itextpdf.com

Text2PdfPageEvents1.java (iText 7)

Stel dat u het volgende tekstbestand hebt: jekyll_hyde.txt

Hoe converteren we het naar een PDF die er als volgt uitziet:

voer hier de afbeeldingsbeschrijving in

Let op de paginanummers onderaan elke pagina. Deze worden toegevoegd met behulp van een IEventHandler implementatie:

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

We kunnen het Text2Pdf.java (iText 7) -voorbeeld opnieuw gebruiken met slechts twee kleine wijzigingen:

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

We voegen een gebeurtenishandler toe die de methode handleEvent() van de klasse Footer activeert wanneer een pagina eindigt. We definiëren ook een rand voor de Paragraph objecten die worden gebruikt voor een titel.

Bron: developers.itextpdf.com en de tutorial iText 7: Building Blocks .

Text2PdfPageEvents2.java

Stel dat u het volgende tekstbestand hebt: jekyll_hyde.txt

Hoe converteren we het naar een PDF die er als volgt uitziet:

voer hier de afbeeldingsbeschrijving in

Merk op dat dit erg lijkt op wat we eerder hadden, maar de rand van de titels heeft nu afgeronde hoeken. We hebben een aangepaste ParagraphRenderer om dit te bereiken, en hebben we een TitleParagraph object dat toepassingen die renderer:

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

Onze code om tekst naar PDF te converteren is nu heel eenvoudig. We hoeven niet langer het lettertype vet in te stellen voor de titels en we hoeven niet langer een rand te definiëren:

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

Bron: developers.itextpdf.com en de tutorial iText 7: Building Blocks .



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow