C#使用iText7给PDF文档添加书签

上一篇文章将SqlSugar官网文档中每个链接对应的网页生成独立PDF文档再合并为单个PDF文档,但是没有书签,八百多页的内容查找和跳转都不方便,本文学习和使用iText7给PDF文档添加多级书签。
  添加多级书签分为两大步骤:1)获取书签分类;2)创建多级书签。如下图所示,SqlSugar官网文档页面右侧的帮助链接都有所属版块,如版本记录属于产品详情版块,入门必看属于从零开始版块,本文第一步先分析如何获取链接所属的版块信息。

  查看网页源代码,分析其中的结构,可以看到版块名称和帮助链接都位于class值为layui-tree的列表内,且版块名称和帮助链接属于同一级别,先出现版块li,其class值为clear,后面跟随的li都属于其版块内容,class值均包含site-float site-tree-noicon。

  根据上述分析,采用HtmlAgilityPack抓取并获取版块及其所属帮助链接信息,主要代码及程序运行效果如下所示:

csharp 复制代码
HtmlWeb web = new HtmlWeb();
HtmlAgilityPack.HtmlDocument docu = web.Load(txtUrl.Text);
HtmlNode node = docu.DocumentNode.SelectSingleNode(@"//ul[@class='layui-tree']");

HtmlNode tmpNode;
string curSection = string.Empty;

foreach (HtmlNode subNode in node.ChildNodes)
{
    string className = subNode.GetAttributeValue<string>("class", string.Empty);

    if (string.IsNullOrEmpty(className))
    {
        continue;
    }

    if (className == "clear")
    {
        curSection = subNode.InnerText;
    }

    if (className.Contains("site-float site-tree-noicon"))
    {
        tmpNode = subNode.SelectSingleNode(".//a");
        
        DataGridViewRow dgvr = new DataGridViewRow();        
        dgvr.CreateCells(dataGridView1);
        dgvr.Cells[0].Value = dataGridView1.Rows.Count + 1;
        dgvr.Cells[1].Value = curSection ;
        dgvr.Cells[2].Value = tmpNode.InnerText;
        dgvr.Cells[3].Value = @"https://www.donet5.com" + tmpNode.Attributes["href"].Value;

        dataGridView1.Rows.Add(dgvr);
    }                
}


  生成的独立文档如下所示,为便于获取文档所属板块,将板块名称作为文件名的第一部分。

  接下来是添加多级书签,主要就是两级,第一级为版块,第二级为版块包含的帮助文档。使用PdfOutline创建书签及跳转链接。在PDF文档合并之后,调用PdfDocument.GetOutlines函数获取书签根节点,然后调用PdfOutline.AddOutline函数创建下级书签(类似于树控件中的节点,可以不停地创建),关键代码如下所示。

csharp 复制代码
PdfDocument pdfDoc = new PdfDocument(new PdfWriter(txtFileName.Text));
...
...
PdfOutline rootOutline = pdfDoc.GetOutlines(false);
PdfOutline tmpOutline = null;
PdfOutline tmpSubOutline = null;
int curPageIndex = 1;
int underlineIndex = -1;
string tmpModule = "XXXXXX";

foreach (PdfFileInfo doc in pdfFiles)
{
    string fileName = doc.FileName;

    if (!fileName.StartsWith(tmpModule))
    {
        underlineIndex = fileName.IndexOf('_');

		//添加第一级版块书签及跳转链接
        tmpModule = fileName.Substring(0, underlineIndex);
        tmpOutline = rootOutline.AddOutline(tmpModule);
        tmpOutline.AddDestination(PdfExplicitDestination.CreateFit(pdfDoc.GetPage(curPageIndex)));
    }

	//添加第二级书签及跳转链接
    tmpSubOutline = tmpOutline.AddOutline(fileName.Substring(underlineIndex + 1));
    tmpSubOutline.AddDestination(PdfExplicitDestination.CreateFit(pdfDoc.GetPage(curPageIndex)));
    curPageIndex += doc.docu.GetNumberOfPages();
}

程序的运行效果及最终的PDF文档效果如下图所示。SqlSugar官网帮助文档的合并PDF文件已上传到资源中,待审核后即可下载使用,有需要的可以自行下载。

参考文献:

1\]https://itextpdf.com/ \[2\]https://github.com/itext/itext-dotnet \[3\]https://blog.csdn.net/qq_38628970/article/details/135478244 \[4\]https://github.com/itext/itext-publications-samples-dotnet/blob/master/itext/itext.samples/itext/samples/sandbox/merge/MergeWithOutlines.cs \[5\]https://blog.csdn.net/rebecca_cao/article/details/135185043

相关推荐
MyBFuture8 小时前
C#数组详解:一维二维与交错数组
开发语言·windows·c#·visual studio·vision pro
有来技术9 小时前
ASP.NET Core 权限管理系统(RBAC)设计与实现|vue3-element-admin .NET 后端
vue.js·后端·c#·asp.net·.net
开开心心_Every9 小时前
家常菜谱软件推荐:分类齐全无广告步骤详细
linux·运维·服务器·华为od·edge·pdf·华为云
开开心心就好9 小时前
键盘映射工具改键位,绿色版设置后重启生效
网络·windows·tcp/ip·pdf·计算机外设·电脑·excel
cuber膜拜10 小时前
Marp CLI快速入门
pdf·npm·markdown·ppt·marp
reasonsummer10 小时前
【办公类-53-09】20260131Python模仿制作2025学年第二学期校历(excel+pdf)
python·pdf
张人玉11 小时前
C#WinFrom中show和ShowDialog的区别
开发语言·microsoft·c#
m0_7482331711 小时前
C#:微软的现代编程利器
开发语言·microsoft·c#
Traced back11 小时前
SQL Server数据自动清理系统最终版(C# WinForms完整源码)
数据库·c#·.net
心语星光11 小时前
用python语言的pyautogui库实现伪批量将xdf文件打印为pdf文件
开发语言·python·pdf·自动化