使用C#编辑PDF文本:如何查找并隐藏/删除指定文本短语?
搞定PDF特定短语隐藏/删除的实用方案
我之前也碰到过类似的PDF文本处理需求,你提到的iTextSharp(现在推荐用它的升级版本iText 7)和Spire其实都有可行的解决办法,可能是之前没找对正确的用法,给你整理几个亲测有效的方案:
一、用iText 7(替代旧版iTextSharp)
iTextSharp已经停止维护了,换成iText 7会更稳定可靠。核心思路是遍历PDF里的每个文本块,找到目标短语后,要么用白色覆盖它(相当于隐藏),要么直接移除文本内容。
方案1:用白色覆盖隐藏短语
这种方法简单直接,适合大多数原生PDF(能复制文本的那种),把目标短语所在的区域涂成白色,视觉上就看不到了。
C#代码示例:
using iText.Kernel.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; public class PdfTextHider : IEventListener { private readonly PdfDocument _pdfDoc; private readonly string _targetPhrase; private readonly List<Rectangle> _matchAreas = new List<Rectangle>(); public PdfTextHider(PdfDocument doc, string targetPhrase) { _pdfDoc = doc; _targetPhrase = targetPhrase; } public void EventOccurred(IEventData data, EventType type) { if (type != EventType.RENDER_TEXT) return; var renderInfo = (TextRenderInfo)data; var text = renderInfo.GetText(); if (text.Contains(_targetPhrase)) { // 获取短语对应的页面矩形区域 var phraseRect = renderInfo.GetDescentLine().GetBoundingRectangle(); _matchAreas.Add(phraseRect); } } public ICollection<EventType> GetSupportedEvents() { return new List<EventType> { EventType.RENDER_TEXT }; } public void HideTargetPhrases() { foreach (var page in _pdfDoc.GetPages()) { _matchAreas.Clear(); var processor = new PdfCanvasProcessor(this); processor.ProcessPageContent(page); // 用白色矩形覆盖匹配到的区域 var canvas = new PdfCanvas(page.NewContentStreamBefore(), page.GetResources(), _pdfDoc); canvas.SetFillColor(iText.Kernel.Colors.ColorConstants.WHITE); foreach (var rect in _matchAreas) { canvas.Rectangle(rect); canvas.Fill(); } } } } // 使用方式 using (var pdfDoc = new PdfDocument(new PdfReader("你的输入文件.pdf"), new PdfWriter("处理后的文件.pdf"))) { var hider = new PdfTextHider(pdfDoc, "Hello World"); hider.HideTargetPhrases(); }
方案2:彻底删除文本内容
如果不想只是视觉隐藏,要彻底从PDF内容流里删掉目标短语,就得操作PDF的底层内容流了,稍微复杂一点,但更彻底。
C#代码示例:
using iText.Kernel.Pdf; using iText.Kernel.Pdf.Canvas; using iText.Kernel.Pdf.Canvas.Parser.Util; using System.Collections.Generic; public class TextRemover : PdfCanvasEditor { private readonly string _targetPhrase; private readonly StringBuilder _currentText = new StringBuilder(); public TextRemover(string targetPhrase) { _targetPhrase = targetPhrase; } public override void Write(PdfCanvasProcessor processor, PdfLiteral operatorLit, List<PdfObject> operands) { var op = operatorLit.ToString(); if (op.Equals("Tj") || op.Equals("TJ")) { var text = PdfContentByteUtils.GetContentText(operands); _currentText.Append(text); // 如果当前文本不包含目标短语,才保留这个文本操作 if (!_currentText.ToString().Contains(_targetPhrase)) { base.Write(processor, operatorLit, operands); } else { // 清空缓存,避免后续匹配混乱 _currentText.Clear(); } } else { base.Write(processor, operatorLit, operands); } } } // 使用方式 using (var pdfDoc = new PdfDocument(new PdfReader("你的输入文件.pdf"), new PdfWriter("处理后的文件.pdf"))) { var remover = new TextRemover("Hello World"); foreach (var page in pdfDoc.GetPages()) { remover.EditPage(page); } }
二、用Spire.PDF的正确操作方法
你之前用Spire没成功,大概率是没用到它专门的文本替换工具类。Spire.PDF提供了PdfTextReplacer,可以直接把目标短语替换为空字符串,相当于删除。
C#代码示例:
using Spire.Pdf; using Spire.Pdf.Text; class Program { static void Main(string[] args) { var pdf = new PdfDocument(); pdf.LoadFromFile("你的输入文件.pdf"); // 创建文本替换器 var replacer = new PdfTextReplacer(pdf); // 把目标短语替换成空,就是删除的效果 replacer.Replace("Hello World", string.Empty); pdf.SaveToFile("处理后的文件.pdf"); pdf.Close(); } }
小提示:Spire的免费版有页数限制,如果是大文件可能需要商业版,或者测试的时候用小文件先验证效果。另外,如果PDF布局复杂,还可以设置
ReplacerOptions来提升匹配的准确性。
三、特殊情况:扫描版PDF
如果你的PDF是扫描件(本质是图片),上面的方法都没用,因为没有可编辑的文本。这种情况需要先做OCR识别:
- 用工具提取PDF里的图片
- 用Tesseract OCR识别图片中的文本,定位到目标短语的位置
- 用白色覆盖图片中对应区域
- 把处理后的图片重新生成PDF
内容的提问来源于stack exchange,提问作者Karan Aggarwal
相关产品推荐
相关产品推荐

