当前位置: 首页 > 知识库问答 >
问题:

PDFBOX:拆分PDF并添加书签IOException

松雅昶
2023-03-14

在我的项目中,我按书签拆分了一个pdf文件。应该创建一个新的pdf文件,其中包含拆分的页面和一些新的书签。

这将导致以下异常:
线程“main”java.io.ioException中的异常:COSStream已关闭,无法读取。也许它所附的PDDocument已经关闭了?

如果删除outline.addlast(pagesOutline);行,则新的pdf包含拆分的页面(没有例外),但显然不包含书签。我想我尝试添加书签的方式有问题。

我的代码:

private void tryCreatePDF(List<String> listOfBookmarks) throws IOException
{
    document = PDDocument.load(new File("C:/Users/me/Desktop/existingpdf.pdf"));
    PDDocumentCatalog catalog = document.getDocumentCatalog();
    PDDocumentOutline bookmarksInExistingFile = catalog.getDocumentOutline();

    destinationPDF = new PDDocument();
    outline = new PDDocumentOutline();
    destinationPDF.getDocumentCatalog().setDocumentOutline(outline);

    pagesOutline = new PDOutlineItem();
    pagesOutline.setTitle("First Bookmark");
    outline.addLast(pagesOutline);

    for(String bookmarkToSplit : listOfBookmarks)
    {
        addPagesFromExistingFileToNewPDF(bookmarksInExistingFile, bookmarkToSplit);
    }

    createNewPDF();
}

private void addPagesFromExistingFileToNewPDF(PDOutlineNode outlineNodeFromExistingPDF, String bookmarkToSplit) throws IOException
{
    PDOutlineItem current = outlineNodeFromExistingPDF.getFirstChild();

    while(current != null)
    {
        PDPage currentPage = current.findDestinationPage(document);
        Integer pageNumber = document.getDocumentCatalog().getPages().indexOf(currentPage) + 1;

        addPagesFromExistingFileToNewPDF(current, bookmarkToSplit);

        String bookmark = current.getTitle().trim();

        if(bookmark.matches(bookmarkToSplit + "\\s.+"))
        {
            Splitter splitter = new Splitter();

            splitter.setStartPage(pageNumber);
            splitter.setEndPage(pageNumber);

            List<PDDocument> pages = splitter.split(document);

            addPagesToNewDocument(pages);
        }

        current = current.getNextSibling();
    }
}

private void addPagesToNewDocument(List<PDDocument> pages) throws IOException
{
    PDFMergerUtility pdfMergerUtility = new PDFMergerUtility();

    for(int index = 0; index < pages.size(); index++)
    {
        PDDocument doc = pages.get(index);

        pdfMergerUtility.appendDocument(destinationPDF, doc);

        if(index == 0)
        {
            addNewBookmarkToNewPDF(doc);
        }

        doc.close();
    }
}

private void addNewBookmarkToNewPDF(PDDocument doc)
{
    PDPageFitWidthDestination dest = new PDPageFitWidthDestination();
    dest.setPage(doc.getPage(0));

    PDOutlineItem bookmark = new PDOutlineItem();
    bookmark.setDestination(dest);
    bookmark.setTitle("Child Bookmark");

    pagesOutline.addLast(bookmark);
}

private void createNewPDF() throws IOException
{
    File targetFile = new File("C:/Users/me/Desktop/newpdf.pdf");

    pagesOutline.openNode();
    outline.openNode();

    destinationPDF.save(targetFile);
    destinationPDF.close();

    document.close();
}

StackTrace:

Exception in thread "main" java.io.IOException: COSStream has been closed and cannot be read. Perhaps its enclosing PDDocument has been closed?
    at org.apache.pdfbox.cos.COSStream.checkClosed(COSStream.java:77)
    at org.apache.pdfbox.cos.COSStream.createRawInputStream(COSStream.java:125)
    at org.apache.pdfbox.pdfwriter.COSWriter.visitFromStream(COSWriter.java:1203)
    at org.apache.pdfbox.cos.COSStream.accept(COSStream.java:383)
    at org.apache.pdfbox.pdfwriter.COSWriter.doWriteObject(COSWriter.java:522)
    at org.apache.pdfbox.pdfwriter.COSWriter.doWriteObjects(COSWriter.java:460)
    at org.apache.pdfbox.pdfwriter.COSWriter.doWriteBody(COSWriter.java:444)
    at org.apache.pdfbox.pdfwriter.COSWriter.visitFromDocument(COSWriter.java:1099)
    at org.apache.pdfbox.cos.COSDocument.accept(COSDocument.java:419)
    at org.apache.pdfbox.pdfwriter.COSWriter.write(COSWriter.java:1370)
    at org.apache.pdfbox.pdfwriter.COSWriter.write(COSWriter.java:1257)
    at org.apache.pdfbox.pdmodel.PDDocument.save(PDDocument.java:1267)
    at org.apache.pdfbox.pdmodel.PDDocument.save(PDDocument.java:1238)
    at askstackoverflow.SplitPDFByBookmarks.createNewPDF(SplitPDFByBookmarks.java:126)
    at askstackoverflow.SplitPDFByBookmarks.tryCreatePDF(SplitPDFByBookmarks.java:55)
    at askstackoverflow.SplitPDFByBookmarks.<init>(SplitPDFByBookmarks.java:33)
    at askstackoverflow.Main.main(Main.java:9)

共有1个答案

丘学海
2023-03-14

AddPageStoneWDocument()中关闭太早。这还会关闭源文档中的资源,因为这些资源被两者使用。最好在保存所有文档后才开始关闭。

 类似资料:
  • 问题内容: 如何使用iText将书签添加到现有PDF? 我将多个PDF合并为一个PDF,并且需要为最终PDF构建书签。例如,我有三个PDF:doc1.pdf,doc2.pdf和doc3.pdf,doc1和doc2属于Group1,doc3属于Group2。我需要合并它们,并且必须为生成的PDF构建嵌套书签,如下所示: 等等 问题答案: 我已经制作了一个MergeWithOutlines示例,该示例

  • 问题内容: 我正在使用Apache PDFBox处理Java应用程序中的PDF文件。我想在每个页面上分割一个PDF文档。 是否有可能做到这一点Apache PDFBox?如果是这样,怎么办? 问题答案: 可以使用来实现。 这是一个示例代码,它将在每个页面上拆分文档: 您可以使用来控制每个拆分的PDF的页数。

  • 我想问一个问题,如果我想在多页pdf中添加数字签名,每页都有相同的印章,我是否可以在第一页只添加一次数字签名,然后其他页面只需要引用第一个印章的外观。因为使用这种方法可以减少添加邮票的时间。 我使用了mkl给出的代码,但我有一个问题。我用其他代码替换了以下代码。 原件: 现在: 原始代码在加盖印花时有效,但修改后的代码将使印花无效。我使用Adobe Acrobat Pro DC打开已签名的文档。此

  • 主要内容:Eclipse 书签是什么,添加书签,打开书签视图,使用书签视图Eclipse 书签是什么 Eclipse 编辑器允许您在编辑器内的任何行上放置书签。您可以使用书签作为提醒并快速导航到文件中的任何行。 添加书签 要设置书签,请右键单击要放置书签的行附近的垂直标尺,然后选择添加书签。在添加书签对话框中输入书签的名称。 点击“Add Bookmark” 签图标出现在垂直标尺中。此外,在书签视图中的表中添加了一行。 打开书签视图 打开书签视图 : 单击“Window

  • 关于书签 Eclipse 中可以在编辑器的任意一行添加书签。 您可以使用书签作为提示信息,或者使用书签快速定位到文件中的指定的行。 添加书签 如果你想设置书签,你只需要在垂直标尺上右击鼠标并选择能 "Add Bookmark" 即可。 在弹出的对话框中输入书签名。 垂直标尺上就会出现一个书签的按钮,当然你也可以在 Bookmarks 视图中查看到书签列表。 打开 Bookmarks(书签) 视图