iTextSharp 在 pdf 文件的单词中插入空格

iTextSharp inserting spaces within words from a pdf file

我正在尝试使用 iTextSharp 从以下 pdf 文件中提取文本:

https://www.treasury.gov/ofac/downloads/sdnlist.pdf

这是代码:

var currentText = PdfTextExtractor.GetTextFromPage(pdfReader, 2, new SimpleTextExtractionStrategy());
                   if (currentText.Length > 0)
                            {
                                var capture = new Capture();
                                capture.Text = currentText;

                                // write the results to the DB, if any data was found
                                _dataService.AddCapture(capture);
                            }

使用 SimpleTextExtractionStrategy,将结果写入数据库,并在单词中包含无数不需要的空格。第2页的前几行写为:

OFFICE OF FOREIGN ASSETS CONTROL SPECIALLY DESIGNATED NATIONALS & BLOCKED PERSONS February 3, 2017 - 2 - A.A. RASPLET IN; a .k. a. AL MAZ -AN TEY MSDB; a .k.a . AL MAZ -ANTEY PV O 'AI R DEFENSE' CO NCERN LEAD SYSTE M S DESIGN BUREAU OAO ' OPEN JO INT -STOCK COMPANY' IMENI ACADEMIC IAN A.A . RASPLETIN; a.k .a. GO LOVNOYE SISTEMN OYE KONS TRUKT ORSKOY E BYURO OPEN J OIN T-S TOCK C OMP ANY OF ALMAZ -AN TEY PVO C ONCERN I MEN I ACADEMICIAN A .A. RASPLE TIN; a.k. a. JO INT STOCK C OMPANY A LMA Z-AN TEY AI R DEFENSE CON CERN MA IN SYSTE M DESIGN BUREAU NAMED BY ACADE MICIAN A.A.

例如第 4 行和第 6 行中的单词 "JO INT",以及倒数第二行中的单词 "CON CERN"。这些类型的空间出现在整个结果中。不幸的是,这将使查询文本变得不可能。

有谁知道为什么会这样以及如何解决这个问题吗?

为什么会这样

原因实际上是文本提取策略的一个功能,在您的情况下无法按预期工作。

一些背景知识:您认为 PDF 文件中单词之间的 space 不一定是由于指令 绘制 space 字符,它也可以是指令将文本插入位置稍微向右移动的结果。因此,文本提取策略通常会在找到足够大的 right-shift 字符时添加一个 space 字符。有关此的更多信息(特别是“足够大”的部分),例如this answer.

不过,对于您的文档,正文字体的字体宽度信息太小(如果按原样使用,字符看起来粘在一起,没有任何 space in-between);因此,在每对连续字符之间有小的右移,其中一些移宽到足以被上述机制错误地识别为单词分隔。

如何解决这个问题

由于 PDF 中的单词分隔是由绘制 space 字符的指令创建的,因此您不需要上述功能。因此,解决该问题的最简单方法是使用没有该功能的文本提取策略。

您可以通过复制 SimpleTextExtractionStrategy 的源代码(例如来自 here)并注释掉方法 RenderText 中的一些行来创建这样的策略,如下所示:

public virtual void RenderText(TextRenderInfo renderInfo)
{
    [...]

    if (hardReturn)
    {
        //System.out.Println("<< Hard Return >>");
        AppendTextChunk('\n');
    }
    else if (!firstRender)
    {
//        if (result[result.Length - 1] != ' ' && renderInfo.GetText().Length > 0 && renderInfo.GetText()[0] != ' ')
//        { // we only insert a blank space if the trailing character of the previous string wasn't a space, and the leading character of the current string isn't a space
//            float spacing = lastEnd.Subtract(start).Length;
//            if (spacing > renderInfo.GetSingleSpaceWidth() / 2f)
//            {
//                AppendTextChunk(' ');
//                //System.out.Println("Inserting implied space before '" + renderInfo.GetText() + "'");
//            }
//        }
    }
    else
    {
        //System.out.Println("Displaying first string of content '" + text + "' :: x1 = " + x1);
    }

    [...]
}

使用这种简化的提取策略,可以正确提取您的文本。