6

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 も試しましたが、効果はありませんでした。

4

2 に答える 2

8

原因

OPによって提供されたファイルを調べると、問題は実際にそこにある余分なスペースが原因であることがわかりました! 同じ開始位置から複数の文字列が引き出されています。すべての位置で、これらの文字列の最大 1 つにスペース以外の文字が含まれています。したがって、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 ビューアでは、次のように表示されます。

スクリーンショット

Adobe 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 に問題があるだけでなく、これら 2 つの出力は異なって見えますが、いずれにしても余分なスペースが問題になります。

これらの PDF の作成者に、Adobe 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 がテキスト文字列を抽出するためです。この手順には独自の危険がありますが、この場合、すぐに使用できるより使いやすいものになります。

于 2015-06-24T17:48:06.923 に答える