You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 07:21:20