Sök…


Anmärkningar

I iText 5 introducerade vi konceptet med sidhändelser så att utvecklare kan lägga till specifikt beteende när ett dokument öppnas, när en ny sida öppnas, när en sida slutar och när ett dokument stängs.

I dokumentationen gjorde vi det mycket tydligt att det var förbjudet att lägga till innehåll i onStartPage() -metoden; innehåll kan bara läggas till på onEndPage() . Vi gjorde det också mycket tydligt att Document skickades till sidhändelsemetoderna skickades endast för skrivskydd . Det var förbjudet att använda document.add() även i onEndPage() .

Tyvärr ignorerar många utvecklare fullständigt dokumentationen, vilket ledde till problem som:

Jag kommer inte ihåg hur många gånger jag blev upprörd eftersom ännu en utvecklare publicerade en duplikat av dessa frågor. Folk undrar ofta varför de får ett hårt svar, men de inser inte att ett minimum av ansträngning från deras sida skulle ha sparat alla, inklusive sig själva, mycket tid. Alla dessa frågor kunde ha besvarats genom att säga "Läs handboken (du vet vilken)."

Ett annat alternativ var en fullständig översyn av iText så att sådana problem kan undvikas.

På grund av den organiska tillväxten av iText hade sidhändelseklassen också utvidgats med funktionalitet som inte var relaterad till sidhändelser. Den innehöll generisk chunk- funktionalitet, den registrerade början och slutet på stycken och så vidare.

Vad vi fixade i iText 7:

Vi tog bort sidhändelsefunktionen.

För alla händelser med avseende på sidor implementerar vi nu IEventHandler gränssnittet och vi använder addEventHandler att lägga till den här hanteraren som ett PdfDocumentEvent till PdfDocument . I exemplet använder vi en END_PAGE händelse, men vi kunde också ha använt en START_PAGE händelse. Det spelar ingen roll mer om du lägger till innehåll i början eller i slutet. Du kan läsa mer om detta i Hantera händelser; ställa in visningspreferenser och författaregenskaper som är kapitel 7 i iText 7: Building Blocks- handledning.

Vi förbättrade byggstenarna i den meningen att vi gjorde dem mer hierarkiska (se Innan vi börjar: Översikt över klasser och gränssnitt som är introduktionen av iText 7: Building Blocks- tutorial). Vi introducerade också en uppsättning Renderer-klasser, en för varje byggsten, och vi tillåter utvecklare att anpassa dessa renderare så att en byggnadsblock visar ett annat beteende när de återges. Se exempelvis renderingsexemplet i Lägga till AbstractElement-objekt (del 1) som är kapitel 7 i iText 7: Building Blocks- handledning.

Dessa förändringar förenklar funktionaliteten för utvecklare som inte (vill) veta mycket om PDF och iText, samtidigt som de erbjuder en överflöd av flexibilitet för de utvecklare som inte är rädda för att gräva djupt i iText-koden för att skapa en PDF precis som de vill ha det.

Vill veta mer? Skaffa gratis e-bok!

Text2PdfPageEvents.java (iText 5)

Anta att vi har följande textfil: jekyll_hyde.txt

Hur konverterar vi den till en PDF som ser ut så här:

ange bildbeskrivning här

Notera den blå ramen som läggs till i titlarna och sidnumret längst ner på varje sida. I iText 5 läggs dessa element till med sidhändelser:

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

Vi kan återanvända koden för att konvertera en textfil till en PDF från exemplet Text2Pdf.java (iText 5) och introducera PdfWriter till 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();
}

Källa: utvecklare.itextpdf.com

Text2PdfPageEvents1.java (iText 7)

Anta att du har följande textfil: jekyll_hyde.txt

Hur konverterar vi den till en PDF som ser ut så här:

ange bildbeskrivning här

Notera sidnumren längst ner på varje sida. Dessa läggs till med en IEventHandler implementering:

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

Vi kan återanvända Text2Pdf.java-exemplet (iText 7) med bara två mindre ändringar:

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

Vi lägger till en händelsehanterare som utlöser handleEvent() i Footer klassen varje gång en sida slutar. Vi definierar också en gräns för Paragraph som används för en titel.

Källa: utvecklare.itextpdf.com och iText 7: Handledning för byggstenar .

Text2PdfPageEvents2.java

Anta att du har följande textfil: jekyll_hyde.txt

Hur konverterar vi den till en PDF som ser ut så här:

ange bildbeskrivning här

Observera att det här är mycket likt det vi hade tidigare, men titlarnas gräns har nu rundade hörn. Vi skapade en anpassad ParagraphRenderer att uppnå detta och vi skapade ett TitleParagraph objekt som använder renderaren:

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

Vår kod för att konvertera text till PDF är mycket enkel nu. Vi behöver inte längre ställa in teckensnittet för fetstil för titlarna och vi behöver inte längre definiera en gräns:

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

Källa: utvecklare.itextpdf.com och iText 7: Handledning för byggstenar .



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow