You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过iText7的RegexBasedLocationExtractionStrategy获取匹配文本的字体名与字号

解决iText7中提取文本时同时获取字体名称和字号的问题

要拿到匹配文本的字体名称和字号,你得自定义一个文本提取策略,继承RegexBasedLocationExtractionStrategy并扩展功能,在处理文本渲染事件时捕获字体属性。

实现步骤

  • 自定义提取策略类:重写事件处理方法,记录每个匹配文本片段的字体名称、字号,同时保留原有的位置信息。
  • 使用自定义策略提取信息:实例化自定义策略,传入正则表达式,遍历PDF页面获取所有匹配片段的完整信息。
  • 基于提取的信息进行文本替换:利用获取到的字体和位置信息,生成新的文本覆盖原位置。

代码示例

自定义提取策略类

using iText.Kernel.Pdf.Canvas.Parser;
using iText.Kernel.Pdf.Canvas.Parser.Data;
using iText.Kernel.Pdf.Canvas.Parser.Listener;
using System.Collections.Generic;
using System.Text.RegularExpressions;

public class RegexWithFontExtractionStrategy : RegexBasedLocationExtractionStrategy
{
    // 存储匹配到的文本的完整信息
    public List<TextWithFontInfo> MatchedTextInfos { get; } = new List<TextWithFontInfo>();

    public RegexWithFontExtractionStrategy(Regex regex) : base(regex)
    {
    }

    public override void EventOccurred(IEventData data, EventType type)
    {
        base.EventOccurred(data, type);

        if (type == EventType.RENDER_TEXT)
        {
            TextRenderInfo renderInfo = (TextRenderInfo)data;
            string text = renderInfo.GetText();

            // 检查当前文本片段是否匹配正则
            Match match = GetRegex().Match(text);
            if (match.Success)
            {
                // 获取字体名称和字号
                string fontName = renderInfo.GetFont().GetFontProgram().GetFontNames().GetFontName();
                float fontSize = renderInfo.GetFontSize();
                // 获取文本位置矩形
                var rect = renderInfo.GetDescentLine().GetBoundingRectangle();

                MatchedTextInfos.Add(new TextWithFontInfo
                {
                    Text = match.Value,
                    BoundingRect = rect,
                    FontName = fontName,
                    FontSize = fontSize
                });
            }
        }
    }
}

// 存储文本及字体信息的实体类
public class TextWithFontInfo
{
    public string Text { get; set; }
    public iText.Kernel.Geom.Rectangle BoundingRect { get; set; }
    public string FontName { get; set; }
    public float FontSize { get; set; }
}

使用自定义策略提取并替换文本

using iText.Kernel.Pdf;
using iText.Kernel.Pdf.Canvas;
using iText.Layout;
using iText.Layout.Element;
using iText.Layout.Properties;

// 读取原PDF并创建输出PDF
PdfReader reader = new PdfReader("input.pdf");
PdfWriter writer = new PdfWriter("output.pdf");
PdfDocument pdfDoc = new PdfDocument(reader, writer);

// 定义要搜索的正则表达式
Regex regex = new Regex("要替换的文本");

for (int pageNum = 1; pageNum <= pdfDoc.GetNumberOfPages(); pageNum++)
{
    PdfPage page = pdfDoc.GetPage(pageNum);
    // 实例化自定义提取策略
    RegexWithFontExtractionStrategy strategy = new RegexWithFontExtractionStrategy(regex);
    PdfCanvasProcessor processor = new PdfCanvasProcessor(strategy);
    processor.ProcessPageContent(page);

    // 遍历所有匹配的文本信息,执行替换
    foreach (var textInfo in strategy.MatchedTextInfos)
    {
        // 用白色矩形覆盖原文本
        PdfCanvas canvas = new PdfCanvas(page);
        canvas.SaveState()
              .SetFillColor(iText.Kernel.Colors.ColorConstants.WHITE)
              .Rectangle(textInfo.BoundingRect)
              .Fill()
              .RestoreState();

        // 使用原字体和字号添加替换后的文本
        Document doc = new Document(pdfDoc);
        Paragraph newText = new Paragraph("替换后的文本")
            .SetFontSize(textInfo.FontSize)
            .SetFont(textInfo.FontName)
            .SetFixedPosition(textInfo.BoundingRect.GetLeft(), textInfo.BoundingRect.GetBottom(), textInfo.BoundingRect.GetWidth());
        doc.Add(newText);
        doc.Close();
    }
}

// 关闭资源
pdfDoc.Close();
reader.Close();
writer.Close();

注意事项

  • 部分PDF中的字体是嵌入的子集,字体名称可能带有后缀(如ArialMT),这是正常现象,iText会正确识别。
  • 如果替换后的文本长度与原文本差异较大,需要调整矩形宽度或处理换行,避免内容溢出。
  • 确保已安装iText7相关NuGet包:iText7.Core、iText7.Layout。

内容的提问来源于stack exchange,提问作者zhusp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 06:05:32