使用Python实现在PDF中创建与管理书签

 更新时间:2026年07月03日 08:14:07   作者:用户835629078051  
在处理长篇 PDF 文档时,书签(Bookmark)是帮助读者快速定位到特定章节的关键导航工具,本文将介绍如何使用 Python 对 PDF 文档中的书签进行完整管理,包括创建、修改、删除、获取信息以及控制展开状态等操作,希望对大家有所帮助

在处理长篇 PDF 文档时,书签(Bookmark)是帮助读者快速定位到特定章节的关键导航工具。无论是技术手册、学术论文还是企业报告,合理的书签结构都能显著提升文档的可读性和使用效率。本文将介绍如何使用 Python 对 PDF 文档中的书签进行完整管理,包括创建、修改、删除、获取信息以及控制展开状态等操作。

为什么需要编程管理 PDF 书签

手动在 PDF 阅读器中添加书签效率较低,尤其在面对批量文档或需要频繁更新的场景时更是如此。通过编程方式管理书签具有以下优势:

  • 批量处理:一次脚本运行即可为大量文档生成统一的书签结构
  • 精确控制:可以准确指定书签跳转位置、样式和层级关系
  • 动态更新:根据文档内容变化自动调整书签标题和结构
  • 自动化集成:将书签生成嵌入到文档生成流水线中

环境搭建

本文使用 Spire.PDF for Python 库来操作 PDF 文档。通过 pip 安装即可:

pip install Spire.PDF

安装完成后,在脚本中导入所需模块:

from spire.pdf.common import *
from spire.pdf import *

创建带有父子层级的书签

书签的核心概念是层级结构。一个 PDF 文档可以包含多个顶级书签(父书签),每个父书签下又可以挂载多个子书签,形成树状导航。

创建书签的关键步骤是:创建文档和页面、在页面上绘制内容、然后将书签指向对应的位置。

from spire.pdf.common import *
from spire.pdf import *

doc = PdfDocument()

# 设置页面边距和尺寸
unitCvtr = PdfUnitConvertor()
margin = PdfMargins()
margin.Top = unitCvtr.ConvertUnits(2.54, PdfGraphicsUnit.Centimeter, PdfGraphicsUnit.Point)
margin.Bottom = margin.Top
margin.Left = unitCvtr.ConvertUnits(3.17, PdfGraphicsUnit.Centimeter, PdfGraphicsUnit.Point)
margin.Right = margin.Left

section = doc.Sections.Add()
section.PageSettings.Margins = margin
section.PageSettings.Size = PdfPageSize.A4()

# 创建第一页并绘制标题
page = section.Pages.Add()
font_title = PdfTrueTypeFont("Arial", 16.0, PdfFontStyle.Bold, True)
brush = PdfBrushes.get_Black()
format_center = PdfStringFormat(PdfTextAlignment.Center)
page.Canvas.DrawString("PDF 书签示例文档", font_title, brush,
    page.Canvas.ClientSize.Width / 2, 10, format_center)

上述代码完成了文档的基本框架搭建。PdfUnitConvertor 用于将厘米等单位转换为 PDF 内部使用的 Point 单位,确保页面布局的精确控制。

添加父书签

父书签通过 doc.Bookmarks.Add() 方法创建,该方法接受书签标题作为参数,返回一个 PdfBookmark 对象。每个书签需要关联一个 PdfDestination,指定点击书签后跳转到的页面和位置。

# 在页面上绘制章节标题
font_chapter = PdfTrueTypeFont("Arial", 11.0, PdfFontStyle.Bold, True)
y = 60.0
page.Canvas.DrawString("1. 第一章 概述", font_chapter, PdfBrushes.get_Blue(), 0.0, y)

# 创建父书签并设置跳转目标
dest1 = PdfDestination(page, PointF(0.0, y))
bookmark1 = doc.Bookmarks.Add("1. 第一章 概述")
bookmark1.Color = PdfRGBColor(Color.get_SaddleBrown())
bookmark1.DisplayStyle = PdfTextStyle.Bold
bookmark1.Action = PdfGoToAction(dest1)

PdfDestination 接收页面对象和坐标点作为参数。PdfGoToAction 将这个目标绑定到书签上,实现点击跳转。书签的 ColorDisplayStyle 属性分别控制书签在阅读器中显示的颜色和文字样式(粗体、斜体等)。

添加子书签

子书签的创建方式与父书签类似,区别在于需要通过 PdfBookmarkCollection 将子书签添加到父书签之下,而不是直接添加到文档的顶级书签集合。

# 获取父书签的子书签集合
childCollection = PdfBookmarkCollection(bookmark1)

# 创建子书签
page2 = section.Pages.Add()
y2 = 0.0
page2.Canvas.DrawString("1.1. 背景介绍", font_chapter, PdfBrushes.get_Brown(), 0.0, y2)

dest_child = PdfDestination(page2, PointF(0.0, y2))
child_bookmark = childCollection.Add("1.1. 背景介绍")
child_bookmark.Color = PdfRGBColor(Color.get_Coral())
child_bookmark.DisplayStyle = PdfTextStyle.Italic
child_bookmark.Action = PdfGoToAction(dest_child)

通过 PdfBookmarkCollection(parentBookmark) 获取父书签的子集合后,调用 Add() 方法即可在该父书签下添加子书签。子书签同样可以设置独立的颜色和样式,便于在导航面板中区分层级。

保存文档

完成所有书签的添加后,保存文档:

doc.SaveToFile("Bookmark_output.pdf")
doc.Close()

修改已有书签

对于已存在的 PDF 文档,可以加载后修改其书签的标题、颜色和样式。这对于需要根据模板生成定制化文档的场景非常实用。

doc = PdfDocument()
doc.LoadFromFile("input.pdf")

# 获取第一个顶级书签
bookmark = doc.Bookmarks[0]

# 修改标题
bookmark.Title = "修改后的书签标题"

# 修改颜色为黑色
bookmark.Color = PdfRGBColor(Color.get_Black())

# 设置样式为粗体
bookmark.DisplayStyle = PdfTextStyle.Bold

doc.SaveToFile("UpdatedBookmark.pdf")
doc.Close()

修改子书签时,需要通过递归方式遍历子书签集合:

def update_child_bookmarks(parent_bookmark):
    children = PdfBookmarkCollection(parent_bookmark)
    for i in range(children.Count):
        child = children.get_Item(i)
        child.Color = PdfRGBColor(Color.get_Blue())
        child.DisplayStyle = PdfTextStyle.Regular
        # 递归处理更深层级的子书签
        update_child_bookmarks(child)

# 更新第一个书签下的所有子书签
update_child_bookmarks(doc.Bookmarks[0])

递归遍历确保了无论书签层级有多深,每个子书签都能被正确更新。

删除书签

删除书签分为两种场景:删除指定书签和清除所有书签。

删除单个书签

通过索引移除特定的顶级书签:

doc = PdfDocument()
doc.LoadFromFile("input.pdf")

# 删除第一个顶级书签(及其所有子书签)
doc.Bookmarks.RemoveAt(0)

doc.SaveToFile("DeleteBookmark.pdf")
doc.Close()

RemoveAt() 方法会同时删除该书签下的所有子书签。这在需要精简文档导航结构时非常有用。

清除所有书签

如果需要一次性移除文档中的所有书签:

doc = PdfDocument()
doc.LoadFromFile("input.pdf")

# 清除所有书签
doc.Bookmarks.Clear()

doc.SaveToFile("DeleteAllBookmarks.pdf")
doc.Close()

Clear() 方法会清空整个书签集合,适用于需要重新生成书签结构前的清理操作。

获取书签信息

在自动化处理流程中,经常需要读取 PDF 文档中已有的书签信息,例如标题、样式和所在页码。

获取书签标题和样式

doc = PdfDocument()
doc.LoadFromFile("input.pdf")

bookmarks = doc.Bookmarks
results = []

if bookmarks.Count > 0:
    results.append("PDF 书签列表:")
    for i in range(bookmarks.Count):
        parent = bookmarks.get_Item(i)
        results.append(f"标题:{parent.Title}")
        results.append(f"样式:{parent.DisplayStyle}")

        # 递归获取子书签
        children = PdfBookmarkCollection(parent)
        for j in range(children.Count):
            child = children.get_Item(j)
            results.append(f"  子书签:{child.Title}")
            results.append(f"  样式:{child.DisplayStyle}")

with open("Bookmarks_Info.txt", "w", encoding="utf-8") as f:
    f.write("\n".join(results))

doc.Close()

获取书签所在页码

书签跳转的目标页码可以通过 Destination.Page 属性获取。由于 Pages.IndexOf() 返回的是从 0 开始的索引,需要加 1 才是实际的页码编号:

doc = PdfDocument()
doc.LoadFromFile("input.pdf")

bookmark = doc.Bookmarks[0]
page_number = doc.Pages.IndexOf(bookmark.Destination.Page) + 1
print(f"书签所在页码:{page_number}")

doc.Close()

控制书签的展开和折叠状态

PDF 阅读器打开文档时,书签面板可以处于展开或折叠状态。通过编程方式可以控制这一行为:

展开或折叠所有书签

doc = PdfDocument()
doc.LoadFromFile("input.pdf")

# True 表示展开所有书签,False 表示折叠
doc.ViewerPreferences.BookMarkExpandOrCollapse = True

doc.SaveToFile("ExpandAllBookmarks.pdf")
doc.Close()

控制特定书签的展开状态

如果只需要展开或折叠部分书签,可以单独设置每个书签的 ExpandBookmark 属性:

doc = PdfDocument()
doc.LoadFromFile("input.pdf")

# 展开第一个书签
doc.Bookmarks.get_Item(0).ExpandBookmark = True

# 折叠第二个书签
doc.Bookmarks.get_Item(1).ExpandBookmark = False

doc.SaveToFile("ExpandSpecificBookmarks.pdf")
doc.Close()

这种细粒度的控制适合在文档中突出显示某些重点章节的导航结构,同时保持其他章节的折叠状态以减少视觉干扰。

设置书签跳转时的缩放级别

书签跳转时可以同时控制页面的缩放比例,这在需要精确展示页面内容的场景中很有用:

doc = PdfDocument()
doc.LoadFromFile("input.pdf")

bookmarks = doc.Bookmarks
for i in range(bookmarks.Count):
    bookmark = bookmarks.get_Item(i)
    # 设置缩放级别,0.5 表示 50% 缩放
    bookmark.Destination.Zoom = 0.5

doc.SaveToFile("SetBookmarkZoom.pdf")
doc.Close()

缩放值为 0 时表示继承当前阅读器的缩放设置,大于 0 的值则指定具体的缩放比例。

总结

本文介绍了使用 Python 管理 PDF 文档书签的完整流程,涵盖了以下核心操作:

  1. 创建书签:通过 Bookmarks.Add() 添加父书签,通过 PdfBookmarkCollection 添加子书签
  2. 修改书签:更新标题、颜色和文字样式,支持递归修改子书签
  3. 删除书签:使用 RemoveAt() 删除指定书签,使用 Clear() 清除全部书签
  4. 获取信息:读取书签标题、样式和所在页码
  5. 控制展开状态:全局或单独控制书签的展开和折叠行为
  6. 设置缩放级别:控制书签跳转时的页面缩放比例

这些操作可以灵活组合,应用于批量文档处理、自动化报告生成等实际场景。掌握书签管理后,还可以进一步探索 PDF 的超链接、表单字段和数字签名等高级功能。

到此这篇关于使用Python实现在PDF中创建与管理书签的文章就介绍到这了,更多相关Python PDF创建与管理书签内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • kNN算法python实现和简单数字识别的方法

    kNN算法python实现和简单数字识别的方法

    这篇文章主要介绍了kNN算法python实现和简单数字识别的方法,详细讲述了kNN算法的优缺点及原理,并给出了应用实例,需要的朋友可以参考下
    2014-11-11
  • 教你用Django将前端的数据存入Mysql数据库

    教你用Django将前端的数据存入Mysql数据库

    这篇文章主要给大家介绍了关于如何用Django将前端的数据存入Mysql数据库的相关资料,文中通过图文以及示例代码介绍的非常详细,对大家学习或者使用Django具有一定的参考学习价值,需要的朋友可以参考下
    2021-11-11
  • Python partial函数原理及用法解析

    Python partial函数原理及用法解析

    这篇文章主要介绍了Python partial函数原理及用法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-12-12
  • 基于Python编写一个单词自测程序

    基于Python编写一个单词自测程序

    这篇文章主要为大家详细介绍了如何基于Python编写一个单词自测程序,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-12-12
  • 使用Python制作微信跳一跳辅助

    使用Python制作微信跳一跳辅助

    Python火到微信去了,辅助微信跳一跳,让你玩到朋友圈第一,今天就跟着我来试试用python实现制作跳一跳辅助,并把代码分享给大家
    2018-01-01
  • python 定时修改数据库的示例代码

    python 定时修改数据库的示例代码

    这篇文章主要介绍了python 定时修改数据库的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-04-04
  • Pycharm自动添加文件头注释和函数注释参数的方法

    Pycharm自动添加文件头注释和函数注释参数的方法

    这篇文章主要介绍了Pycharm自动添加文件头注释和函数注释参数,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-10-10
  • Python文件路径os.path函数深入剖析

    Python文件路径os.path函数深入剖析

    这篇文章主要为大家介绍了Python文件路径os.path函数深入剖析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-08-08
  • Python使用Selenium实现按文本查找元素

    Python使用Selenium实现按文本查找元素

    本文我们将通过示例为大家详细介绍如何在Python中使用selenium通过文本查找元素的方法,文中的示例代码讲解详细,感兴趣的小伙伴可以参考一下
    2023-11-11
  • python区块链简易版交易实现示例

    python区块链简易版交易实现示例

    这篇文章主要为大家介绍了python区块链简易版交易实现示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-05-05

最新评论