PoDoFoは、ドキュメントからテキストを簡単に抽出する手段を提供していませんが、それを行うのは難しくありません。
PdfMemDocument
ドキュメントを:にロードします
PoDoFo::PdfMemDocument pdf("mydoc.pdf");
各ページを繰り返します。
for (int pn = 0; pn < pdf.GetPageCount(); ++pn) {
PoDoFo::PdfPage* page = pdf.GetPage(pn);
そのページのすべてのPDFコマンドを繰り返します。
PoDoFo::PdfContentsTokenizer tok(page);
const char* token = nullptr;
PoDoFo::PdfVariant var;
PoDoFo::EPdfContentsType type;
while (tok.ReadNext(type, token, var)) {
switch (type) {
case PoDoFo::ePdfContentsType_Keyword:
// process token: it contains the current command
// pop from var stack as necessary
break;
case PoDoFo::ePdfContentsType_Variant:
// process var: push it onto a stack
break;
default:
// should not happen!
break;
}
}
}
「プロセストークン」と「プロセス変数」のコメントは、もう少し複雑になります。処理する生のPDFコマンドが与えられます。幸い、実際にページをレンダリングしておらず、テキストだけが必要な場合は、ほとんどのページを無視できます。処理する必要のあるコマンドは次のとおりです。
BT
、、、、、、、、、、、、、ET
_ Td
_ TD
_ Ts
_ T
_ Tm
_ Tf
_ "
_ '
_ Tj
_TJ
BT
andコマンドは、テキストストリームの開始と終了をマークするため、 /ペアET
の間にないものはすべて無視する必要があります。BT
ET
PDF言語はRPNベースです。コマンドストリームは、スタックにプッシュされる値と、スタックから値をポップして処理するコマンドで構成されます。
、、、およびコマンドは"
、実際にテキストを生成する唯一のものです。、および単一の文字列を返します。とを使用して処理します。'
Tj
TJ
"
'
Tj
var.IsString()
var.GetString()
TJ
文字列の配列を返します。次の方法でそれぞれを抽出できます。
if (var.isArray()) {
PoDoFo::PdfArray& a = var.GetArray();
for (size_t i = 0; i < a.GetSize(); ++i)
if (a[i].IsString())
// do something with a[i].GetString()
他のコマンドは、改行をいつ導入するかを決定するために使用されます。"
また、'
改行を導入します。最善の策は、AdobeからPDF仕様をダウンロードし、テキスト処理セクションを検索することです。各コマンドの機能について詳しく説明しています。
PDFファイルを取得し、各ページのコマンドストリームをダンプする小さなプログラムを作成すると非常に便利であることがわかりました。
var
注:位置情報なしで生のテキストを抽出するだけの場合は、実際に値のスタックを維持する必要はありません。すべてのテキストレンダリングコマンドには、最大で1つのパラメータがあります。var
の最後の値に現在のコマンドのパラメーターが含まれていると単純に想定できます。