Java PDFBox:拆分PDF并添加书签

Java PDFBox:拆分PDF并添加书签,java,pdf,pdfbox,Java,Pdf,Pdfbox,在我的项目中,我用书签分割了一个pdf文件。应创建一个新的pdf文件,其中包含拆分的页面和一些新书签 这会导致以下异常: 线程“main”java.io.IOException中的异常:CoStream已关闭,无法读取。可能其随附文档已关闭? 如果我删除行outline.addLast(pagesOutline)新pdf包含拆分的页面(没有例外),但显然不包含书签。我认为我尝试添加书签的方式有问题 我的代码: private void tryCreatePDF(List<String>

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

这会导致以下异常:
线程“main”java.io.IOException中的异常:CoStream已关闭,无法读取。可能其随附文档已关闭?

如果我删除行
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();
}
private void tryCreatePDF(图书标记列表)引发IOException
{
document=PDDocument.load(新文件(“C:/Users/me/Desktop/existingpdf.pdf”);
PDDocumentCatalog=document.getDocumentCatalog();
PDDocumentOutline书签ExistingFile=catalog.getDocumentOutline();
destinationPDF=新的PDDocument();
outline=新的PDDocumentOutline();
destinationPDF.getDocumentCatalog().setDocumentOutline(大纲);
pagesOutline=新的PDOutlineItem();
setTitle(“第一个书签”);
outline.addLast(pagesOutline);
for(字符串bookmarkToSplit:listOfBookmarks)
{
将页面从现有文件添加到EWPDF(书签现有文件,书签拆分);
}
createNewPDF();
}
私有void addPagesFromExistingFileToNewPDF(PDOutlineNode outlineNodeFromExistingPDF,String bookmarkToSplit)引发IOException
{
PDOutlineItem current=outlineNodeFromExistingPDF.getFirstChild();
while(当前!=null)
{
PDPage currentPage=当前.findDestinationPage(文档);
整数pageNumber=document.getDocumentCatalog().getPages().indexOf(currentPage)+1;
将现有文件添加到EWPDF(当前,书签到拆分);
String bookmark=current.getTitle().trim();
if(bookmark.matches(bookmarkToSplit+“\\s.+”))
{
拆分器拆分器=新拆分器();
拆分器。设置起始页(页码);
splitter.setEndPage(页码);
列表页=拆分器。拆分(文档);
addPagesToNewDocument(页);
}
current=current.getNextSibling();
}
}
私有void addPagesToNewDocument(列表页)引发IOException
{
PDFMergerUtility PDFMergerUtility=新的PDFMergerUtility();
对于(int index=0;index
堆栈跟踪:

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)
线程“main”java.io.IOException中的异常:CoStream已关闭,无法读取。也许它的附件已经关闭了? 位于org.apache.pdfbox.cos.costream.checkClosed(costream.java:77) 位于org.apache.pdfbox.cos.costream.createRawInputStream(costream.java:125) 位于org.apache.pdfbox.pdfwriter.COSWriter.visitFromStream(COSWriter.java:1203) 位于org.apache.pdfbox.cos.costream.accept(costream.java:383) 位于org.apache.pdfbox.pdfwriter.COSWriter.doWriteObject(COSWriter.java:522) 位于org.apache.pdfbox.pdfwriter.COSWriter.doWriteObjects(COSWriter.java:460) 位于org.apache.pdfbox.pdfwriter.COSWriter.doWriteBody(COSWriter.java:444) 位于org.apache.pdfbox.pdfwriter.COSWriter.visitFromDocument(COSWriter.java:1099) 位于org.apache.pdfbox.cos.COSDocument.accept(COSDocument.java:419) 位于org.apache.pdfbox.pdfwriter.COSWriter.write(COSWriter.java:1370) 位于org.apache.pdfbox.pdfwriter.COSWriter.write(COSWriter.java:1257) 位于org.apache.pdfbox.pdmodel.PDDocument.save(PDDocument.java:1267) 位于org.apache.pdfbox.pdmodel.PDDocument.save(PDDocument.java:1238) 位于askstackoverflow.SplitPDFByBookmarks.createNewPDF(SplitPDFByBookmarks.java:126) 位于askstackoverflow.SplitPDFByBookmarks.tryCreatePDF(SplitPDFByBookmarks.java:55) 在askstackoverflow.SplitPDFByBookmarks。(SplitPDFByBookmarks.java:33) 位于askstackoverflow.Main.Main(Main.java:9)
编辑: @本问题的以下所有读者:

解决问题后,我的程序没有按我预期的那样工作。(每个书签都指向第一页。)但这个问题不属于这个问题。

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

我怀疑(只是很快看了一眼)关闭
addPagesToNewDocument()
太早了。这还会关闭源文档中的资源。最好在所有的东西都保存好后再关上。@tilmahauser你说得对,它现在起作用了。谢谢如果你把它作为一个答案贴出来,我会接受并投赞成票:)警告加1!