C++使用PoDoFo库处理PDF文件

news2025/5/11 3:45:50

📚 PoDoFo 简介

PoDoFo 是一个用 C++ 编写的自由开源库,专用于 读取、写入和操作 PDF 文件。它适用于需要程序化处理 PDF 文件的应用程序,比如批量生成、修改、合并、提取元数据、绘图等。
在这里插入图片描述

🌟 核心特点

特性说明
📄 PDF 读取支持加载 PDF,读取内容流、页数、对象、元数据等
✍️ PDF 写入可创建新 PDF,添加页、文本、图片、绘图操作
📌 PDF 编辑可访问并修改 PDF 内部结构,如对象树
🔐 加密支持支持基本加密(RC4、标准 PDF 加密),但支持有限
📦 轻量依赖只依赖标准 C++ 和一些通用库(如 zlib、freetype、libjpeg)

🏗️ 技术基础

  • 语言:C++
  • 授权协议:LGPL
  • 平台:Linux / Windows / macOS
  • 主要头文件#include <podofo/podofo.h>

📦 常见用途

  1. 批量生成 PDF 报告
  2. 批量提取页数、作者、标题等元数据
  3. 根据程序逻辑创建图形、表格型 PDF
  4. 读取 PDF 对象结构进行分析或修改

⚠️ 局限性

  • 不支持 PDF 渲染(不能直接显示或截图)
  • 对于复杂加密和 PDF/A 等标准支持有限
  • 文档和社区相对较小,不如 poppler 丰富

📌 官方地址

  • GitHub 镜像(非官方): https://github.com/podofo/podofo
  • 官方网站(较旧): http://podofo.sourceforge.net/

1、安装podofo

方式1:apt安装

sudo apt install libpodofo-dev
# 确认是否安装成功
dpkg -LA libpodofo-dev

出现类似这样的路径说明没问题。
在这里插入图片描述

方式2:源码安装

git clone https://github.com/podofo/podofo.git
cd podofo
mkdir build && cd build
cmake ..
make
sudo make install

2、示例代码

下面是一个使用PoDoFo库来过滤PDF文件的示例代码。假设我们有一个目录,里面包含多个PDF文件,我们想根据某些条件(比如页数)来过滤这些文件。

2.1 main.cpp

#include <podofo/podofo.h>
#include <iostream>
#include <filesystem>
#include <vector>

namespace fs = std::filesystem;

void FilterPDFs(const std::string& directory, int minPages) {
    std::vector<std::string> filteredFiles;

    for (const auto& entry : fs::directory_iterator(directory)) {
        if (entry.is_regular_file() && entry.path().extension() == ".pdf") {
            try {
                PoDoFo::PdfMemDocument document;
                // std::cout<<entry.path().string()<<std::endl;
                document.Load(entry.path().c_str());
                // 获取PDF文件的页数
                int numPages = document.GetPageCount();

                if (numPages >= minPages) {
                    filteredFiles.push_back(entry.path().string());
                }
            } catch (const PoDoFo::PdfError& e) {
                std::cerr << "Error processing file " << entry.path().string() << ": " << e.what() << std::endl;
            }
        }
    }

    // 输出符合条件的PDF文件
    std::cout << "Filtered PDF files with at least " << minPages << " pages:" << std::endl;
    for (const auto& file : filteredFiles) {
        std::cout << file << std::endl;
    }
}

int main() {
    std::string directory = "/your/pdf/path/";  // 替换为你的PDF文件所在目录
    int minPages = 5;  // 过滤条件:至少包含5页的PDF文件

    FilterPDFs(directory, minPages);

    return 0;
}
  • PoDoFo库:这是一个C++库,用于创建、修改和解析PDF文件。在这个例子中,我们使用它来加载PDF文件并获取其页数。
  • std::filesystem:这是C++17引入的标准库,用于处理文件系统相关的操作,如遍历目录中的文件。
  • FilterPDFs函数:该函数接收一个目录路径和最小页数作为参数,遍历目录中的所有PDF文件,并根据页数进行过滤。
  • 异常处理:在加载PDF文件时可能会出现错误(例如文件损坏),因此我们使用try-catch块来捕获并处理这些错误。

2.2 CMakeLists.txt

# 指定CMake的最低版本要求
cmake_minimum_required(VERSION 3.10)

# 定义项目名称和编程语言
project(PdfFilter VERSION 1.0 LANGUAGES CXX)

# 设置C++标准 (例如C++17)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
set(CMAKE_CXX_EXTENSIONS False)

# podofo
find_library(PODOFO_LIBRARY podofo)

# 添加可执行文件
add_executable(${PROJECT_NAME} main.cpp)

# 如果有第三方库需要链接,可以使用target_link_libraries
target_link_libraries(${PROJECT_NAME} ${PODOFO_LIBRARY})

message("🐼 ${PODOFO_LIBRARY}")

2.3 编译运行

  • 编译
mkdir build
cd build
cmake ..
-- The CXX compiler identification is GNU 13.3.0
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
🐼 /usr/lib/libpodofo.so
-- Configuring done (1.4s)
-- Generating done (0.0s)
-- Build files have been written to: /mnt/d/cppworkspace/PDFDemo/build
make
[ 50%] Building CXX object CMakeFiles/PdfFilter.dir/main.cpp.o
[100%] Linking CXX executable PdfFilter
[100%] Built target PdfFilter
  • 运行
./PdfFilter
  • 文件结构
.
|-- main.cpp
|-- CMakeLists.txt
|-- build
|   |-- CMakeCache.txt
|   |-- CMakeFiles
|   |-- Makefile
|   |-- PdfFilter
|   |-- cmake_install.cmake

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2372826.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Unity】Unity中修改网格的大小和倾斜网格

一、问题 unity中的网格&#xff08;Grid&#xff09;或者地面Plane组件&#xff0c;在使用时&#xff0c;都是正方形的网格&#xff0c;而且建立该网格后&#xff0c;在不改变Scale情况下&#xff0c;没发使其整体变大&#xff0c;而且也没法改变每个网格的大小&#xff0c;而…

Transformer-LSTM混合模型在时序回归中的完整流程研究

Transformer-LSTM混合模型在时序回归中的完整流程研究 引言与背景 深度学习中的长期依赖建模一直是时序预测的核心问题。长短期记忆网络&#xff08;LSTM&#xff09;作为一种循环神经网络&#xff0c;因其特殊的门控结构能够有效捕捉序列的历史信息&#xff0c;并在时序预测…

UE5 渲染思路笔记(角色)

参考示例 首先是怎么做到辉光只有部分有而整体没有的 使用的是Bloom内的阈值,控制光的溢光量 Threshold&#xff08;阈值&#xff09;&#xff1a;这个参数决定了图像中哪些像素会参与泛光计算。只有那些亮度超过阈值的像素才会触发泛光效果。阈值越低&#xff0c;更多的像素会…

运维打铁:服务器分类及PHP入门

文章目录 C/S架构和B/S架构C/S架构B/S架构 服务器分类服务器类型服务器软件 使用 WampServer 搭建 HTTP服务集成环境的分类WampServer 的安装测试访问配置网站根目录 静态网站和动态网站PHP的常见语法第一段 php 代码注释变量数据类型运算符函数的定义类和对象内容输出循环语句…

Python - 爬虫;Scrapy框架(一)

框架&#xff0c;就相当于一个封装了很多功能的结构体&#xff0c;它帮我们把主要的结构给搭建好了&#xff0c;我们只需往骨架里添加内容就行。 Scrapy是适用于Python的一个快速、高层次的屏幕抓取和web抓取框架&#xff0c;用于抓取web站点并从页面中提取结构化的数据。Scra…

The 2024 ICPC Kunming Invitational Contest G. Be Positive

https://codeforces.com/gym/105386/problem/G 题目&#xff1a; 结论&#xff1a; 从0开始每四个相邻数的异或值为0 代码&#xff1a; #include<bits/stdc.h> using namespace std; #define int long long void solve() {int n;cin >> n;if(n1||n%40){cout &…

GET请求如何传复杂数组参数

背景 有个历史项目&#xff0c;是GET请求&#xff0c;但是很多请求还是复杂参数&#xff0c;比如&#xff1a;参数是数组&#xff0c;且数组中每一个元素都是复杂的对象&#xff0c;这个时候怎么传参数呢&#xff1f; 看之前请求直接是拼接在url后面 类似&items%5B0%5D.…

leetcode - 双指针问题

文章目录 前言 题1 移动零&#xff1a; 思路&#xff1a; 参考代码&#xff1a; 题2 复写零&#xff1a; 思考&#xff1a; 参考代码&#xff1a; 题3 快乐数&#xff1a; 思考&#xff1a; 参考代码&#xff1a; 题4 盛最多水的容器&#xff1a; 思考&#xff1a;…

人工智能之数学基础:二次型

本文重点 二次型作为线性代数领域的重要概念,架起了代数方程与几何分析之间的桥梁。从古典解析几何中的圆锥曲线方程到现代优化理论中的目标函数,二次型以其简洁的数学表达和丰富的结构特性,在数学物理、工程技术和经济金融等领域发挥着不可替代的作用。 二次型的基本概念…

【Unity笔记】实现支持不同渲染管线的天空盒曝光度控制组件(SkyboxExposureController)——参数化控制

写在前面 在Unity中&#xff0c;天空盒&#xff08;Skybox&#xff09;不仅承担视觉上的背景作用&#xff0c;更是场景环境光照与氛围塑造的重要组成部分。不同时间、天气、场景转换等&#xff0c;都需要灵活调整天空的亮度。而**曝光度&#xff08;Exposure&#xff09;**就是…

Docker 使用与部署(超详细)

目录 引入 入门使用 部署对比 镜像仓库 命令解释 基础 常见命令 示例 数据卷的使用 数据卷的概念 数据卷的使用 挂载本地目录文件 镜像 结构 Dockerfile 容器网络 部署 DockerCompose 语法 ​编辑 基础命令 引入 当我们在 Linux 上部署一个集成了很多中间件…

CSS实现图片垂直居中方法

html <div class"footer border-top-row"><div class"footer-row"><span class"footer-row-col01">制单人&#xff1a;{{ printData[pageIndex - 1].rkMaster.makerName}}<img :src"getPersonSignImgSrc(printData[pa…

Python+Scrapy跨境电商爬虫实战:从亚马逊/沃尔玛数据采集到反爬攻克(附Pangolin API高效方案)

从零实战到反爬攻克&#xff0c;揭秘跨境数据抓取全流程与Pangolin Scrape API终极方案 在当今数据驱动的跨境电商时代&#xff0c;谁掌握了优质的市场数据&#xff0c;谁就掌握了成功的关键。随着全球电商市场规模持续扩大&#xff08;据Statista最新报告显示&#xff0c;2025…

【日撸 Java 三百行】Day 7(Java的数组与矩阵元素相加)

目录 Day 7&#xff1a;Java 的数组与矩阵元素相加 一、基本知识 二、矩阵的建立与基本计算 三、代码及测试 拓展&#xff1a;Arrays类详解 小结 Day 7&#xff1a;Java 的数组与矩阵元素相加 Task&#xff1a; 矩阵的赋值.二重循环. 一、基本知识 在学习 Java 中的数组与矩…

【Python】常用命令提示符

Python常用的命令提示符 一、Python环境基础命令【Windows】 于Windows环境下&#xff0c;针对Python&#xff0c;在CMD&#xff08;命令提示符&#xff09;常用的命令以及具体用法&#xff0c;怎么用&#xff1b;   主要包含&#xff1a;运行脚本、包管理、虚拟环境、调试与…

vite:npm 安装 pdfjs-dist , PDF.js View 预览功能示例

pdfjs-dist 是 Mozilla 的 PDF.js 库的预构建版本&#xff0c;能让你在项目里展示 PDF 文件。下面为你介绍如何用 npm 安装 pdfjs-dist 并应用 pdf.js 和 pdf.worker.js。 为了方便&#xff0c;我将使用 vite 搭建一个原生 js 项目。 1.创建项目 npm create vitelatest pdf-v…

【开源版】likeshop上门家政系统PHP版全开源+uniapp前端

一.系统介绍 likeshop_上门家政系统&#xff0c;PHP版本更新至2.1.1最新版&#xff0c;全开源&#xff0c;适用于上门家政场景&#xff0c;系统拥有用户端、师傅端、无论运营还是二开都是性价比极高的100%开源家政系统。 二.搭建环境-教程 系统环境&#xff1a;CentOS、 运行…

MySQL 8.0 OCP 英文题库解析(一)

Oracle 为庆祝 MySQL 30 周年&#xff0c;从 2025.04.20 ~ 2025.07.31 之间&#xff0c;所有人均可以免费考取 MySQL OCP 认证。从今天开始&#xff0c;将英文题库免费公布出来&#xff0c;并进行解析&#xff0c;帮助大家在一个月之内轻松通过OCP认证&#xff0c;省1700多RMB&…

路由器断流排查终极指南:从Ping测试到Wireshark抓包5步定位法

测试路由器是否出现“断流”&#xff08;网络连接间歇性中断&#xff09;&#xff0c;需通过多维度排查硬件、软件及外部干扰因素。以下是详细步骤指南&#xff1a; 一、基础环境准备 设备连接 有线测试&#xff1a;用网线将电脑直接连接路由器LAN口&#xff0c;排除WiFi干扰。…

04 基于 STM32 的时钟展示程序

前言 我们经常会看到 各个场合下面有 基于数码管 的时钟程序 比如 在车站, 教室, 办公室 等等 各个场合都有 然后 这里就是做一个 简单的 时钟程序 展示程序 测试用例 每一秒钟更新时间, 然后 迭代更新 天, 时, 分 等等 然后 主流程 基于 天, 时分秒 渲染数码管 #incl…