【问题标题】:PDFBox: Split PDF and add bookmarks IOExceptionPDFBox:拆分 PDF 并添加书签 IOException
【发布时间】:2017-07-27 10:54:29
【问题描述】:

在我的项目中,我通过书签拆分了一个 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();
}

堆栈跟踪:

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)

编辑: @此问题的以下所有读者:
解决问题后,我的程序没有按预期工作。 (每个书签都指向第一页。)但是这个问题不是这个问题的一部分。

【问题讨论】:

  • 我怀疑(只是快速浏览了一下)关闭addPagesToNewDocument() 为时过早。这也会关闭源文档中的资源。最好在全部保存后关闭。
  • @TilmanHausherr 你是对的,它现在可以工作了。谢谢!如果您将其发布为答案,我会接受并投票赞成:)
  • 警告加一!

标签: java pdf pdfbox


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 2011-02-05
    • 2016-05-13
    • 1970-01-01
    • 2020-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多