使用iTextSharp编辑现有PDF文件

我有一个pdf文件,我正在使用以下编码将其转换为文本进行处理。

ITextExtractionStrategy strategy = new SimpleTextExtractionStrategy(); string currentText = PdfTextExtractor.GetTextFromPage(pdfReader, page, strategy); currentText = Encoding.UTF8.GetString(ASCIIEncoding.Convert(Encoding.Default, Encoding.UTF8, Encoding.Default.GetBytes(currentText))); 

在处理期间,如果我在内容中看到任何类型的歧义意味着PDF文件的数据中的错误,我必须标记pdf的整行(颜色与红色的行)文件,但我无法分析如何实现这一点。 请帮我。

正如评论中已经提到的: 您基本上需要的是SimpleTextExtractionStrategy替换,它不仅返回文本,而且还返回带位置的文本。 LocationTextExtractionStrategy将是一个很好的起点,因为它收集带有位置的文本(按正确的顺序排列)。

如果您查看LocationTextExtractionStrategy的源代码,您会看到它将其文本片段保存在成员List locationalResultTextChunkLocationTextExtractionStrategy内部类)表示具有位置信息的文本块(最初由单个文本绘制操作绘制)。 在GetResultantText此列表已排序(从上到下,从左到右,全部相对于文本基线)并缩减为字符串。

你需要的是类似于LocationTextExtractionStrategy东西,区别在于你检索(排序的)文本片段, 包括它们的位置

不幸的是, locationalResult成员是private 。 如果它至少protected ,您可以简单地从LocationTextExtractionStrategy派生出新策略。 相反,你现在必须复制它的源来添加它(或做一些内省/reflection魔术)。

您的添加将是一个类似于GetResultantText的新方法。 此方法可能会识别同一行上的所有文本(就像GetResultantText那样),也可以识别

  • 进行分析/搜索歧义本身并返回任何找到的歧义的位置列表(开始和结束); 要么

  • 将当前行找到的文本与该行的有效开始和结束位置一起放入单个TextChunk实例中,并最终返回List每个都代表一个文本行; 如果你这样做,调用代码将进行分析以找到歧义,如果找到歧义,则它具有歧义所在的行的起始和结束位置。 请注意,原始策略中的TextChunk protected但您需要将此方法public

无论哪种方式,您最终都会得到歧义的开始和结束位置,或者至少有歧义所在的行。 现在你必须突出显示有问题的行(正如你所说,你必须标记pdf的整行(用红色表示颜色) )。

要操作给定的PDF,请使用PdfStamper 。 您可以在页面上标记一行

  • PdfStamper获取该页面的PdfStamper并使用您的位置数据填充红色矩形; 这种方法的这个缺点是,如果原始PDF已经在填充区域的线上进行了衬底,那么你的标记将隐藏在其中; 或者

  • PdfStamper获取该页面的PdfStamper并用红色填充一个有点透明的矩形; 或者

  • 向页面添加高亮注释

为了使事情更顺畅,您可能希望扩展TextChunk的副本( LocationTextExtractionStrategy副本中的内部类),不仅要保留基线坐标,还要保持使用的字形的最大上升和下降。 显然你必须在RenderText填写这些信息……

这样,您就可以确切地知道标记矩形所需的高度。

评论太久了; 添加为答案。

我的好伙伴和同行阿迪,这在很大程度上取决于你的PDF内容。 对这样的事情做一个通用的解决方案很难。 currentText包含什么? 你能举个例子吗? 此外,如果您要检查大量这些PDF,则需要获取其中一些PDF的currentText ,以确保您当前的PDF到字符串转换每次都会产生相同的结果。 如果每次来自不同的PDF,它是相同的; 然后你就可以开始自动化了。

自动化也很大程度上取决于你的内容,例如,如果当前的Text是这样的: Value: 10\nValue: 11\nValue: 9Value\n15那么我推荐的是通过每一行,提取值并检查它你需要它是什么。 这是未经测试的半伪代码,可让您了解我的意思:

 var lines = new List(currentText.Split('\n')); var newlines = new List(); foreach (var line in lines) { if (line != "Value: 10") { newLines.Add(line); // This line is correct, no marking needed } else { newlines.Add("THIS IS WRONG: " + line); // Mark as incorrect; use whatever you need here } } // Next, return newlines to the user showing them which lines are bad so they can edit the PDF 

如果您需要自动编辑现有PDF,这将是非常非常非常困难的。 我认为这超出了我的答案范围 – 我正在回答如何识别错误的行而不是如何标记它们 – 抱歉! 别人请加上答案。

顺便说说; 对于做这样的事情,PDF不是一个好的格式。 如果您可以访问任何其他信息来源,则很可能另一个信息来源更好。