如何获取PDF文档中内部跳转(GoTo动作)链接的目标页面及矩形区域?
如何获取PDF文档中内部跳转(GoTo动作)链接的目标页面及矩形区域?
嘿,你已经把基础工作做好了——成功定位到PDF页面上的Link注解,接下来只需要解析它的GoTo动作就能拿到你要的目标页面和矩形信息啦。我来帮你把代码补全,还会给你讲清楚每一步的逻辑:
public static void GetLinks(PdfDocument pdfDocument, int page) { // 获取目标页面上的所有注解 IList<PdfAnnotation> annotations = pdfDocument.GetPage(page).GetAnnotations(); // 遍历所有注解 foreach (PdfAnnotation annotation in annotations) { // 筛选出Link类型的注解 if (annotation.GetSubtype() == PdfName.Link) { PdfLinkAnnotation linkAnnotation = annotation as PdfLinkAnnotation; if (linkAnnotation == null) continue; // 获取该链接的动作 PdfAction action = linkAnnotation.GetAction(); if (action == null) continue; // 只处理内部跳转的GoTo动作(排除外部链接URI等其他类型) if (action.GetSubtype() == PdfName.GoTo) { // 获取GoTo动作的目标数组 PdfArray destArray = action.Get(PdfName.D) as PdfArray; if (destArray == null || destArray.Count < 2) continue; // 解析目标页面:数组第一个元素是目标页的字典对象 PdfDictionary targetPageDict = destArray.GetAsDictionary(0); int destinationPageNo = pdfDocument.GetPageNumber(targetPageDict); // 解析目标矩形/定位坐标:根据GoTo动作的不同目标类型处理 float[] targetRect = null; PdfName destType = destArray.GetAsName(1); // 处理FitR类型:直接返回目标矩形的四个坐标(左、下、右、上) if (destType == PdfName.FitR) { if (destArray.Count >= 6) { targetRect = new float[] { destArray.GetAsNumber(2).FloatValue, destArray.GetAsNumber(3).FloatValue, destArray.GetAsNumber(4).FloatValue, destArray.GetAsNumber(5).FloatValue }; } } // 处理XYZ类型:返回锚点坐标(x,y),可以结合页面尺寸生成默认矩形 else if (destType == PdfName.XYZ) { float x = destArray.GetAsNumber(2).FloatValue; float y = destArray.GetAsNumber(3).FloatValue; // 这里可以自定义矩形的宽高,比如取50x50的区域 targetRect = new float[] { x, y - 25, x + 50, y + 25 }; } // 其他类型比如Fit、FitH等可以根据需求补充处理 else { // 如果是Fit(适配整页),目标矩形就是整个页面的尺寸 PdfPage targetPage = pdfDocument.GetPage(destinationPageNo); Rectangle pageSize = targetPage.GetPageSize(); targetRect = new float[] { pageSize.GetLeft(), pageSize.GetBottom(), pageSize.GetRight(), pageSize.GetTop() }; } // 现在你可以使用拿到的信息了 Console.WriteLine($"源矩形: {annotation.GetRectangle()}"); Console.WriteLine($"目标页码: {destinationPageNo}"); if (targetRect != null) { Console.WriteLine($"目标矩形: 左={targetRect[0]}, 下={targetRect[1]}, 右={targetRect[2]}, 上={targetRect[3]}"); } } } } }
一些需要注意的细节:
- 不是所有Link注解都是内部跳转:有些是外部链接(
PdfName.URI类型的动作),所以一定要先判断动作子类型是PdfName.GoTo - GoTo动作的目标格式有多种:PDF规范里定义了Fit、FitH、FitV、FitR、XYZ等多种视图模式,上面的代码覆盖了最常见的几种,你可以根据自己的需求扩展其他类型
- 目标页的解析:PDF里的目标页通常是用页字典对象存储的,通过
pdfDocument.GetPageNumber()可以把字典转换成我们熟悉的页码 - 坐标系统:PDF的坐标原点在页面左下角,和我们日常的屏幕坐标(左上角为原点)不一样,处理的时候要注意转换
内容来源于stack exchange
相关产品推荐
相关产品推荐

