使用iTextSharp从PDF中提取文本不适用于某些PDF

时间:2016-01-28 18:19:42

标签: c# pdf itextsharp pdftotext

我使用以下代码从iTextSharp中提取PDF文件第一页的文本:

public static string ExtractTextFromPDFFirstPage(string fileName)
{
    string text = null;
    using (var pdfReader = new PdfReader(fileName))
    {
        ITextExtractionStrategy strategy = new SimpleTextExtractionStrategy();

        text = PdfTextExtractor.GetTextFromPage(pdfReader,1,strategy);

        text = Encoding.UTF8.GetString(Encoding.Convert(Encoding.Default, Encoding.UTF8, Encoding.Default.GetBytes(text)));

    }
    return text;
}

它适用于许多PDF,但不适用于其他一些PDF。

工作PDF:http://data.hexagosoft.com/LFBO.pdf

不工作PDF:http://data.hexagosoft.com/LFBP.pdf

这两个PDF看起来非常相似,但一个是有效的,另一个不是。 我猜他们的制作者标签不一样的事实是一个线索。 另一个线索是,此功能适用于没有图表的PDF的任何其他页面。

我也尝试过ghostscipt,没有成功。

编码线似乎也没用。

如何使用iTextSharp提取非工作PDF的第一页文本?

由于

2 个答案:

答案 0 :(得分:0)

这两个文档在其编码/差异数组中使用具有非官方字形名称的字体,并且两者都不使用ToUnicode映射。字形命名似乎有些直接:MT前缀后面的数字是使用的字形的ASCII码。

第一个文档有效,因为映射完全没有改变,iText将使用默认编码(我猜):

/Differences[65/MT65/MT66/MT67 71/MT71/MT72/MT73 76/MT76 78/MT78 83/MT83]

另一个文档确实改变了映射:

/Differences [2 /MT76 /MT105 /MT103 /MT104 /MT116 /MT110 /MT32 /MT97 /MT100 /MT115 /MT58 ]

这意味着:例如字符代码2应映射到名为MT76的字形,这是iText不知道的非官方/私有字形名称,因此它没有更多信息,但字符代码2将使用此代码作为最终结果(I猜测)。

如果没有为MT前缀字形名称实现逻辑,则无法从此文档中获取正确的文本。无论如何,无法定义以MT开头,后跟整数的字形名称可以映射到ASCII值......这只是偶然或由字体设计器/创建工具实现,无论它来自何处。

答案 1 :(得分:0)

第二个PDF(LFBP.pdf)包含从字形到文本的不正确映射,即您看到正确的字形,但在生成此PDF期间由于某种原因未正确编码文本表示。如果你有很多像这样的文件,那么工作方法可能是:

  • 通过搜索应出现在每个页面上的一些短语来提取文本时检测损坏的页面,可能像“service”
  • 使用OCR与Tesseract with .NET Wraper
  • 等工具分别处理这些页面