我正在尝试从字节数组中复制pdf,并使用包含单个页面的pdf标记每个页面。每当我尝试复制pdf并盖章每页时,我都会得到异常iText'java.io.IOException该文档没有页面'
这是我的代码:
public static ByteArrayOutputStream AddPageTemplate(ByteArrayOutputStream baos){
Document document = getDocument();
ByteArrayOutputStream copyWithTemplateAdded = new ByteArrayOutputStream();
try {
PdfCopy copy = new PdfCopy(document, copyWithTemplateAdded);
PdfWriter writer = PdfWriter.getInstance(document, copyWithTemplateAdded);
PdfReader templateReader = new PdfReader(PAGE_TEMPLATE.getInputStream());
PdfImportedPage templatePage = writer.getImportedPage(templateReader, 1);
document.open();
baos.flush();
PdfReader reader = new PdfReader(baos.toByteArray());
int n1 = reader.getNumberOfPages();
PdfImportedPage page;
PdfCopy.PageStamp stamp;
for (int i = 1; i <= n1; ++i) {
page = copy.getImportedPage(reader, i);
stamp = copy.createPageStamp(page);
stamp.getUnderContent().addTemplate(templatePage, 0, 0);
stamp.alterContents();
copy.addPage(page);
}
copyWithTemplateAdded.close();
reader.close();
copy.close();
templateReader.close();
document.close();
}
catch(DocumentException p){
//todo log error
}
catch (IOException e) {
//todo log error
}
return copyWithTemplateAdded;
}
解决此问题的任何帮助都会很棒。我使用的是itextpdf 5.3.4
答案 0 :(得分:2)
您在很短的代码段中犯了很多不同的错误。
导致错误的一个错误是:您将copyWithTemplateAdded
创建为ByteArrayOutputStream
,并为两位作者使用相同的OutputStream
:
PdfCopy copy = new PdfCopy(document, copyWithTemplateAdded);
PdfWriter writer = PdfWriter.getInstance(document, copyWithTemplateAdded);
这永远不会奏效:
PdfCopy
会将字节写入OutputStream
,目的是将现有PDF 复制到新PDF。PdfWriter
会将字节写入相同的 OutputStream
,目的是从头开始创建新PDF 。结果将是完全损坏的PDF,因为:
PdfWriter
与PdfCopy
混合在一起OutputStream
(想想The Fly中的Jeff Goldblum,以了解期待的内容)。 PdfWriter
获取导入的页面(意味着所需的所有引用都将存储在writer
对象中),但您使用PdfCopy
实例中的导入页面(但是copy
没有对该页面所需资源的任何引用。) IOException
是writer
对象已关闭(document.close()
后)并且未添加任何内容的原因:所有内容都已添加到copy
对象
另一个错误:在关闭copy
之前关闭document
实例。
但最大的错误是您使用PdfCopy
(以及PdfWriter
)来处理可能应该使用PdfStamper
的内容。
您从哪里获得代码的灵感?你可以帮我一个忙,然后下载Chapter 6 of my book并查看StampStationery示例吗?
public void manipulatePdf(String src, String stationery, String dest)
throws IOException, DocumentException {
// Create readers
PdfReader reader = new PdfReader(src);
PdfReader s_reader = new PdfReader(stationery);
// Create the stamper
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
// Add the stationery to each page
PdfImportedPage page = stamper.getImportedPage(s_reader, 1);
int n = reader.getNumberOfPages();
PdfContentByte background;
for (int i = 1; i <= n; i++) {
background = stamper.getUnderContent(i);
background.addTemplate(page, 0, 0);
}
// CLose the stamper
stamper.close();
reader.close();
s_reader.close();
}
在此示例中,我们有一个现有的PDF文件(其路径为src
)以及我们要添加为每个页面背景的模板(模板的路径为stationery
) 。我们创建一个PdfStamper
对象,它将根据现有的PDF文档创建一个新文件(新文件的路径为dest
)。
我们将模板的第一页加载到PdfImportedPage
(page
对象)中。我们遍历每个页面,然后在后台添加page
。此代码直接来自文档,比您编写的内容更容易理解。