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

时间:2017-02-06 17:25:32

标签: pdf itext text-extraction

使用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页的前几行写为:

  
    

外国资产管理办公室特别指定的国民和被封锁的人2017年2月3日 - 2 - A.A. RASPLET IN; a .k。     一个。 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     公司' IMENI学术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 ANY     ALMAZ -AN TEY PVO C ONCERN I MEN I Acadeician A .A。 RASPLE TIN;     A.K.一个。 JO INT STOCK C OMPANY LMA Z-AN TEY AI R DEFENSE CON CERN     硕士学位设计学院由ACADE MICIAN A.A。

命名   

例如,参见单词" JO INT"在第四&第6行,和#34; CON CERN"在第二行到最后一行。这些类型的空间出现在整个结果中。不幸的是,这将使得查询文本成为不可能。

有没有人知道为什么会这样做以及如何解决这个问题?

1 个答案:

答案 0 :(得分:2)

为什么会这样做

原因实际上是文本提取策略的一个特性,在您的情况下无法正常工作。

一些背景:你认为PDF文件中的单词之间的空格不一定是由于绘制空格字符的指令而产生的,它也可能是一个结果指令将文本插入位置向右移动。因此,文本提取策略通常在找到像这样的足够大的右移时添加空格字符。对于这方面的更多内容(特别是“足够大”的部分),例如this answer

如果是你的文档,文本正文字体的字体宽度信息太小(如果按原样使用,字符会粘在一起,中间没有任何空格);因此,在每对连续字符之间存在小的右移,其中一些移位宽度足以通过上述机制错误地识别为字分离。

如何解决此问题

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

您可以通过复制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);
    }

    [...]
}

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