Как работать с фасадами API в Aspose.PDF FOSS for C++
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/, рядом с 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.
Часто задаваемые вопросы
В чём разница между фасадами API и ядром Document API?
Ядро Document API (Document, PageCollection, Annotation и т.д.) напрямую раскрывает модель объектов PDF. Классы фасадов, такие как PdfExtractor, располагаются поверх неё и упаковывают конкретную многошаговую задачу — извлечение контента, редактирование закладок, заполнение полей формы — за более узким, специализированным интерфейсом.
Могу ли я редактировать закладки или заполнять поля формы так же, как извлекаю контент с помощью PdfExtractor?
Да. PdfBookmarkEditor (с CreateBookmarks(), ModifyBookmarks(), ExtractBookmarks() и DeleteBookmarks()) и FormEditor (с AddField(), RemoveField() и SetFieldAttribute()) находятся в том же пространстве имён Aspose::Pdf::Facades и следуют тому же шаблону include/construct, показанному в Шагах 2 и 3 — каждый работает только с разной частью документа.
Может ли 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.