我的知识记录

Python PDF提取目录书签 大纲导出教程

用Python读取PDF内置书签/大纲(Outlines),提取章节名和对应页码,导出为Excel或TXT,方便做索引目录。

场景痛点

很多PDF(尤其是电子书、合同、规范)自带左侧书签目录,但想把这份目录导出到Excel里做索引、转成Markdown目录、或者给飞书文档当锚点,手动一条条复制太慢。用Python直接读取PDF的Outlines对象,把章节名+页码一次性导出成表格,几秒钟搞定。

用到的库

pip install PyPDF2

完整代码

# -*- coding: utf-8 -*-
"""
提取 PDF 的书签(大纲)结构,导出为 txt / Excel
"""
from PyPDF2 import PdfReader
import pandas as pd


def _walk_outlines(outlines, reader, level=1, result=None):
"""
递归遍历书签树,把层级、标题、页码拍平成一行一条
"""
if result is None:
result = []

for item in outlines:
# 子书签是嵌套列表
if isinstance(item, list):
_walk_outlines(item, reader, level + 1, result)
else:
# item 是 Destination 对象,title 是标题,page 是页面对象
title = item.title
try:
# get_destination_page_number 返回 0 基页码
page_no = reader.get_destination_page_number(item) + 1
except Exception:
page_no = None
result.append({"层级": level, "标题": title, "页码": page_no})
return result


def extract_bookmarks(pdf_path: str, out_excel: str = None) -> list:
"""
提取 PDF 书签
"""
reader = PdfReader(pdf_path)
# outlines 是书签树根节点,可能是嵌套列表
outlines = reader.outline

rows = _walk_outlines(outlines, reader)
print(f"共提取 {len(rows)} 个书签")

for row in rows:
indent = "  " * (row["层级"] - 1)
print(f"{indent}[P{row['页码']}] {row['标题']}")

if out_excel:
df = pd.DataFrame(rows)
df.to_excel(out_excel, index=False)
print(f"已导出 Excel: {out_excel}")

return rows


if __name__ == "__main__":
extract_bookmarks("with_toc.pdf", "bookmarks.xlsx")

代码讲解

  • reader.outline 是PDF的大纲树根节点,结构是嵌套列表:一级书签是 Destination 对象,其下的二级书签是一个子列表。
  • _walk_outlines 递归遍历:遇到 list 就加深一层继续递归,遇到 Destination 就记录一行。
  • reader.get_destination_page_number(item) 返回该书签跳到的0基页码,+1 转成人类习惯的 1 基页码。
  • 最后用 pandas 导出 Excel,三列:层级、标题、页码,方便按层级缩进查看。
  • 控制台打印时用空格缩进体现层级关系,直接就能看到目录树。

运行结果

控制台按层级打印书签树,如:

[P1] 封面
[P3] 第一章 项目背景
[P3] 1.1 行业现状
[P5] 1.2 市场规模

同目录生成 bookmarks.xlsx,三列结构清晰。

注意事项

  • 不是所有PDF都有书签,没有书签的 reader.outline 是空列表。
  • 有些书签指向命名目标(named destination),get_destination_page_number 可能返回异常,脚本已 try/except 兜底为 None。
  • 层级深度取决于原PDF怎么做的书签,脚本会原样保留。
  • 想按书签拆分整本PDF。

Python PDF提取目录书签 大纲导出教程

标签:

更新时间:2026-09-14 21:39:33

上一篇:Python读取PDF全部图片 一键提取教程

下一篇:Python Excel转PDF:表格不溢出分页打印