java - 我尝试使用 itext7 与 eclipse 生成 pdf 文件。但是当我在其上添加页面时,它将输出错误“java.lang.NullPointerException”

标签 java itext7

itext7版本是7.1.3,生成pdf文件是正确的,但是当我向pdf文件添加页面且总页数超过4页时,会产生错误:

Exception in thread "main" java.lang.NullPointerException

我不明白为什么 4 以下的所有页面结果都是正确的,而 4 以上的页面则不能产生正确的结果。 jdk版本为1.8。

我的项目有什么问题吗?

这是我的代码:

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

}

错误消息如下:

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)

这是我导入的 jar:

enter image description here

最佳答案

我不完全确定问题的确切原因是什么,但在调用 page.getPageSize() 方法之前关闭文档可以解决问题。 很可能在您调用 document.close() 方法之前,某些属性不会被写掉。

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

需要注意的重要一点是,如果您想重用 PdfFont 对象,则必须重新创建它。否则 iText 将无法将字体数据刷新到 Pdf 文档。

您还可以通过在文档上禁用 immediateFlush 并使用简单的方法来实现“第 x 页,共 y 页”用例,而根本不需要 page.getPageSize() 方法for 循环如下 iText Example 。这样您就不需要关闭并重新打开文档。

您可以通过以下方式完成此操作: 我们告诉文档不应立即刷新其内容。

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

添加所有内容后,我们循环遍历文档中的每个页面,并向每个页面添加一个段落

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

(我提供的链接中有完整的示例)

亲切的问候, 凯文

关于java - 我尝试使用 itext7 与 eclipse 生成 pdf 文件。但是当我在其上添加页面时,它将输出错误“java.lang.NullPointerException”,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52333159/

相关文章:

c# - 多重签名不起作用

java - 使用 iText java 创建的带有水印图像的 PDF 文件

java - 访问 fragment View 时偶尔出现 NPE

Java Socket 发送多个文件但收到单个文件?

java - 将按钮与框组件对齐

java - 使用 iText 7.1 从 PDF 中删除链接

java - Apache Httpclient 中止请求导致错误

java - 我是否必须避免使用 Spring Data 的 native sql?

c# - 使用带有 C# 的 itext7 通过 acrofield 获取 pdf 页码

java - 带有 iText 7 的 PDF 中的希腊字符