iText 9.0.0给PDF多页添加XObject时触发空指针异常求助
iText 9.0.0 添加XObject到多页PDF时崩溃问题
使用iText 9.0.0编写Java程序生成PDF,将外部PDF作为XObject添加到目标PDF每一页。当目标PDF页数为1或2时正常,页数≥3(比如把int n = 30;改成int n = 31;)时程序崩溃,抛出空指针异常。
代码示例
package net.opho; import com.itextpdf.kernel.geom.Rectangle; import com.itextpdf.kernel.pdf.PdfDocument; import com.itextpdf.kernel.pdf.PdfReader; import com.itextpdf.kernel.pdf.PdfWriter; import com.itextpdf.kernel.pdf.canvas.PdfCanvas; import com.itextpdf.kernel.pdf.xobject.PdfXObject; import com.itextpdf.layout.Document; import com.itextpdf.layout.element.Paragraph; public class Main { public static void main(String[] args) throws Exception { PdfDocument output = new PdfDocument(new PdfWriter("C:\\develop\\demo.pdf")); Document document = new Document(output); document.setTopMargin(120); Paragraph paragraph = (new Paragraph("Some texts...")).setFontSize(24); int n = 30; for (int i = 0; i < n; i++) { document.add(paragraph); } PdfDocument logoPdf = new PdfDocument(new PdfReader("C:\\develop\\OPhOLogo.pdf")); PdfXObject logoObject = logoPdf.getFirstPage().copyAsFormXObject(output); logoPdf.close(); Rectangle logoRectangle = PdfXObject.calculateProportionallyFitRectangleWithWidth(logoObject, 20, 750, 200); for (int i = 1; i <= output.getNumberOfPages(); i++) { PdfCanvas canvas = new PdfCanvas(output, i); canvas.addXObjectFittedIntoRectangle(logoObject, logoRectangle); } output.close(); } }
抛出的异常信息
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "java.util.Map.get(Object)" because "this.map" is null at com.itextpdf.kernel.pdf.PdfDictionary.get(PdfDictionary.java:471) at com.itextpdf.kernel.pdf.PdfDictionary.getAsNumber(PdfDictionary.java:184) at com.itextpdf.kernel.pdf.PdfPage.getRotation(PdfPage.java:151) at com.itextpdf.kernel.pdf.canvas.PdfCanvas.<init>(PdfCanvas.java:229) at com.itextpdf.kernel.pdf.canvas.PdfCanvas.<init>(PdfCanvas.java:271) at net.opho.Main.main(Main.java:25)
问题原因及解决方法
原因
通过Document添加内容生成多页PDF时,iText会延迟生成部分页面的底层PDF对象(页数较多时更明显),此时直接通过页码获取页面创建PdfCanvas,会遇到未完全初始化的页面,触发空指针异常。
解决方法
在操作页面之前,先调用document.close()强制完成所有页面的初始化,确保所有页面的PDF对象都已创建。修改后的代码如下:
package net.opho; import com.itextpdf.kernel.geom.Rectangle; import com.itextpdf.kernel.pdf.PdfDocument; import com.itextpdf.kernel.pdf.PdfReader; import com.itextpdf.kernel.pdf.PdfWriter; import com.itextpdf.kernel.pdf.canvas.PdfCanvas; import com.itextpdf.kernel.pdf.xobject.PdfXObject; import com.itextpdf.layout.Document; import com.itextpdf.layout.element.Paragraph; public class Main { public static void main(String[] args) throws Exception { PdfDocument output = new PdfDocument(new PdfWriter("C:\\develop\\demo.pdf")); Document document = new Document(output); document.setTopMargin(120); Paragraph paragraph = (new Paragraph("Some texts...")).setFontSize(24); int n = 31; for (int i = 0; i < n; i++) { document.add(paragraph); } // 关闭Document,强制完成所有页面初始化 document.close(); PdfDocument logoPdf = new PdfDocument(new PdfReader("C:\\develop\\OPhOLogo.pdf")); PdfXObject logoObject = logoPdf.getFirstPage().copyAsFormXObject(output); logoPdf.close(); Rectangle logoRectangle = PdfXObject.calculateProportionallyFitRectangleWithWidth(logoObject, 20, 750, 200); for (int i = 1; i <= output.getNumberOfPages(); i++) { PdfCanvas canvas = new PdfCanvas(output.getPage(i)); canvas.addXObjectFittedIntoRectangle(logoObject, logoRectangle); } output.close(); } }
关键修改点
- 添加完所有内容后调用
document.close(),确保所有页面完全生成并初始化。 - 创建
PdfCanvas时,改用output.getPage(i)获取已初始化的页面对象,避免直接通过页码构造时的潜在问题。
内容的提问来源于stack exchange,提问作者user27326776
相关产品推荐
相关产品推荐

