如何用PyPDF2排序PDF书签 修复排序后书签不可点击问题
PyPDF2排序书签后无法跳转修复
问题表现
代码运行后可生成带排序后书签的新PDF,但书签点击无反应,在Adobe Acrobat Reader中查看书签属性,可见动作值为null。
问题根因
- 代码中调用
sorted()对书签字典排序后没有接收返回值,排序逻辑实际未生效——sorted()是返回新排序列表,不会修改原对象。 - 直接把
PdfReader读取到的原书签目标对象通过add_bookmark_dict添加到PdfWriter时,对象内部关联的是原读取器的页面对象引用,和写入器中新增的页面没有建立映射,导致书签跳转目标丢失。
修复代码
import PyPDF2 from PyPDF2 import PdfReader, PdfWriter reader = PdfReader("/Users/ME/Documents/in.pdf") writer = PdfWriter() level1_bookmarks = [] # 提取所有一级书签(跳过嵌套子书签) for item in reader.outlines: if isinstance(item, PyPDF2.generic.Destination): level1_bookmarks.append(item) # 按书签标题排序,必须接收sorted返回值 sorted_bookmarks = sorted(level1_bookmarks, key=lambda x: x['/Title']) # 写入所有页面 for page in reader.pages: writer.add_page(page) # 逐个重新创建书签,绑定到写入器内的对应页面 for bm in sorted_bookmarks: # 获取书签对应的页码 page_index = reader.get_destination_page_number(bm) # 适配原书签的跳转位置、缩放参数 fit_type = bm.get('/Fit', '/FitH') pos_args = [] for key in ['/Left', '/Top', '/Zoom']: if key in bm: pos_args.append(bm[key]) # 调用add_bookmark创建绑定正确页面的新书签 writer.add_bookmark( title=bm['/Title'], pagenum=page_index, fit=fit_type, *pos_args ) # 输出文件 with open('/Users/ME/Documents/out.pdf', 'wb') as f: writer.write(f)
扩展说明
如果PDF存在多级嵌套书签,只需要递归遍历reader.outlines的嵌套列表结构,添加子书签时把父书签对象传入add_bookmark的parent参数,即可保留原书签层级。
内容的提问来源于stack exchange,提问作者mellow-yellow
相关产品推荐
相关产品推荐

