Apache PDFBox 删除字符之间的空格

Posted

技术标签:

【中文标题】Apache PDFBox 删除字符之间的空格【英文标题】:Apache PDFBox Remove Spaces between characters 【发布时间】:2015-06-15 18:10:48 【问题描述】:

我们正在使用 PDFBox 从 PDF 中提取文本。

某些 PDF 的文本无法正确提取。 下图将 PDF 中的一部分显示为图像:

文本提取后,我们得到以下文本: 3, 8 5 EU R 1 Netto 38,50 EUR 4,00 (',' 和 '8' 之间添加空格)

这是我们的代码:

            PDDocument pdf = PDDocument.load(reuseableInputStream);
            PDFTextStripper pdfStripper = new PDFTextStripper();
            pdfStripper.setSortByPosition(true);
            String text = pdfStripper.getText(pdf);

我们尝试使用 PDFTextStripper 属性“AverageCharTolerance”和“SpacingTolerance”,但没有任何积极影响。

替代库“iText”正确提取文本,字符之间没有空格。但由于许可证问题,我们不能使用它。

有什么想法吗?谢谢。

编辑:我们使用的是 1.8.9 版。我们还尝试了快照版本 2.0.0,但没有任何效果。

【问题讨论】:

你能分享一个示例 PDF 吗?这样我们就可以看到文件中是否真的有空格字符(即使它们可能不显示)。 此文件为客户文件,对不起。我被禁止分享这些文件:/ 禁止共享此文档 - 恐怕在这种情况下,这里没有什么可做的。 我现在可以分享一个示例 PDF。请通过电子邮件与我联系 tobias.holke@trustpact.com。我将通过电子邮件发送。 您可以在我的个人资料中找到我的电子邮件地址,只需点击mkl。 【参考方案1】:

在较新版本的 PDFBox 上,该解决方法不起作用。 但是您可以修复问题空间并获得相同的结果,只需像这样设置您的 PDFTextStripper:

PDFTextStripper strippet = new PDFTextStripper();
stripper.setWordSeparator("");

【讨论】:

【参考方案2】:

原因

检查 OP 提供的文件,发现问题是由 实际存在的额外空格引起的!从同一个起始位置抽取多个字符串;在每个位置,这些字符串中最多有一个具有非空格字符。因此,PDF 查看器的输出看起来不错,但作为文本提取器的 PDFBox 会尝试利用找到的所有字符,包括那些额外的空格字符。

可以使用带有 F0Courier 的内容流的 PDF 重现该行为:

BT
/F0 9 Tf
100 500 Td
(             2                                                                  Netto        5,00 EUR 3,00) Tj
0 0 Td
(                2882892  ENERGIZE LR6 Industrial                     2,50 EUR 1) Tj
ET

在 PDF 查看器中如下所示:

从 Adob​​e Reader 复制和粘贴结果

2 2 8 8 2 8 9 2 E N E R G I Z E L R 6 I n d u s t r i a l 2 , 5 0 E U R 1 Netto 5,00 EUR 3,00

使用 PDFBox 进行常规提取会导致

             2    2 8 8 2 89 2    E N E RG  IZ  E  L R 6  I n du s t  ri  a l                      2 ,5  0  EU  R  1 Netto        5,00 EUR 3,00

因此,不仅 PDFBox 有问题,这两个输出看起来不同,但额外的空格都是问题。

我建议告诉这些 PDF 的制作者,它们很难进行后期处理,即使对于 Adob​​e Reader 等广泛使用的软件也是如此。

一种解决方法

要从中提取一些有意义的东西,我们必须以某种方式忽略(实际存在!)额外的空格。由于无法临时知道哪些空格可以稍后使用,哪些不可以,我们只需删除所有空格并希望 PDFBox 在必要时添加空格:

String extractNoSpaces(PDDocument document) throws IOException

    PDFTextStripper stripper = new PDFTextStripper()
    
        @Override
        protected void processTextPosition(TextPosition text)
        
            String character = text.getCharacter();
            if (character != null && character.trim().length() != 0)
                super.processTextPosition(text);
        
    ;
    stripper.setSortByPosition(true);
    return stripper.getText(document);

(ExtractWithoutExtraSpaces.java)

将此方法与我们得到的测试文档一起使用:

2 2882892 ENERGIZE LR6 Industrial 2,50 EUR 1 Netto 5,00 EUR 3,00

不同的文本提取器

替代库“iText”正确提取文本,字符之间没有空格

这是因为 iText 是逐个字符串而不是逐个字符地提取文本。此过程有其自身的危险,但在这种情况下会产生一些开箱即用的更有用的东西。

【讨论】:

你成就了我的一天!谢谢!

以上是关于Apache PDFBox 删除字符之间的空格的主要内容,如果未能解决你的问题,请参考以下文章

Apache PDFbox开发指南之PDF文档读取

转换为PNG时,Apache PDFBox删除水平线

删除字符串之间不需要的空格[重复]

使用 PDFbox 确定文档中单词的坐标

删除字符和单词之间的空格[重复]

仅用连字符替换单词之间的空格并删除所有其他空格[重复]