简体   繁体   中英

Collapse Bookmarks using PYPDF2

When I use PYPDF2 to merge two PDF documents, I set the Page Mode to /UseOutlines so that the PDF will display the bookmark pane when the document is opened.

merger = PdfFileMerger()
merger.append(PdfFileReader(filename,'rb'),import_bookmarks=True)
merger.setPageMode('/UseOutlines')
merger.setPageLayout('/SinglePage')

However, whenever the PDF document is opened the bookmarks are always expanded. Is there a property that I can modify to force the bookmarks to be collapsed when the document is opened?

Quite late but after a bit of digging and with the hint of @Eugene I found a solution.

You have to do small adjustments on the source code: (Tested for version 1.26.0)

PyPDF2/pdf.py:

Change the definition of the method addBookmark (~ line 690) to:

def addBookmark(self, title, pagenum, parent=None, color=None, bold=False, italic=False, fit='/Fit', collapse=False, *args):

(add the parameter collapse=False )

Then at the end of the same method change the line (~ line 750) to:

parent.addChild(bookmarkRef, self, collapse)

(add collapse )

PyPDF2/generic.py

Now we have to adjust the addChild method (~ line 665):

def addChild(self, child, pdf, collapse=False):

(again add the parameter collapse=False )

Then exchange the line (~ line 677) in the same method:

self[NameObject('/Count')] = NumberObject(self[NameObject('/Count')] + 1)

with

if collapse: self[NameObject('/Count')] = NumberObject(self[NameObject('/Count')] - 1)
else: self[NameObject('/Count')] = NumberObject(self[NameObject('/Count')] + 1)

That's it!

Usage

If you now call the method 'addBookmark()' with parameter 'collapse=True' all bookmarks are closed.

An open outline in PDF contains the /Count key in the dictionary indicating the number of children inside the outline. To display an outline as closed it should have this key removed or set to -1 . But unfortunately no way to specify it in PyPDF2 yet.

this is possible without changing the PyPDF2 source code:

from PyPDF2 import generic

def compressPicklist(mypdf, baseref=None):
    ## sets /Count to zero to compress bookmark picklist
    parent = baseref;
    if baseref == None: parent = mypdf.getOutlineRoot()
    parent = parent.getObject()
    parent[generic.NameObject('/Count')] = generic.NumberObject(0)

# call compressPickList after every call to addBookMark  
pdf_writer.addBookmark(item.title,n2,baseref)
compressPicklist(pdf_writer,baseref)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM