'Change order of pdf bookmarks using PyPdf2
I create an application, that merges multiple pdfs with a bookmark. If the origin pdfs already have bookmarks, I want to keep them and just add a bookmark at the beginning of the pdf. I use the following code: The title and the path in the code come from user input.
from PyPDF2 import PdfFileReader, PdfFileMerger
from PyPDF2.utils import PdfReadError
merger = PdfFileMerger()
pages_total = 0
for path, title in zip(paths, titles):
merger.append(path, import_bookmarks=True)
with open(path, "rb") as file:
pdf = PdfFileReader(file, "rb")
pages_one = pdf.getNumPages()
pages_total += pages_one
merger.addBookmark(f"{title}", pages_total - pages_one, parent=None)
save_path = input() + ".pdf"
merger.write(save_path)
merger.close()
The new pdf has all bookmarks, that points to the right pages. However, that bookmark for the entire pdf appears after the pdfs that already existed. How can I change the order in which the bookmarks are displayed?
The picture below hopefully clarifies the problem. The last bookmark was added and should be the first in the list.
Solution 1:[1]
I found a solution. First I create a parent bookmark with the the pdf title. Then I get all existing bookmarks in the pdf with pdf.getOutlines() and iterate over the output:
parent = merger.addBookmark(f"{title}", pages_total - pages_one, parent=None)
for i in pdf.getOutlines():
if isinstance(i, list): # if nested bookmarks exists
nested_boomarks(parent=child, bookmarks=i, merger=merger, pdf=pdf)
else:
child = merger.addBookmark(i["/Title"], pdf.getDestinationPageNumber(i), parent=parent)
When there are bookmarks inside the bookmarks I use this recursive function.
def nested_boomarks(parent, bookmarks, merger, pdf):
for i in bookmarks:
if isinstance(i, list):
nested_boomarks(child, i, merger, pdf)
else:
child = merger.addBookmark(i["/Title"], pdf.getDestinationPageNumber(i), parent=parent)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Mazze |


