ファイルから表形式の情報を抽出するために、pdf および MS Office ドキュメント形式のパーサーを探しています。Apache Tika を見たとき、個別の実装を作成することを考えていました。これらのファイル形式から全文を抽出できます。しかし、私の要件は、キー値形式で 2 つの列を期待している表形式のデータを抽出することです。解決策としてネットで入手可能なもののほとんどをチェックしましたが、何も見つかりませんでした。これに対する指針はありますか?
4 に答える
さて、私は先に進み、MS フォーマット用の apache poi を使用して個別に実装しました。PDFを求めてTikaに戻ってきました。Tika がドキュメントに対して行うことは、ドキュメントを「SAX ベースの XHTML イベント」として出力することです1
したがって、基本的には、ファイルを解析するためのカスタム SAX 実装を作成できます。
構造テキストの出力は次の形式になります (メタ詳細は回避されます)
<body><div class="page"><p/>
<p>Key1 Value1 </p>
<p>Key2 Value2 </p>
<p>Key3 Value3</p>
<p/>
</div>
</body>
この SAX 実装では、最初の部分をキーと見なすことができます (この問題では、キーは既にわかっており、値を探しているので、部分文字列です)。
public void characters(char[] ch, int start, int length) をロジックでオーバーライドします
私の場合、コンテンツの構造は固定されており、入ってくるキーを知っているので、このようにするのは簡単でした. これは一般的な解決策ではありません
私はtika(tika-app-1.19.jar)とaspose(aspose-pdf-18.9.1.jar)の組み合わせを使用しています...
最初に Aspose を使用して pdf を変更し、テーブルの列の最後にパイプ ('|') を付けます... ...そしてそれを Tika に読み込んでテキストに変換します...
InputStream is = part.getInputStream(); // input-stream of PDF or PDF part
// Aspose add pipes ("|")
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
Document pdfDocument = new Document(is); // load existing PDF file
PageCollection pageCollection = pdfDocument.getPages();
int iNumPages = pageCollection.size();
for(int i = 1; i <= iNumPages; i++)
{
Page page = pageCollection.get_Item(i);
TableAbsorber absorber = new TableAbsorber();// Create TableAbsorber object to find tables
absorber.visit(page);// Visit first page with absorber
IGenericList<AbsorbedTable> listTables = absorber.getTableList();
for(AbsorbedTable absorbedTable : listTables)
{
IGenericList<AbsorbedRow> listRows = absorbedTable.getRowList();
for(AbsorbedRow absorbedRow : listRows)
{
IGenericList<AbsorbedCell> listCells = absorbedRow.getCellList();
for(AbsorbedCell absorbedCell : listCells)
{
TextFragmentCollection collectionTextFrag = absorbedCell.getTextFragments();
Rectangle rectangle = absorbedCell.getRectangle();
// Add pipes ("|") to indicate table ends
TextBuilder textBuilder = new TextBuilder(page);
TextFragment textFragment = new TextFragment("|");
double x = rectangle.getURX();
double y = rectangle.getURY();
textFragment.setPosition(new Position(x, y));
textBuilder.appendText(textFragment);
}
}
}
}
pdfDocument.save(outputStream);
is = new ByteArrayInputStream(outputStream.toByteArray()); // input-steam of modified PDF with pipes included ("|")
これで、テーブル セルの末尾にパイプ ("|") を含む上記の pdf 入力ストリームを Tika に取り込み、テキストに変更できるようになりました...
BodyContentHandler handler = new BodyContentHandler();
Metadata metadata = new Metadata();
ParseContext context = new ParseContext();
PDFParser pdfParser = new PDFParser();
PDFParserConfig config = pdfParser.getPDFParserConfig();
config.setSortByPosition(true); // needed for text in correct order
pdfParser.setPDFParserConfig(config);
//InputStream stream = new ByteArrayInputStream(sIS.getBytes(StandardCharsets.UTF_8));
pdfParser.parse(is, handler, metadata, context);
String sPdfData = handler.toString();