C# VSTO中基于iText提取PDF可点击链接及对应文本
提取PDF中链接及对应文本(iText实现)
你已经能提取PDF中的URI链接,但链接对应的文本并不存储在链接注释本身中,而是位于注释覆盖的页面矩形区域内。需要通过获取注释的位置矩形,提取该区域内的页面文本。
实现步骤与代码
首先定义一个类来存储链接和对应文本:
public class LinkWithText { public string Uri { get; set; } public string Text { get; set; } }
修改原方法,加入文本提取逻辑:
using iText.Kernel.Pdf; using iText.Kernel.Pdf.Annot; using iText.Kernel.Geom; using iText.Kernel.Pdf.Canvas.Parser; using iText.Kernel.Pdf.Canvas.Parser.Filter; using iText.Kernel.Pdf.Canvas.Parser.Listener; using System.Collections.Generic; public static List<LinkWithText> LinkWithTextCollector(string pdfPath) { List<LinkWithText> linkWithTextList = new List<LinkWithText>(); using var reader = new PdfReader(pdfPath); using var pdfDoc = new PdfDocument(reader); for (int pageNum = 1; pageNum <= pdfDoc.GetNumberOfPages(); pageNum++) { PdfPage page = pdfDoc.GetPage(pageNum); var annotList = page.GetAnnotations(); foreach (var annot in annotList) { // 仅处理链接类型注释 if (annot.GetSubtype() != PdfName.Link) continue; PdfDictionary annotDict = annot.GetPdfObject() as PdfDictionary; if (annotDict == null) continue; PdfDictionary linkAction = annotDict.GetAsDictionary(PdfName.A); // 仅处理URI类型的链接动作 if (linkAction == null || linkAction.Get(PdfName.S) != PdfName.URI) continue; // 获取链接地址 string uri = linkAction.GetAsString(PdfName.URI).ToString(); // 获取链接注释覆盖的矩形区域 PdfArray rectArray = annotDict.GetAsArray(PdfName.Rect); if (rectArray == null) continue; // 转换为iText矩形对象(PDF坐标原点在左下角,无需额外转换) float llx = rectArray.GetAsNumber(0).FloatValue; float lly = rectArray.GetAsNumber(1).FloatValue; float urx = rectArray.GetAsNumber(2).FloatValue; float ury = rectArray.GetAsNumber(3).FloatValue; Rectangle linkRect = new Rectangle(llx, lly, urx, ury); // 提取矩形区域内的文本 LocationTextExtractionStrategy textStrategy = new LocationTextExtractionStrategy(); FilteredTextEventListener filteredListener = new FilteredTextEventListener( textStrategy, new TextRegionEventFilter(linkRect)); PdfCanvasProcessor processor = new PdfCanvasProcessor(filteredListener); processor.ProcessPageContent(page); string linkText = textStrategy.GetResultantText().Trim(); linkWithTextList.Add(new LinkWithText { Uri = uri, Text = linkText }); } } return linkWithTextList; }
关键逻辑说明
- 过滤有效注释:通过判断注释子类型为
PdfName.Link、动作类型为PdfName.URI,确保只处理目标链接注释。 - 获取覆盖区域:从注释字典的
PdfName.Rect键提取链接覆盖的页面坐标,转换为Rectangle对象。 - 区域文本提取:使用
FilteredTextEventListener结合TextRegionEventFilter,仅提取指定矩形范围内的文本,避免获取页面其他无关内容。
内容的提问来源于stack exchange,提问作者ThibaultKm
相关产品推荐
相关产品推荐

