我有一个包含12页内容的PDF。我有另一个PDF(只有1页),这是图形模板。
PDF(内容和模板)都是 A4尺寸,水平方向。
对于内容PDF的每一页,我需要应用相同的模板,作为背景
这是我到目前为止编写的代码(我的代码started from here),但我无法检索模板页面并将其应用到每个页面。
public static void main(String[] args) throws IOException, DocumentException {
// PDF with contents (12 pages)
File pdfContent = new File("content.pdf");
// PDF with template (1 page only)
File pdfTemplate = new File("template.pdf");
// Where to save the output file
File output = new File("pdf_output.pdf");
if (output.exists()) {
output.delete();
}
// Opening reader on content PDF and creating stamper
PdfReader contentReader = new PdfReader(new FileInputStream(pdfContent));
PdfStamper stamper = new PdfStamper(contentReader, new FileOutputStream(output));
// Looping through pages
for (int i = 1; i <= contentReader.getNumberOfPages(); i++) {
// Retrieve content page where to apply template
PdfContentByte contentPage = stamper.getUnderContent(i);
// Opening template pdf
PdfReader templateReader = new PdfReader(new FileInputStream(pdfTemplate));
// Retrieve first page of template pdf (will be applied to content)
PdfImportedPage templatePage = stamper.getImportedPage(templateReader, 1);
// Apply template to PDF content
contentPage.addTemplate(templatePage, 0, 0);
// Closing reader
templateReader.close();
}
stamper.getWriter().freeReader(contentReader);
contentReader.close();
// FIXME calling it throws java.lang.IllegalStateException: Already closed
// stamper.close();
}
此代码有效,无任何错误结束,但生成的PDF已损坏且无法显示。
PdfStamper是获取我正在寻找的结果的正确方法吗?
如何正确使用库以获得结果?
编辑基于@mkl回复
// Opening reader on content PDF and creating stamper
PdfReader contentReader = new PdfReader(new FileInputStream(pdfContent));
PdfStamper stamper = new PdfStamper(contentReader, new FileOutputStream(output));
// Opening template pdf
PdfReader templateReader = new PdfReader(new FileInputStream(pdfTemplate));
PdfImportedPage templatePage = stamper.getImportedPage(templateReader, 1);
templateReader.close();
// Looping through pages
for (int i = 1; i <= contentReader.getNumberOfPages(); i++) {
// Retrieve content page where to apply template
PdfContentByte contentPage = stamper.getUnderContent(i);
// Apply template to PDF content
contentPage.addTemplate(templatePage, 0, 0);
}
stamper.close();
contentReader.close();
在此编辑中,我在最后使用stamper.close()
阅读了模板PDF e。
致电stamper.close()
时,我收到此异常
Exception in thread "main" java.lang.IllegalStateException: Already closed
at com.itextpdf.text.io.ArrayRandomAccessSource.get(ArrayRandomAccessSource.java:64)
at com.itextpdf.text.io.IndependentRandomAccessSource.get(IndependentRandomAccessSource.java:77)
at com.itextpdf.text.pdf.RandomAccessFileOrArray.read(RandomAccessFileOrArray.java:225)
at com.itextpdf.text.pdf.RandomAccessFileOrArray.readFully(RandomAccessFileOrArray.java:247)
at com.itextpdf.text.pdf.RandomAccessFileOrArray.readFully(RandomAccessFileOrArray.java:241)
at com.itextpdf.text.pdf.PdfReader.getStreamBytesRaw(PdfReader.java:2665)
at com.itextpdf.text.pdf.PdfReader.getStreamBytes(PdfReader.java:2631)
at com.itextpdf.text.pdf.PdfReader.getPageContent(PdfReader.java:2385)
at com.itextpdf.text.pdf.PdfReaderInstance.getFormXObject(PdfReaderInstance.java:125)
at com.itextpdf.text.pdf.PdfImportedPage.getFormXObject(PdfImportedPage.java:136)
at com.itextpdf.text.pdf.PdfReaderInstance.writeAllPages(PdfReaderInstance.java:172)
at com.itextpdf.text.pdf.PdfWriter.addSharedObjectsToBody(PdfWriter.java:1368)
at com.itextpdf.text.pdf.PdfStamperImp.close(PdfStamperImp.java:280)
at com.itextpdf.text.pdf.PdfStamper.close(PdfStamper.java:230)
答案 0 :(得分:1)
不要做
stamper.getWriter().freeReader(contentReader);
contentReader.close();
这将关闭压模所基于的压模以及压模在关闭时需要的信息。
但是
stamper.close();
在此期间,压模最终确定PDF文档,向其添加对象交叉引用信息。
此后你可以而且应该关闭读者
contentReader.close();
话虽如此,您只应导入模板页面一次,然后重复使用PdfImportedPage templatePage
。
编辑问题后:
请在关闭压模之前关闭模板pdf阅读器。即移动线
templateReader.close();
后
stamper.close();
答案 1 :(得分:0)
基于@mkl回复,这是工作结果
// Opening reader on content PDF and creating stamper
PdfReader contentReader = new PdfReader(new FileInputStream(pdfContent));
PdfStamper stamper = new PdfStamper(contentReader, new FileOutputStream(output));
// Opening template pdf
PdfReader templateReader = new PdfReader(new FileInputStream(pdfTemplate));
PdfImportedPage templatePage = stamper.getImportedPage(templateReader, 1);
// Looping through pages
for (int i = 1; i <= contentReader.getNumberOfPages(); i++) {
// Retrieve content page where to apply template
PdfContentByte contentPage = stamper.getUnderContent(i);
// Apply template to PDF content
contentPage.addTemplate(templatePage, -40, -40);
}
stamper.close();
templateReader.close();
contentReader.close();