嗨,所以我试图解析一些pdf中的一些文本,我想使用PoDoFo,现在我已经尝试过搜索如何使用PoDoFo解析pdf的例子,但我能想到的只是示例如何创建和编写一个不是我真正需要的pdf文件。
如果有人有任何使用PoDoFo解析PDF文件的教程或示例,或者有我可以使用的其他库的建议,请告诉我。另外我知道linux上有pdftotext,但是,我不仅可以不使用它,而且我更愿意在内部完成所需的一切,而不是依赖于正在安装的外部程序。
答案 0 :(得分:36)
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;
}
}
}
“过程令牌”&amp; “process var”注释是它变得更复杂的地方。您将获得要处理的原始PDF命令。幸运的是,如果你实际上没有渲染页面而你想要的只是文本,你可以忽略它们中的大部分。您需要处理的命令是:
BT
,ET
,Td
,TD
,Ts
,T
,Tm
,Tf
,"
,'
,Tj
和TJ
BT
和ET
命令标记文本流的开头和结尾,因此您要忽略不在BT
/ ET
对之间的任何内容。< / p>
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
值。所有文本渲染命令最多只有一个参数。您可以简单地假设var
中的最后一个值包含当前命令的参数。
答案 1 :(得分:4)
我没有使用PoDoFo,但在API网页上快速浏览类层次结构显示:
void PoDoFo::PdfMemDocument::Load( const char * pszFilename )
所以我想在这里做一个猜测,你这样做:
PoDoFo::PdfMemDocument doc;
doc.Load( "somefile.pdf" );
然后我想你通过调用doc.GetObjects()
并遍历该数组(see PdfDocument class)来浏览文档树