简体   繁体   中英

I try to use itext7 to produce a pdf file with eclipse.but when I add the pages on it ,it will output a error"java.lang.NullPointerException"

The itext7 version is 7.1.3 and producing pdf files is correct, but when I add pages to the pdf file and the total pages is over 4 pages, it'll produce error:

Exception in thread "main" java.lang.NullPointerException

I don't comprehend why the all pages below 4 the outcome is correct whereas over 4 it can't produce the right result. The jdk version is 1.8.

Is there any wrong in my project?

Here is my code:

import java.io.FileNotFoundException;
import java.io.IOException;

import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.geom.PageSize;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfPage;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.property.TextAlignment;

public class Test {
    private static TextAlignment alignment;
    public static void main(String[] args) throws IOException {
        // TODO Auto-generated method stub
        String dest = "C:\\Users\\wsco\\Desktop\\pdfDemo.pdf";
        PdfDocument pdfDoc =new PdfDocument(new PdfWriter(dest));
        Document document = new Document(pdfDoc,PageSize.A4);
        PdfFont f1 = PdfFontFactory.createFont("STSong-Light","UniGB-UCS2-H",true); 
        for(int i =1;i<100;i++) {
            document.add(new Paragraph(i+"line").setFont(f1).setFontSize(20).setTextAlignment(alignment.LEFT));
        }
        int n = pdfDoc.getNumberOfPages();
        System.out.println("total:"+n+"page");
        Rectangle pageSize ;
        PdfCanvas canvas;
        for(int i = 3;i<=n;i++) {
            PdfPage page = pdfDoc.getPage(i);
            pageSize = page.getPageSize();
            canvas = new PdfCanvas(page);
            canvas.beginText().setFontAndSize(f1, 12)
            .moveText(pageSize.getWidth()/2-7, 10)
            .showText(String.valueOf(i-2))
            .showText("/")
            .showText(String.valueOf(n-2))
            .endText();
        }

        pdfDoc.close();
        System.out.println("successfully");
    }

}

Here's the error message:

total:6page
Exception in thread "main" java.lang.NullPointerException
    at com.itextpdf.kernel.pdf.PdfDictionary.get(PdfDictionary.java:456)
    at com.itextpdf.kernel.pdf.PdfDictionary.getAsArray(PdfDictionary.java:156)
    at com.itextpdf.kernel.pdf.PdfPage.getMediaBox(PdfPage.java:516)
    at com.itextpdf.kernel.pdf.PdfPage.getPageSize(PdfPage.java:125)
    at Test.main(Test.java:33)

Here's my jar that I import:

在此处输入图片说明

I'm not completely sure what the exact cause of the issue is but closing the document before calling the page.getPageSize() method resolves the issue. Most likely some properties are not written away until you call the document.close() method.

public static void main(String[] args) throws IOException {
    PdfDocument pdfDoc = new PdfDocument(new PdfWriter(SRC));
    Document document = new Document(pdfDoc, PageSize.A4);
    PdfFont f1 = PdfFontFactory.createFont(StandardFonts.HELVETICA);

    for (int i = 1; i < 100; i++) {
        document.add(new Paragraph(i + "line").setFont(f1).setFontSize(20).setTextAlignment(alignment.LEFT));
    }

    pdfDoc.close();
    pdfDoc = new PdfDocument(new PdfReader(SRC), new PdfWriter(DEST));

    int n = pdfDoc.getNumberOfPages();
    System.out.println("total:" + n + "page");
    Rectangle pageSize;
    PdfCanvas canvas;
    f1 = PdfFontFactory.createFont(StandardFonts.HELVETICA);

    for (int i = 3; i <= n; i++) {
        PdfPage page = pdfDoc.getPage(i);
        pageSize = page.getPageSize();
        canvas = new PdfCanvas(page);
        canvas.beginText().setFontAndSize(f1, 12)
                .moveText(pageSize.getWidth() / 2 - 7, 10)
                .showText(String.valueOf(i - 2))
                .showText("/")
                .showText(String.valueOf(n - 2))
                .endText();
    }

    pdfDoc.close();
    System.out.println("successfully");
}

An important thing to notice is that you will have to recreate your PdfFont Object if you wish to reuse it. Otherwise iText will be unable to flush the font data to the Pdf Document.

You could also approach this 'page x of y' usecase without needing the page.getPageSize() method at all by disabling immediateFlush on your Document and using a simple for loop as in this iText Example . This way you will not need to close and reopen your document.

You can accomplish this in the following way: We tell the Document that is shouldn't flush its content immediately.

Document document = new Document(pdf, PageSize.A4, false);

After adding all of the content we loop over every page in the document and we add a Paragraph to each page.

    int n = pdf.getNumberOfPages();
    Paragraph footer;
    for (int page = 1; page <= n; page++) {
        footer = new Paragraph(String.format("Page %s of %s", page, n));
        document.showTextAligned(footer, 297.5f, 20, page, TextAlignment.CENTER, VerticalAlignment.MIDDLE, 0);
    }

(A complete example is present in the link I provided)

Kind regards, Kevin

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM