如何在 Aspose.PDF FOSS for C++ 中使用 Facades API
Aspose.PDF FOSS for C++ 将一组更高级的外观和编辑器类分组——其中包括 PdfExtractor、PdfBookmarkEditor、PdfContentEditor、PdfAnnotationEditor、FormEditor、PdfFileEditor 和 PdfConverter —— 位于 Aspose::Pdf::Facades 命名空间。每个类都在核心 Document API 之上包装单一的文档维护任务,使您能够提取内容、编辑书签或填写表单字段,而无需自行手动遍历页面和对象。本文重点介绍 PdfExtractor,该外观用于从现有 PDF 中提取嵌入的文件附件、页面文本和嵌入图像。
分步指南
步骤 1:安装包
将 Aspose.PDF FOSS for C++ 添加为 CMake 子目录并链接静态库目标:
git clone https://github.com/aspose-pdf-foss/Aspose.PDF-FOSS-for-Cpp.gitadd_subdirectory(Aspose.PDF-FOSS-for-Cpp)
target_link_libraries(your_app PRIVATE aspose_pdf_foss)在编写任何外观代码之前,确认工具链和链接步骤已正确解析:
cmake -S . -B build
cmake --build build在 C++20 编译器下进行干净构建可确认 aspose_pdf_foss 已链接到 your_app。
步骤 2:导入所需类
PdfExtractor 位于 aspose/pdf/facades/ 下,与来自 core 命名空间的 Document 同在:
#include <aspose/pdf/document.hpp>
#include <aspose/pdf/facades/pdf_extractor.hpp>
using namespace Aspose::Pdf;
using namespace Aspose::Pdf::Facades;步骤 3:将文档绑定到 PdfExtractor
每个外观类都继承自一个公共的 Facade 基类,该基类公开 BindPdf(srcFile) 和 BindPdf(srcDoc),以便在构造后将其附加到文档。PdfExtractor 还在其构造函数中直接接受已经打开的 Document,这就是本指南贯穿使用的模式:
Document doc("input.pdf");
PdfExtractor extractor(doc);步骤 4:提取嵌入的文件附件
首先检查 Document::EmbeddedFiles(),然后使用 GetAttachNames() 读取附件名称,并使用 GetAttachment() 将附件的字节提取到磁盘:
#include <iostream>
if (doc.EmbeddedFiles().Count() > 0) {
std::vector<std::string> names = extractor.GetAttachNames();
for (const auto& name : names) {
std::cout << "Attachment: " << name << "\n";
}
// Writes the bytes of the first attachment to disk
extractor.GetAttachment("extracted_attachment.bin");
}步骤 5:从每页提取文本
ExtractText() 后接 GetText() 将整个文档的文本写入单个文件:
extractor.ExtractText();
extractor.GetText("extracted_text.txt");若要改为每页捕获一个文件,请使用 StartPage() / EndPage() 设置页范围,然后在循环中驱动 HasNextPageText() / GetNextPageText(),为每次调用提供各自的输出路径:
extractor.StartPage(1);
extractor.EndPage(doc.Pages().Count());
int pageNumber = extractor.StartPage();
while (extractor.HasNextPageText()) {
std::string outputFile = "page_" + std::to_string(pageNumber) + ".txt";
extractor.GetNextPageText(outputFile);
++pageNumber;
}步骤 6:提取嵌入的图像
ExtractImage() 初始化图像光标;随后 HasNextImage() / GetNextImage() 逐个遍历图像,将每个图像写入您传入的路径:
extractor.ExtractImage();
int imageIndex = 1;
while (extractor.HasNextImage()) {
std::string outputFile = "extracted_image_" + std::to_string(imageIndex);
if (extractor.GetNextImage(outputFile)) {
++imageIndex;
}
}常见问题与解决方案
GetAttachNames() 返回一个空向量。 源 PDF 没有嵌入文件。检查 doc.EmbeddedFiles().Count() 在调用任何附件方法之前 PdfExtractor 以免尝试从从未有附件的文档中提取。
页面文本循环从未进入主体。 HasNextPageText() returns false 立即如果 StartPage() / EndPage() 从未被设置,或被设置为超出文档实际页数的范围。请显式地从 doc.Pages().Count() 检查之前 HasNextPageText().
GetNextImage() returns false 在第一次调用时。 ExtractImage() 必须调用一次以初始化图像光标,然后再进行检查 HasNextImage() 或调用 GetNextImage()。调用 GetNextImage() 没有先前的 ExtractImage() 调用在调用者的角度来看是未定义的 — 始终调用 ExtractImage() 先。
每个提取的图像或页面文本文件都会覆盖之前的文件。 GetNextImage() and GetNextPageText() 每个都使用字面输出路径;外观不会为您生成唯一的文件名。为每次迭代构建不同的路径(例如,通过追加递增计数器),如步骤 5 和 6 所示。
链接错误:未定义的引用到 aspose_pdf_foss 符号。 Confirm add_subdirectory() 指向克隆的仓库根目录,并且该 target_link_libraries() 命名为 aspose_pdf_foss 目标完全相同,使用配置为 C++20 标准的 your_app.
常见问题
Facades API 与核心 Document API 有何区别?
核心 Document API(Document、PageCollection、Annotation 等)直接公开 PDF 对象模型。像 PdfExtractor 这样的 Facade 类位于其之上,并将特定的多步骤任务——提取内容、编辑书签、填写表单字段——封装在更窄的专用接口后。
我能像使用 PdfExtractor 提取内容一样编辑书签或填写表单字段吗?
是的。PdfBookmarkEditor(包含 CreateBookmarks()、ModifyBookmarks()、ExtractBookmarks() 和 DeleteBookmarks())和 FormEditor(包含 AddField()、RemoveField() 和 SetFieldAttribute())位于同一个 Aspose::Pdf::Facades 命名空间,并遵循步骤 2 和 3 中展示的相同 include/construct 模式——它们各自只作用于文档的不同部分。
PdfExtractor 能读取受密码保护的 PDF 吗?
在调用任何提取方法之前设置密码:
extractor.Password("owner-or-user-password");PdfExtractor::Password() 是一个普通的读/写属性,因此必须在 ExtractText()、ExtractImage() 或附件方法之前设置。
如果 PDF 没有可提取的文本、图像或附件,会怎样?
不会抛出异常。GetAttachNames() 返回一个空向量,HasNextPageText() / HasNextImage() 在第一次检查时返回 false,因此相应的循环体根本不会执行。
我应该为特定的外观类包含哪个头文件?
每个外观类都有自己的头文件位于 aspose/pdf/facades/,文件名与类名匹配:pdf_extractor.hpp 对应 PdfExtractor,pdf_bookmark_editor.hpp 对应 PdfBookmarkEditor,form_editor.hpp 对应 FormEditor,以及 bookmark.hpp 对应 Bookmark / Bookmarks 值类型。