首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++ (PoDoFo)中的PDF解析

C++ (PoDoFo)中的PDF解析
EN

Stack Overflow用户
提问于 2012-07-30 12:53:07
回答 2查看 27.1K关注 0票数 12

嗨,所以我想从一些pdf文件中解析一些文本,我想使用PoDoFo,现在我已经尝试搜索如何使用PoDoFo来解析pdf的示例,但是我能想到的只是如何创建和编写pdf文件的示例,这并不是我真正需要的。

如果任何人有任何教程或使用PoDoFo解析PDF文件的示例,或者对我可以使用的其他库有建议,请让我知道。我也知道linux上有pdftotext,然而,我不仅不能使用pdftotext,而且我更希望能够在内部做我需要的一切,而不是依赖于安装外部程序。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-07-30 18:15:10

PoDoFo不提供从文档中轻松提取文本的方法,但这并不难做到。

将文档加载到PdfMemDocument

代码语言:javascript
复制
PoDoFo::PdfMemDocument pdf("mydoc.pdf");

遍历每个页面:

代码语言:javascript
复制
for (int pn = 0; pn < pdf.GetPageCount(); ++pn) {
    PoDoFo::PdfPage* page = pdf.GetPage(pn);

遍历该页面上的所有PDF命令:

代码语言:javascript
复制
    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;
        }
    }
}

"process token“和"process var”注释有点复杂。您将看到要处理的原始PDF命令。幸运的是,如果您实际上并没有渲染页面,而只是想要文本,那么您可以忽略其中的大多数内容。您需要处理的命令包括:

BTETTdTDTsTTmTf"、<代码>D13、<代码>D14和<代码>D15

BTET命令标记文本流的开始和结束,因此您希望忽略除BT/ET对之外的任何内容。

PDF语言是基于RPN的。命令流由推入堆栈的值和将值弹出堆栈并对其进行处理的命令组成。

"'TjTJ命令是唯一实际生成文本的命令。"'Tj返回单个字符串。使用var.IsString()var.GetString()对其进行处理。

TJ返回字符串数组。您可以使用以下命令提取每个文件:

代码语言:javascript
复制
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中的最后一个值包含当前命令的参数。

票数 43
EN

Stack Overflow用户

发布于 2012-07-30 13:49:01

我没有使用过PoDoFo,但是快速浏览一下他们的网页上的类层次结构就会发现:

代码语言:javascript
复制
void PoDoFo::PdfMemDocument::Load( const char * pszFilename )

(API doc link)

所以我想在这里大胆猜测一下,你确实是这样做的:

代码语言:javascript
复制
PoDoFo::PdfMemDocument doc;
doc.Load( "somefile.pdf" );

然后,我假设您通过调用doc.GetObjects()并遍历该数组(see PdfDocument class)来导航文档树

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11715561

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档