web-dev-qa-db-ja.com

上級PDFパーサーJava

JavaのPDFファイルから異なるコンテンツを抽出したい:

  • 完全な表示テキスト
  • 画像
  • リンク

次のものを入手することもできますか?

  • タイトル、説明、作成者などのドキュメントメタタグ
  • 見出しのみ
  • ドキュメントにフォームが含まれている場合は入力要素

PDFファイルを操作またはレンダリングする必要はありません。そのような目的に最適なライブラリはどれですか?

[〜#〜]更新[〜#〜]

OK、私はPDFBoxを試しました:

Document luceneDocument = LucenePDFDocument.getDocument(new File(path));
Field contents = luceneDocument.getField("contents");
System.out.println(contents.stringValue());

しかし、出力はnullです。 「概要」フィールドは問題ありませんが。

次のスニペットは正常に動作します。

PDDocument doc = PDDocument.load(path);
PDFTextStripper stripper = new PDFTextStripper();
String text = stripper.getText(doc);
System.out.println(text);
doc.close();

しかし、それでは、画像やリンクなどを抽出する方法がわかりません。

更新2

私は画像を抽出する方法の例を見つけましたが、それでも抽出する方法について答えがありませんでした:

  • リンク
  • タイトル、説明、作成者などのドキュメントメタタグ
  • 見出しのみ
  • ドキュメントにフォームが含まれている場合は入力要素
17
Alp

iText は最近の私のPDF最適なツールです。

  • 完全な表示テキスト

「目に見える」は厳しいものです。すべての解析可能なテキストをcom.itextpdf.text.pdf.parseパッケージのクラスで解析できますが、それらのクラスはCLIPPINGを認識していません。パーサーをページサイズに簡単に制限できます。

_// all text on the page, regardless of position
PdfTextExtractor.getTextFromPage(reader, pageNum);
_

実際には、フィルタリングされた戦略であるTextExtractionStrategyを取るオーバーライドが必要です。それはかなりすぐに興味深くなりますが、私はここであなたが欲しいものすべてを「箱から出して」得ることができると思います。

  • 画像

はい、同じパッケージクラスを使用します。画像リスナーはテキストリスナーほどサポートされていませんが、存在します。

  • リンク

はい。リンクはさまざまなPDF=ページへの「注釈」です。リンクを見つけるのは、各ページの「注釈配列」をループしてリンクの注釈を選択するだけです。

_PdfDictionary pageDict = myReader.getPageN(1);
PdfArray annots = pageDict.getAsArray(PdfName.ANNOTS);
ArrayList<String> dests = new ArrayList<String>();
if (annots != null) {
  for (int i = 0; i < annots.size(); ++i) {
    PdfDictionary annotDict = annots.getAsDict(i);
    PdfName subType = annotDict.getAsName(PdfName.SUBTYPE);
    if (subType != null && PdfName.LINK.equals(subType)) {
      PdfDictionary action = annotDict.getAsDict(PdfName.A);
      if (action != null && PdfName.URI.equals(action.getAsName(PdfName.S)) {
        dests.add(action.getAsString(PdfName.URI).toString());
      } // else { its an internal link, meh }
    }
  }
}
_

PDF Spec here を見つけることができます。

  • 入力要素

絶対に。 XFA(LiveCycle Designer)または古い技術の「AcroForm」フォームの場合、iTextはすべてのフィールドとその値を検索できます。

_AcroFields fields = myReader.getAcroFields();

Set<String> fieldNames = fields.getFields().keySet();
for (String fldName : fieldNames) {
  System.out.println( fldName + ": " + fields.getField( fldName ) );
}
_

複数選択リストはそれほどうまく処理されません。空のテキストフィールドとボタンのコロンの後に空白が表示されます。あまり有益な情報はありません...しかし、それであなたは始められます.

  • タイトル、説明、作成者などのドキュメントメタタグ

かなり簡単です。はい。

_Map<String, String> info = myPdfReader.getInfo();
System.out.println( info );
_

基本的な作者/タイトル/その他に加えて、reader.getMetadata()を介してアクセスできるかなり複雑なXMLスキーマがあります。

  • 見出しのみ

TextRenderFilterは、任意の基準に基づいてテキストを無視できます。フォントサイズは、コメントに基づいて適切に聞こえます。

19
Mark Storer
6
Dhaivat Pandya

これらすべての抽出タスクにJPedalを使用することもできます。

1
mark stephens

はい、Alp、iTextはあなたが言及した機能を提供します。

PDFの読み取り

iTextはPDFビューアではありません。iTextはPDF=画像に変換できません。また、iTextを使用してPDFを印刷することもできませんが、PdfReaderクラスです。 PDFドキュメントを構成するオブジェクトと各ページのコンテンツストリームにアクセスできます。このコンテンツストリームは解析でき、コンテンツがラスタライズされたテキストとして追加されなかった場合は、ページをプレーンテキストに変換できます。iTextはOCRを実行しないことに注意してください。

使用する com.itextpdf.text.pdf.PdfReader;クラス。

0
Suresh

これのほとんどは our PDF Library extended edition でも実行できます。

どちらの解決策でも、PDF文書の場合、PDFの構築方法が原因でテキストの抽出は不可能です(上のグリフページには、意味的な意味が関連付けられていない場合があります)。

これを確認する簡単な方法は、Acrobatでドキュメントを開き、テキストをコピーして貼り付けることです。意味不明なように表示される場合、他のPDFエクストラクターで意味不明なように表示される可能性があります。

0
Mike B