使用iTextSharp编辑现有PDF文件

时间:2014-02-20 08:08:34

标签: c# string pdf itextsharp itext

我有一个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的整行(颜色与红色一致)但我无法分析如何实现这一目标。请帮帮我。

2 个答案:

答案 0 :(得分:1)

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

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

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

var lines = new List<string>(currentText.Split('\n'));
var newlines = new List<string>();
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不是一个好的格式。如果您可以访问任何其他信息来源,则很可能另一个信息来源更好。

答案 1 :(得分:1)

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

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

你需要的是这样的LocationTextExtractionStrategy,区别在于你检索(排序的)文本片段,包括他们的位置

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

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

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

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

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

要操作给定的PDF,请使用PdfStamper。您可以通过

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

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

  • 在页面中添加突出显示注释

为了让事情变得更加顺畅,您可能希望将TextChunkLocationTextExtractionStrategy副本中的内部类)的副本扩展为不仅保留基线坐标,还要保持最大上升和下降使用的字形。显然你必须在RenderText ...

中填写这些信息

这样做可以准确了解标记矩形所需的高度。