PDF文档中文本解析

常用的PDF文档解析解决方案有两种。

一是通过文档结构读取解析,另一种是通过ocr技术处理。

这里我们主要说一下文档读取解析的方案,现在常用的解析库有mupdf、pdfium、Aspose等第三方库来处理。其中mupdf、pdfium为开源、免费的。Aspose是一款收费的商业库。

下边我们分别说一说各种库的使用。

mupdf

库编译以及链接至项目中这里就不做介绍了我们主要说一下使用该库做文本提取,代码示例如下:

cpp 复制代码
std::string strPath = "pdf.pdf";
fz_context* ctx = fz_new_context(NULL, NULL, FZ_STORE_UNLIMITED);
fz_register_document_handlers(ctx);
fz_document* doc = fz_open_document(ctx, strPath.c_str());
int nCount = fz_count_pages(ctx, doc);
if (nCount > 0)
{
    //这里我们只演示第一页数据的获取,如果需要获取其他页的则自行处理
    fz_stext_page* text_page = fz_new_stext_page(ctx, fz_bound_page(ctx, page));
    fz_device* device = fz_new_stext_device(ctx, text_page, NULL);
    fz_run_page(ctx, page, device, fz_identity, NULL);
    fz_stext_block* block;
    
    SStringW sstrData;
    for (block = text_page->first_block; block; block = block->next)
    {
        if (block->type == FZ_STEXT_BLOCK_TEXT)
        {
            fz_stext_line* line;
            for (line = block->u.t.first_line; line; line = line->next)
            {
                fz_stext_char* ch;
                for (ch = line->first_char; ch; ch = ch->next)
                {
                    //获取字符
                    SStringW sstrChar;
                    sstrChar.Format(L"%c", ch->c);
                    sstrData += sstrChar;     
                    //获取字体
                    std::string strFont = ch->font->name;
                    //其他参数获取可自行实现,具体能获取那些可参考fz_stext_char结构,比如颜色、大小、位置等数据
                    //TODO:                                                                                                        
                }    
                sstrData += L"\n";        
            }        
        }  
    }
}

pdfium

代码示例如下:

cpp 复制代码
std::string strPath = "pdf.pdf";
FPDF_InitLibrary();
FPDF_DOCUMENT document = FPDF_LoadDocument(strPath.c_str(), nullptr);
if (!document)
{
    //error
}
int nCount = FPDF_GetPageCount(document);
if (nCount > 0)
{
    //这里我们只演示第一页数据的获取,如果需要获取其他页的则自行处理
    FPDF_PAGE page = FPDF_LoadPage(document, 0); // 加载第一页 (索引 0)
    if (page) 
    {
        std::wstring wstrText; 
        FPDF_TEXTPAGE text_page = FPDFText_LoadPage(page);
        if (text_page)
        {
            int char_count = FPDFText_CountChars(text_page);
            for (int i = 0; i < char_count; ++i) {
                unsigned short ch = FPDFText_GetUnicode(text_page, i);
                wchar_t wide_char = static_cast<wchar_t>(ch);
                wstrText += wide_char;
            }
            FPDFText_ClosePage(text_page);     
        }             
    }
}

在实际使用中发现使用mupdf解析文本时每一个block即为一段落的文本。但是在pdfium中获取的文本为整页中的所有文本,如果要划分段落则需要使用者自己根据字符的位置信息自己做归类处理。

Aspose

代码示例如下:

cpp 复制代码
if (!System::IO::File::Exists(u"Example1.pdf"))
{
    //文件不存在
}
auto extractor = MakeObject<Facades::PdfExtractor>();
extractor->BindPdf(u"Example1.pdf");
extractor->ExtractText();

auto memStream = MakeObject<System::IO::MemoryStream>();
extractor->GetText(memStream);

auto unicode = System::Text::Encoding::get_Unicode();
String allText = unicode->GetString(memStream->ToArray());
相关推荐
zzh9407718 分钟前
2026年AI文件上传功能实战:聚合站处理图片、PDF、PPT全指南
人工智能·pdf·powerpoint
今夕资源网1 小时前
windows11无法启用投屏功能 无线显示器无法添加可选功能 解决办法 Miracast修复脚本
windows·计算机外设·miracast·系统修复·无线显示器·投屏功能·投屏功能无法添加
仰泳的熊猫3 小时前
题目2570:蓝桥杯2020年第十一届省赛真题-成绩分析
数据结构·c++·算法·蓝桥杯
Thera7777 小时前
C++ 高性能时间轮定时器:从单例设计到 Linux timerfd 深度优化
linux·开发语言·c++
君义_noip8 小时前
信息学奥赛一本通 1952:【10NOIP普及组】三国游戏 | 洛谷 P1199 [NOIP 2010 普及组] 三国游戏
c++·信息学奥赛·csp-s
旖-旎9 小时前
二分查找(x的平方根)(4)
c++·算法·二分查找·力扣·双指针
顶点多余9 小时前
使用C/C++语言链接Mysql详解
数据库·c++·mysql
汉克老师9 小时前
GESP2026年3月认证C++四级( 第二部分判断题(1-10))
c++·指针·函数重载·文件操作·数组·gesp4级·gesp四级
内卷焦虑人士10 小时前
Windows安装WSL2+Ubuntu 22.04
linux·windows·ubuntu
khddvbe10 小时前
C++并发编程中的死锁避免
开发语言·c++·算法