首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在for循环中使用PdfStamper的最佳方法

在for循环中使用PdfStamper的最佳方法
EN

Stack Overflow用户
提问于 2015-11-07 12:54:16
回答 1查看 4K关注 0票数 1

我有下面的iText代码来读取文件并将其添加到主PDF文件中,因此它基本上是在现有的PDF页面中以绝对位置添加PDF页面。主PDF中的绝对位置和页码将动态确定。有时,它可能在第1页与100,100(x,y)或第2页与250,250(x,y)。我正在遍历每个对象代表PDF文件的PDF对象,然后我将应用业务逻辑将PDF对象转换为PDF文件,即srcPdf。现在,我需要在主PDF中的绝对位置添加这个srcPdf (这里是pdfStamper ):

代码语言:javascript
复制
for(ListOfPdfObject pdfObj: ListOfPdfObjects) {
    // code to create srcPdf so there will be new srcPdf for each iteration. srcPdf is flattened pdf of acro form field pdf.
    PdfReader reader2 = new PdfReader(srcPdf.getAbsolutePath());
    PdfImportedPage page = pdfStamper.getImportedPage(reader2, 1);
    pdfStamper.insertPage(1, reader2.getPageSize(1));
    pdfStamper.getUnderContent(1).addTemplate(page, 100, 100);
    pdfStamper.close(); // problem is here
    reader2.close();
}

这里,pdfStamper是在for-loop之外创建的,如下所示:

代码语言:javascript
复制
PdfReader pdfReader = new PdfReader(new FileInputStream(tempPdf));
PdfStamper pdfStamper = new PdfStamper(pdfReader, new FileOutputStream(destPdf));

问题是,如果我在pdfStamper之后关闭for-loop,它会引发RandomAccessSource not opened异常。如果在for循环内部关闭,则必须在for-loop中再次创建。请你指出正确的方向好吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-11-07 13:20:30

正如我在对摘录pdf页并插入现有pdf的答复中所解释的那样,使用PdfStamper只是满足您需求的一种方法。如果您需要操作单个PDF文档,那么PdfStamper可能是您的最佳选择,并且可以从另一个PDF文档中添加一个页面,正如我先前的回答所演示的那样。

但是,您现在表示必须连接多个PDF文件。在这种情况下,使用PdfStamper并不是最好的选择。您应该考虑切换到PdfCopy

假设您有以下文件。

代码语言:javascript
复制
String[] paths = new String[]{
    "resources/to_be_inserted_1.pdf",
    "resources/to_be_inserted_2.pdf",
    "resources/to_be_inserted_3.pdf"
};

您需要在使用路径"resources/main_document.pdf"的现有PDF文件的开头插入每个文档的第一页(仅是第一页),然后您可以这样做:

代码语言:javascript
复制
Document document = new Document();
PdfCopy copy = new PdfCopy(document, new FileOutputStream(dest));
document.open();
PdfReader reader;
for (String path : paths) {
    reader = new PdfReader(path);
    copy.addPage(copy.getImportedPage(reader, 1));
    reader.close();
}
reader = new PdfReader("resources/main_document.pdf");
copy.addDocument(reader);
reader.close();
document.close();

如您所见,addPage()方法添加一个页面,而addDocument()方法则添加文档的所有页面。

更新

似乎您不想插入新的页面,而是希望将页面叠加起来:您希望在现有内容的基础上或下面添加页面。

在这种情况下,您确实需要PdfStamper,但是您正在犯两个关键错误。

  1. 关闭循环中的stamper。一旦stamper关闭,它就关闭了:您不能再向它添加任何内容了。您需要将stamper.close()移出循环之外。
  2. 在循环中关闭reader,但stamper尚未释放reader。你应该先解放读者。

SuperImpose示例中显示了这一点:

代码语言:javascript
复制
public static final String SRC = "resources/pdfs/primes.pdf";
public static final String[] EXTRA =
    {"resources/pdfs/hello.pdf", "resources/pdfs/base_url.pdf", "resources/pdfs/state.pdf"};
public static final String DEST = "results/stamper/primes_superimpose.pdf";

PdfReader reader = new PdfReader(SRC);
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(DEST));
PdfContentByte canvas = stamper.getUnderContent(1);
PdfReader r;
PdfImportedPage page;
for (String path : EXTRA) {
    r = new PdfReader(path);
    page = stamper.getImportedPage(r, 1);
    canvas.addTemplate(page, 0, 0);
    stamper.getWriter().freeReader(r);
    r.close();
}
stamper.close();

在这种情况下,我总是将导入的页面添加到主文档的第1页。如果要将导入的页面添加到不同的页面,则需要在循环中创建canvas对象。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33582996

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档