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

相关推荐
军训猫猫头4 小时前
96.如何使用C#实现串口发送? C#例子
开发语言·c#
不爱写代码的玉子6 小时前
HALCON透视矩阵
人工智能·深度学习·线性代数·算法·计算机视觉·矩阵·c#
空中湖6 小时前
文档极速转换器 - 免费批量Word转PDF工具
pdf·word
沉到海底去吧Go7 小时前
【工具教程】PDF电子发票提取明细导出Excel表格,OFD电子发票行程单提取保存表格,具体操作流程
pdf·excel
开开心心就好8 小时前
高效Excel合并拆分软件
开发语言·javascript·c#·ocr·排序算法·excel·最小二乘法
一名用户10 小时前
unity实现自定义粒子系统
c#·unity3d·游戏开发
钢铁男儿12 小时前
C# 类和继承(扩展方法)
java·servlet·c#
爱炸薯条的小朋友12 小时前
C#由于获取WPF窗口名称造成的异常报错问题
windows·c#·wpf
Rose 使者14 小时前
全球IP归属地查询接口如何用C#进行调用?
c#·api·ip地址
~plus~16 小时前
Harmony核心:动态方法修补与.NET游戏Mod开发
开发语言·jvm·经验分享·后端·程序人生·c#