一份几十页甚至上百页的 PDF 文档——产品说明书、技术手册、项目报告、会议论文集——如果没有书签和目录,阅读体验会急剧下降。读者如果想从"第 3 章"直接翻到"5.2 小节",只能用鼠标滚轮一页页滚动,或者凭记忆估算页码;评审和归档时,也无法快速定位到某一章节。
书签(Bookmarks)与目录(Table of Contents)解决的正是"定位"问题:书签是 PDF 阅读器左侧导航栏里的层级结构,点击即可跳转到对应章节;目录页则是排在正文之前的一页文字清单,逐行列出章节标题与页码,便于打印阅读或快速浏览全篇结构。但这两样东西往往在文档生成阶段被忽略:Word 转 PDF 时自动书签可能丢失,扫描件与拼装文档更是完全没有书签;手工添加则要在标题与页码之间反复核对,文档一长就极易错位。
Spire.Agent.Office 的 PDF AI 能力可以直接用自然语言描述书签层级与目录要求,AI 智能体理解后自动完成两类工作:为 PDF 生成层次化书签,以及生成一页与正文页码对应、可直接点击跳转的卷首目录页。
对比传统 SDK API 处理
| 传统 Spire.Office for .NET API | Spire.Agent.Office 处理 | |
|---|---|---|
| 驱动方式 | 编写代码遍历页面、按字号或编号正则匹配标题、逐个构造书签树并按页赋值,控制每一步 | 用自然语言描述书签层级与目录要求,AI 理解后自动编排执行路径 |
| 代码量 | 书签与目录生成通常需要 150-300 行 C# 代码(含页面遍历、标题识别、层级判定、书签树构造、页码计算、目录页绘制与排版等) | 约 10 行调用代码 + 1 条自然语言指令 |
| 标题识别 | 需要自己定义"什么样的文本算标题",字号、编号格式一变就得改规则 | AI 结合编号、字号与版式上下文判断标题层级,规则在指令中用一句话描述 |
| 页码对应 | 目录中的页码要手工统计,正文一改动就得重数 | AI 读取正文实际页码填入目录,无需逐章统计 |
| 需求变更 | 改动书签层级/目录样式 → 改代码 → 编译 → 重新部署 | 修改指令,即刻生效 |
本文介绍如何使用 Spire.Agent.Office PDF AI 能力为 PDF 文档生成书签与目录。全文通过两个案例展示"生成层次化书签"与"生成卷首目录页"两种典型用法:
有关产品安装和 SpireToken 配置,请参考 在 .NET 项目中集成 Spire.Agent.Office。以下示例默认已安装 Spire.Agent.Office 并完成 SpireToken 配置。
案例一:为 PDF 自动生成层次化书签
产品说明书、技术手册一类文档通常有相对固定的结构:正文用"第 1 章""第 2 章"划分大的部分,章内再用"1.1""1.2"细分小节。这种结构在版面上靠字号与编号体现,读者一眼就能看出层次,但 PDF 阅读器的导航栏里却是空的——想跳到某一小节,只能自己一页页找。
要让导航栏真正好用,书签必须与正文标题的层级一一对应:一级标题生成顶层书签,二级标题生成挂在该章下的子书签,点击书签直接跳到标题所在页面。手工添加意味着逐页翻找标题、在书签面板里新建条目、再逐个指定跳转位置,几百个标题下来几乎必然出错。
以下示例使用 Spire.Agent.Office 智能体,通过自然语言指令读取 PDF 正文的章节结构,按标题层级自动生成多级书签:
using Spire.Agent.Office.AI;
using Spire.Agent.Office.Extensions;
using Spire.Pdf;
// PDF 处理相关配置
string inputPath = @"E:\manual.pdf"; // 待生成书签的 PDF 文件路径
string savePath = @"E:\output\manual-with-bookmarks.pdf"; // 结果文档保存路径
string key = "**************************"; // SpireToken Key
string instruction =
"读取该 PDF 文件的正文内容,为其自动生成层次化书签:" +
"1. 识别正文中的章节标题,以'第 X 章'开头的标题作为一级书签,以'X.Y'编号开头的标题作为对应章节下的二级书签;" +
"2. 书签按正文出现顺序排列,层级关系与正文标题结构一致,书签标题与正文标题文字保持一致;" +
"3. 每个书签跳转到对应标题所在的页面,点击书签即可定位到该章节;" +
"4. 忽略图表标题、页眉页脚等文字,不为它们生成书签;" +
"5. 保持正文原有的布局、字体与页面设置不变;" +
"最终输出保存为PDF文件";
// 调用PDF文档处理函数
AIResult result = ExecuteDemoPDF(instruction, inputPath, savePath, key);
// 执行PDF文档AI处理
static AIResult ExecuteDemoPDF(string instruction, string inputPath, string savePath, string key)
{
// 创建AIOptions选项配置对象
AIOptions options = new AIOptions();
options.SpireToken = key; // 设置SpireToken Key
// 使用PdfDocument对象处理PDF文档
using (PdfDocument pdf = new PdfDocument())
{
// 从文件加载PDF文档
if (!string.IsNullOrEmpty(inputPath) && File.Exists(inputPath))
{
pdf.LoadFromFile(inputPath);
}
// 创建AI文档处理器
AIDocumentProcessor processor = pdf.AI(options);
// 执行AI指令
return processor.ExecuteInstruction(pdf, instruction, savePath);
}
}
自动生成层次化书签后的 PDF

生成的书签完整复刻了正文的章节结构:一级章节作为顶层书签,各小节作为其子书签折叠在下方,点击任意书签即可跳转到对应标题所在页面。正文的排版、字体与页面设置保持不变,只多出了一套导航结构。
案例二:为 PDF 自动生成卷首目录页
技术方案、项目报告、论文集这类文档交付给评审或读者时,通常需要一页排在最前面的目录:逐行列出各章节的标题,右侧标注该章节所在的页码,便于读者先看清全篇结构、再决定从哪里读起。目录页也是正式文档的体例要求之一。这类文档一般带有封面页,目录就排在封面之后、正文之前。
制作目录页的麻烦在于两件事。其一是"页码":页码必须与正文的实际情况一致,而正文一旦增删章节、调整分页,所有页码都要重数一遍。其二是"跳转":目录上写着"5.2 节 第 27 页",读者仍要自己翻到第 27 页;只有让目录条目本身可以点击,点到哪一条就跳到哪一页,目录才真正好用。
以下示例使用 Spire.Agent.Office 智能体,通过自然语言指令提取正文各章节标题与对应页码,在封面页后插入一页排好版、可直接点击跳转的目录:
using Spire.Agent.Office.AI;
using Spire.Agent.Office.Extensions;
using Spire.Pdf;
// PDF 处理相关配置
string inputPath = @"E:\report.pdf"; // 待生成目录页的 PDF 文件路径
string savePath = @"E:\output\report-with-toc.pdf"; // 结果文档保存路径
string key = "**************************"; // SpireToken Key
string instruction =
"读取该 PDF 文件的正文内容,在封面页后生成目录页:" +
"1. 提取正文中各章节的标题与所在页码,一级与二级标题都要列入;" +
"2. 在封面页之后、正文之前插入一页'目录',逐行列出章节标题与对应页码,标题左对齐、页码右对齐,中间用点线引导;" +
"3. 为目录中的每一条条目建立跳转链接,点击目录条目即可直接跳转到该章节所在页面;" +
"4. 目录中标注的页码与插入目录页后的正文实际页码对应,不得出现页码错位;" +
"5. 目录页标题使用'目录'二字居中显示,字号与正文一级标题一致;" +
"6. 保持正文原有的布局、字体与页面设置不变;" +
"最终输出保存为PDF文件";
// 调用PDF文档处理函数
AIResult result = ExecuteDemoPDF(instruction, inputPath, savePath, key);
// 执行PDF文档AI处理
static AIResult ExecuteDemoPDF(string instruction, string inputPath, string savePath, string key)
{
// 创建AIOptions选项配置对象
AIOptions options = new AIOptions();
options.SpireToken = key; // 设置SpireToken Key
// 使用PdfDocument对象处理PDF文档
using (PdfDocument pdf = new PdfDocument())
{
// 从文件加载PDF文档
if (!string.IsNullOrEmpty(inputPath) && File.Exists(inputPath))
{
pdf.LoadFromFile(inputPath);
}
// 创建AI文档处理器
AIDocumentProcessor processor = pdf.AI(options);
// 执行AI指令
return processor.ExecuteInstruction(pdf, instruction, savePath);
}
}
在卷首生成目录页后的 PDF

目录页按章节层级逐行排布,标题与页码之间以点线引导,与正式出版物的目录版式一致;每个条目都带有跳转链接,点击即定位到对应章节,目录页同时具备了阅读与导航两种用途。正文内容与原有排版不受影响,目录页单独插入在封面页之后。
常见问题
生成的书签没有层级,所有标题都平铺在同一级
原因:正文的层级是通过编号格式("第 1 章"与"1.1")和字号大小体现的,如果指令中没有说明判定规则,AI 可能把识别到的标题统一作为顶层书签处理。
解决:在指令中写明层级判定规则,例如"以'第 X 章'开头的标题作为一级书签,以'X.Y'编号开头的标题作为对应章节下的二级书签"。编号格式特殊(如"第一部分""附录 A")时,把对应规则一并写进指令即可。
目录中的页码与正文实际页码对不上
原因:目录页插入到正文之前,会让其后所有页面整体后移一页,如果先统计页码再插入目录页,目录里标注的页码就会全部偏小一页。
解决:在指令中明确页码的取值基准,例如"目录中标注的页码与插入目录页后的正文实际页码对应";如果正文本身已有独立的页码编排(如封面、前言不参与编号),也在指令中说明其编号规则,让 AI 按同一规则统计。
获取 SpireToken Key
- 联系 该Email地址已收到反垃圾邮件插件保护。要显示它您需要在浏览器中启用JavaScript。或访问 https://www.e-iceblue.com/TemLicense.html获得试用/商业 API 密钥
在代码中配置:
AIOptions options = new AIOptions();options.SpireToken = key;









