查看: 133|回复: 3

Python操作PDF书签:使用Spire.PDF实现创建、修改与删除

[复制链接]
发表于 2 小时前 | 显示全部楼层 |阅读模式
在处理长篇PDF文档(如技术手册、学术论文或企业报告)时,书签是帮助读者快速定位章节的关键导航工具。通过编程方式管理书签,可以批量处理、精确控制层级关系、动态更新,并集成到自动化文档生成流水线中。本文将基于Spire.PDF for Python库,演示如何创建、修改、删除、获取信息并控制书签的展开折叠及缩放行为。

1. 环境搭建

首先通过pip安装Spire.PDF:
  1. pip install Spire.PDF
复制代码

在脚本中导入必要模块:
  1. from spire.pdf.common import *
  2. from spire.pdf import *
复制代码

2. 创建带有父子层级的书签

书签的核心是树状层级结构:顶级父书签下可挂载多个子书签。先创建文档并设置页面:
  1. doc = PdfDocument()
  2. unitCvtr = PdfUnitConvertor()
  3. margin = PdfMargins()
  4. margin.Top = unitCvtr.ConvertUnits(2.54, PdfGraphicsUnit.Centimeter, PdfGraphicsUnit.Point)
  5. margin.Bottom = margin.Top
  6. margin.Left = unitCvtr.ConvertUnits(3.17, PdfGraphicsUnit.Centimeter, PdfGraphicsUnit.Point)
  7. margin.Right = margin.Left
  8. section = doc.Sections.Add()
  9. section.PageSettings.Margins = margin
  10. section.PageSettings.Size = PdfPageSize.A4()
复制代码

添加页面并绘制标题:
  1. page = section.Pages.Add()
  2. font_title = PdfTrueTypeFont("Arial", 16.0, PdfFontStyle.Bold, True)
  3. brush = PdfBrushes.get_Black()
  4. format_center = PdfStringFormat(PdfTextAlignment.Center)
  5. page.Canvas.DrawString("PDF 书签示例文档", font_title, brush,
  6.     page.Canvas.ClientSize.Width / 2, 10, format_center)
复制代码

2.1 添加父书签

父书签通过doc.Bookmarks.Add()创建,返回PdfBookmark对象。需要关联一个PdfDestination指定目标页面和坐标,再用PdfGoToAction绑定:
  1. font_chapter = PdfTrueTypeFont("Arial", 11.0, PdfFontStyle.Bold, True)
  2. y = 60.0
  3. page.Canvas.DrawString("1. 第一章 概述", font_chapter, PdfBrushes.get_Blue(), 0.0, y)
  4. dest1 = PdfDestination(page, PointF(0.0, y))
  5. bookmark1 = doc.Bookmarks.Add("1. 第一章 概述")
  6. bookmark1.Color = PdfRGBColor(Color.get_SaddleBrown())
  7. bookmark1.DisplayStyle = PdfTextStyle.Bold
  8. bookmark1.Action = PdfGoToAction(dest1)
复制代码

Color和DisplayStyle控制书签在导航面板中的颜色和文字样式(粗体、斜体等)。

2.2 添加子书签

子书签通过父书签的PdfBookmarkCollection添加,而非直接添加到文档顶级集合:
  1. childCollection = PdfBookmarkCollection(bookmark1)
  2. page2 = section.Pages.Add()
  3. y2 = 0.0
  4. page2.Canvas.DrawString("1.1. 背景介绍", font_chapter, PdfBrushes.get_Brown(), 0.0, y2)
  5. dest_child = PdfDestination(page2, PointF(0.0, y2))
  6. child_bookmark = childCollection.Add("1.1. 背景介绍")
  7. child_bookmark.Color = PdfRGBColor(Color.get_Coral())
  8. child_bookmark.DisplayStyle = PdfTextStyle.Italic
  9. child_bookmark.Action = PdfGoToAction(dest_child)
复制代码

保存文档:
  1. doc.SaveToFile("Bookmark_output.pdf")
  2. doc.Close()
复制代码

3. 修改已有书签

加载文档后可直接修改书签的Title、Color、DisplayStyle:
  1. doc = PdfDocument()
  2. doc.LoadFromFile("input.pdf")
  3. bookmark = doc.Bookmarks[0]
  4. bookmark.Title = "修改后的书签标题"
  5. bookmark.Color = PdfRGBColor(Color.get_Black())
  6. bookmark.DisplayStyle = PdfTextStyle.Bold
  7. doc.SaveToFile("UpdatedBookmark.pdf")
  8. doc.Close()
复制代码

对于子书签,需递归遍历:
  1. def update_child_bookmarks(parent_bookmark):
  2.     children = PdfBookmarkCollection(parent_bookmark)
  3.     for i in range(children.Count):
  4.         child = children.get_Item(i)
  5.         child.Color = PdfRGBColor(Color.get_Blue())
  6.         child.DisplayStyle = PdfTextStyle.Regular
  7.         update_child_bookmarks(child)
  8. update_child_bookmarks(doc.Bookmarks[0])
复制代码

4. 删除书签

删除单个顶级书签(含其所有子书签)使用RemoveAt(index)
  1. doc.Bookmarks.RemoveAt(0)
复制代码

清除所有书签使用Clear()
  1. doc.Bookmarks.Clear()
复制代码

适合重新生成书签结构前的清理操作。

5. 获取书签信息

遍历书签读取Title和DisplayStyle:
  1. doc = PdfDocument()
  2. doc.LoadFromFile("input.pdf")
  3. bookmarks = doc.Bookmarks
  4. results = []
  5. if bookmarks.Count > 0:
  6.     results.append("PDF 书签列表:")
  7.     for i in range(bookmarks.Count):
  8.         parent = bookmarks.get_Item(i)
  9.         results.append(f"标题:{parent.Title}")
  10.         results.append(f"样式:{parent.DisplayStyle}")
  11.         children = PdfBookmarkCollection(parent)
  12.         for j in range(children.Count):
  13.             child = children.get_Item(j)
  14.             results.append(f"  子书签:{child.Title}")
  15.             results.append(f"  样式:{child.DisplayStyle}")
  16. with open("Bookmarks_Info.txt", "w", encoding="utf-8") as f:
  17.     f.write("\n".join(results))
  18. doc.Close()
复制代码

获取书签所在页码(需加1转换为1-based页码):
  1. page_number = doc.Pages.IndexOf(bookmark.Destination.Page) + 1
复制代码

6. 控制书签展开/折叠状态

全局设置所有书签展开或折叠:
  1. doc.ViewerPreferences.BookMarkExpandOrCollapse = True  # True展开,False折叠
复制代码

控制单个书签展开状态:
  1. doc.Bookmarks.get_Item(0).ExpandBookmark = True
  2.     doc.Bookmarks.get_Item(1).ExpandBookmark = False
复制代码

适合用于突出显示重点章节,同时保持其他章节折叠以减少视觉干扰。

7. 设置书签跳转缩放级别

通过设置Destination.Zoom控制跳转后页面的缩放比例:
  1. bookmark.Destination.Zoom = 0.5  # 50%缩放
复制代码
值为0时继承阅读器默认缩放,大于0则指定固定比例。

总结

以上操作覆盖了PDF书签管理的核心功能:创建(父子层级)、修改、删除、信息读取、展开折叠控制和缩放设置。这些代码可灵活组合用于批量文档处理或自动化报告生成。深入探索还可涉及超链接、表单字段和数字签名等高级功能。
回复

使用道具 举报

发表于 2 小时前 | 显示全部楼层

Re: Python操作PDF书签:使用Spire.PDF实现创建、修改与删除

非常感谢楼主如此详细地分享基于 Spire.PDF 的 Python 书签操作教程!从环境搭建到创建父子层级、再到修改现有书签,每个步骤都配了清晰代码,尤其是对 `PdfDestination` 和 `PdfBookmarkCollection` 的用法讲解,让刚接触 PDF 编程的人也能快速上手。 我试了一下,创建嵌套书签后保存的文档在阅读器里展开层级非常流畅。想请教一下:对于已有大量书签的 PDF(比如数千个),这个库的递归遍历修改性能如何?另外,书签的中文标题会出现乱码吗?期待楼主后续能补充关于删除特定书签以及批量展开/折叠所有书签的实现。再次感谢分享!
回复 支持 反对

使用道具 举报

发表于 2 小时前 | 显示全部楼层

Re: Python操作PDF书签:使用Spire.PDF实现创建、修改与删除

感谢分享!这个教程非常清晰实用,特别是父子层级书签的创建和递归修改部分,正好解决了我处理自动化文档时需要批量生成书签的痛点。我之前试过一些其他库,但对中文支持不够好,Spire.PDF 看起来挺完善的。对了,删除书签的部分没有贴出来,能补充一下具体的代码示例吗?比如如何根据标题匹配并删除特定书签?
回复 支持 反对

使用道具 举报

发表于 2 小时前 | 显示全部楼层

Re: Python操作PDF书签:使用Spire.PDF实现创建、修改与删除

感谢楼主分享这么详细的教程!Spire.PDF for Python 我之前也留意过,但没深入试过书签操作。你讲的父子层级创建、颜色样式设置还有递归修改这部分写得特别清楚,跟着代码跑了一遍,确实能生成带层级导航的 PDF。想问一下,这个库在商业项目里用需要授权吗?另外,如果我想把多个 PDF 的书签批量合并到一个文件里,有没有现成的方法,还是得自己遍历处理?
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

指导单位

江苏省公安厅

江苏省通信管理局

浙江省台州刑侦支队

DEFCON GROUP 86025

Hacking Group 021A

旗下站点

态势感知中心

应急响应中心

红盟安全

联系我们

官方QQ群:112851260

官方邮箱:security#ihonker.org(#改成@)

官方核心成员

关注微信公众号

Archiver|手机版|小黑屋| ( 沪ICP备2021026908号 )

GMT+8, 2026-7-3 11:49 , Processed in 0.036469 second(s), 17 queries , Gzip On, Redis On.

Powered by ihonker.com

Copyright © 2015-现在.

  • 返回顶部