通过 C# 读取并导出 PDF 书签

📅 2026/7/7 5:44:42
通过 C# 读取并导出 PDF 书签
1. 环境准备1.1 安装免费库在 Visual Studio 中通过 NuGet 包管理器安装Free Spire.PDFInstall-Package FreeSpire.PDF该免费版本支持读取 PDF 书签等基础操作无需额外授权文件但有单文件10页的页数限制。1.2 引用命名空间代码中需要引入以下命名空间using System; using System.IO; using System.Text; using Spire.Pdf; using Spire.Pdf.Bookmarks;2. 核心实现逻辑整体流程分为四步加载目标 PDF 文档。获取文档的PdfBookmarkCollection书签集合。递归遍历每个书签及其子书签提取标题和显示样式。将提取的内容写入文本文件。2.1 加载文档并获取书签集合PdfDocument pdf new PdfDocument(); pdf.LoadFromFile(D:\test.pdf); PdfBookmarkCollection bookmarks pdf.Bookmarks;Bookmarks属性返回一个集合包含顶层书签。如果文档没有书签Count为 0。2.2 递归遍历书签树书签结构是典型的树形结构每个书签节点可能拥有子书签集合通过Count属性和索引器访问。我们设计两个方法GetBookmarks处理顶层书签创建StringBuilder并启动递归。GetChildBookmark递归处理子书签。public static void GetBookmarks(PdfBookmarkCollection bookmarks, string result) { StringBuilder content new StringBuilder(); if (bookmarks.Count 0) { content.AppendLine(Pdf bookmarks:); foreach (PdfBookmark parentBookmark in bookmarks) { // 获取标题 content.AppendLine(parentBookmark.Title); // 获取显示样式如普通、粗体、斜体等 content.AppendLine(parentBookmark.DisplayStyle.ToString()); // 递归处理子书签 GetChildBookmark(parentBookmark, content); } } File.WriteAllText(result, content.ToString()); }递归方法public static void GetChildBookmark(PdfBookmark parentBookmark, StringBuilder content) { if (parentBookmark.Count 0) { foreach (PdfBookmark childBookmark in parentBookmark) { content.AppendLine(childBookmark.Title); content.AppendLine(childBookmark.DisplayStyle.ToString()); GetChildBookmark(childBookmark, content); } } }2.3 完整代码示例以下是一个控制台应用程序的完整实现将书签信息输出到GetPdfBookmarks.txt文件。using System; using System.IO; using System.Text; using Spire.Pdf; using Spire.Pdf.Bookmarks; namespace GetBookmark { internal class Program { static void Main(string[] args) { PdfDocument pdf new PdfDocument(); pdf.LoadFromFile(D:\testp\test.pdf); PdfBookmarkCollection bookmarks pdf.Bookmarks; string result GetPdfBookmarks.txt; GetBookmarks(bookmarks, result); Console.WriteLine(书签提取完成结果已保存至 result); } public static void GetBookmarks(PdfBookmarkCollection bookmarks, string result) { StringBuilder content new StringBuilder(); if (bookmarks.Count 0) { content.AppendLine(Pdf bookmarks:); foreach (PdfBookmark parentBookmark in bookmarks) { content.AppendLine(parentBookmark.Title); content.AppendLine(parentBookmark.DisplayStyle.ToString()); GetChildBookmark(parentBookmark, content); } } else { content.AppendLine(该 PDF 文档不包含任何书签。); } File.WriteAllText(result, content.ToString()); } public static void GetChildBookmark(PdfBookmark parentBookmark, StringBuilder content) { if (parentBookmark.Count 0) { foreach (PdfBookmark childBookmark in parentBookmark) { content.AppendLine(childBookmark.Title); content.AppendLine(childBookmark.DisplayStyle.ToString()); GetChildBookmark(childBookmark, content); } } } } }3. 输出格式说明生成的文本文件每两行代表一个书签第一行是标题第二行是显示样式。例如Pdf bookmarks: 第1章 简介 Regular 1.1 背景 Bold 1.2 目标 Italic 第2章 实现 Regular 2.1 环境搭建 RegularDisplayStyle是一个枚举可能的值包括Regular普通文本Bold粗体Italic斜体根据 PDF 文件的实际书签样式输出结果会相应变化。4. 注意事项与扩展4.1 书签可能为空若 PDF 没有书签bookmarks.Count为 0代码会写入提示信息避免空文件。4.2 目标页码与动作的获取上述示例仅获取了标题和样式。如果需要获取书签跳转的目标页码可以使用PdfBookmark.Action属性需判断动作类型。例如if (parentBookmark.Action is PdfGoToAction goToAction) { int pageIndex pdf.Pages.IndexOf(goToAction.Destination.Page); content.AppendLine($跳转至第 {pageIndex 1} 页); }由于 Free Spire.PDF 对Action的支持较为完整可根据实际需求扩展。4.3 性能考虑对于包含数千个书签的 PDF递归遍历不会有明显性能问题。但若需频繁提取可考虑将StringBuilder替换为StreamWriter流式写入降低内存占用。4.4 编码处理File.WriteAllText默认使用 UTF-8 编码如需指定编码如 GB2312可改用StreamWriter。5. 总结本文演示了如何利用免费 .NET 库完整提取 PDF 文档的多级书签信息。关键技术点包括通过PdfDocument.Bookmarks获取根书签集合。递归遍历PdfBookmark节点的Count和索引器。