PDF 到文本:iTextSharp:提取结果中的重复页面

PDF to Text: iTextSharp: Duplicate Pages in Extraction Results

提前致谢。

背景:

我正在开发一个从 pdf 文档的特定部分提取数据的控制台应用程序。为此,我首先需要将该 pdf 转换为要使用的字符串。为此,我求助于 iTextSharp。 pdf 布局为每页两列,因此我使用的是 SimpleTextExtractionStratgey()(我尝试了 iTextSharp.text.pdf.parser.LocationTextExtractionStrategy();但发现它对页面布局无效)。

正在转换为文本的内容说明:

我似乎遇到问题的页面在页面的一侧张贴了 "header"。包含 header 的页面间歇性地分散在文档中。

页面布局图片:http://postimg.org/image/b7i25v0g1/

问题:

似乎当它浏览完页面上的列然后移动到那一侧时 header。然后它会跳转到下一个页面 header,将其转换为文本,然后从遇到第一个 header 的页面顶部重新开始。

我最终得到的文本如下所示:

第 1 页内容

第一个Header

第二个Header

第 1 页内容

第 2 页内容

这是 pdf:http://www.filedropper.com/dd35-completeadventurer

我没有使用 iTextSharp 我只是需要一种可靠的方法来将这种格式的文档转换为文本。解决方法或替代方法将不胜感激。

    static public string ToTxt(string @filePath)
    {
        string strText = string.Empty;
        try
        {
            PdfReader reader = new PdfReader(filePath);

            for (int page = 1; page <= reader.NumberOfPages; page++)
            {

                Widgets.ProgressBar(page);

                //Convert PDF to Text
                ITextExtractionStrategy its = new SimpleTextExtractionStrategy(); //iTextSharp.text.pdf.parser.LocationTextExtractionStrategy();
                String s = PdfTextExtractor.GetTextFromPage(reader, page, its);
                strText = strText + s;
            }
            reader.Close();
            Console.WriteLine("File Extracted");
        }
        catch (Exception e)
        {
            Console.WriteLine("Exception: " + e.Message);
        }
        finally
        {
            Console.Clear();
        }
        return strText;
     }

正如评论中已经推测的那样,PDF 内容中已经存在重复文本!

详情

你的文档中对页的页面内容往往是完全相同的,每次都是整张的内容,而单独的页面仅仅显示只剩下或右半部分。

例如考虑第 6 和第 7 页。它们的内容相同:

填充它们相同的区域MediaBox。只需设置 CropBox(以及 ArtBoxBleedBoxTrimBox) 分别向左或右半部分显示第 6 页的预期内容:

和第 7 页:

iText(Sharp) 解析器框架和 SimpleTextExtractionStrategy 都不会自动限制到这些框,它们会提取内容中任何位置绘制的所有文本。因此,重复文本。

防止提取结果中的重复文本

了解文本重复的原因,有多种方法可以防止它:

  1. 您可以尝试只提取所有其他 PDF 页面的内容。不幸的是,上面所说的并非对所有页面都是正确的,至少初始页面(标题页,内容,...)不是使用上面解释的方案创建的,并且在本书的后面有一些艺术品页面也没有遵循该方案.因此,此选项需要对异常页面进行相当多的管理。

  2. 您可以提取每个页面的内容,但将先前处理的页面的内容保留在某个变量中。现在只将新提取的内容添加到结果中,如果它不等于前一页的内容。

  3. 您可以使用 iText(Sharp) 解析器过滤器。如果将策略处理的文本块限制为仅在当前页面的裁剪框中绘制的文本块,则可以防止由 off-page 内容引起的重复文本。您可以在此处找到按区域过滤的示例:ExtractPageContentArea.java / ExtractPageContentArea.cs.

使用 mkl 的第二种方法(检查每一页是否重复)我想出了以下方法并且效果很好;一个简单的修复:

    string strText = string.Empty;
        try
        {
            PdfReader reader = new PdfReader(filePath);
            string prevPage = "";
            for (int page = 1; page <= reader.NumberOfPages; page++)
            {
                Widgets.ProgressBar(page);
                //Convert PDF to Text
                ITextExtractionStrategy its = new SimpleTextExtractionStrategy();
                String s = PdfTextExtractor.GetTextFromPage(reader, page, its);
                if (prevPage != s)
                    strText += s;
                prevPage = s;
            }
            reader.Close();
            Console.WriteLine("File Extracted");
        }
        catch (Exception e)
        {
            Console.WriteLine("Exception: " + e.Message);
        }
        finally
        {
            Console.Clear();
        }
        return strText;
    }