How to Work with the Facades API in Aspose.PDF FOSS for C++

How to Work with the Facades API in Aspose.PDF FOSS for C++

Aspose.PDF FOSS for C++ groups a set of higher-level facade and editor classes — PdfExtractor, PdfBookmarkEditor, PdfContentEditor, PdfAnnotationEditor, FormEditor, PdfFileEditor, and PdfConverter among them — in the Aspose::Pdf::Facades namespace. Each one wraps a single document-maintenance task on top of the core Document API, so you can extract content, edit bookmarks, or fill form fields without hand-rolling the underlying page and object walks yourself. This guide focuses on PdfExtractor, the facade used to pull embedded file attachments, page text, and embedded images out of an existing PDF.

Step-by-Step Guide

Step 1: Install the Package

Add Aspose.PDF FOSS for C++ as a CMake subdirectory and link the static library target:

git clone https://github.com/aspose-pdf-foss/Aspose.PDF-FOSS-for-Cpp.git
add_subdirectory(Aspose.PDF-FOSS-for-Cpp)
target_link_libraries(your_app PRIVATE aspose_pdf_foss)

Confirm the toolchain and link step resolve correctly before writing any facade code:

cmake -S . -B build
cmake --build build

A clean build against a C++20 compiler confirms aspose_pdf_foss is linked into your_app.


Step 2: Import Required Classes

PdfExtractor lives under aspose/pdf/facades/, alongside Document from the core namespace:

#include <aspose/pdf/document.hpp>
#include <aspose/pdf/facades/pdf_extractor.hpp>

using namespace Aspose::Pdf;
using namespace Aspose::Pdf::Facades;

Step 3: Bind a Document to PdfExtractor

Every facade class derives from a common Facade base that exposes BindPdf(srcFile) and BindPdf(srcDoc) to attach it to a document after construction. PdfExtractor also accepts an already-open Document directly in its constructor, which is the pattern used throughout this guide:

Document doc("input.pdf");
PdfExtractor extractor(doc);

Step 4: Extract Embedded File Attachments

Check Document::EmbeddedFiles() first, then read the attachment names with GetAttachNames() and pull an attachment’s bytes out to disk with 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");
}

Step 5: Extract Text from Every Page

ExtractText() followed by GetText() writes the whole document’s text to a single file:

extractor.ExtractText();
extractor.GetText("extracted_text.txt");

To capture one file per page instead, set the page range with StartPage() / EndPage(), then drive HasNextPageText() / GetNextPageText() in a loop, giving each call its own output path:

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;
}

Step 6: Extract Embedded Images

ExtractImage() primes the image cursor; HasNextImage() / GetNextImage() then walk the images one at a time, writing each to the path you pass in:

extractor.ExtractImage();

int imageIndex = 1;
while (extractor.HasNextImage()) {
    std::string outputFile = "extracted_image_" + std::to_string(imageIndex);
    if (extractor.GetNextImage(outputFile)) {
        ++imageIndex;
    }
}

Common Issues and Fixes

GetAttachNames() returns an empty vector. The source PDF has no embedded files. Check doc.EmbeddedFiles().Count() before calling any attachment method on PdfExtractor so you don’t attempt to extract from a document that never had attachments.

The page-text loop never enters the body. HasNextPageText() returns false immediately if StartPage() / EndPage() were never set, or if they were set to a range outside the document’s actual page count. Set the range explicitly from doc.Pages().Count() before checking HasNextPageText().

GetNextImage() returns false on the first call. ExtractImage() must be called once to prime the image cursor before you check HasNextImage() or call GetNextImage(). Calling GetNextImage() without a prior ExtractImage() call is undefined from the caller’s perspective — always call ExtractImage() first.

Every extracted image or page-text file overwrites the previous one. GetNextImage() and GetNextPageText() each take a literal output path; the facade does not generate unique filenames for you. Build a distinct path per iteration (for example, by appending an incrementing counter) as shown in Steps 5 and 6.

Link error: undefined reference to aspose_pdf_foss symbols. Confirm add_subdirectory() points at the cloned repository root and that target_link_libraries() names the aspose_pdf_foss target exactly, with a C++20 standard configured for your_app.

Frequently Asked Questions

What’s the difference between the Facades API and the core Document API?

The core Document API (Document, PageCollection, Annotation, and so on) exposes the PDF object model directly. Facade classes such as PdfExtractor sit on top of it and package a specific multi-step task — extracting content, editing bookmarks, filling form fields — behind a narrower, purpose-built interface.

Can I edit bookmarks or fill form fields the same way I extract content with PdfExtractor?

Yes. PdfBookmarkEditor (with CreateBookmarks(), ModifyBookmarks(), ExtractBookmarks(), and DeleteBookmarks()) and FormEditor (with AddField(), RemoveField(), and SetFieldAttribute()) live in the same Aspose::Pdf::Facades namespace and follow the same include/construct pattern shown in Steps 2 and 3 — each just operates on a different part of the document.

Can PdfExtractor read a password-protected PDF?

Set the password before calling any extraction method:

extractor.Password("owner-or-user-password");

PdfExtractor::Password() is a plain read/write property, so it must be set ahead of ExtractText(), ExtractImage(), or the attachment methods.

What happens if the PDF has no text, images, or attachments to extract?

Nothing throws. GetAttachNames() returns an empty vector, and HasNextPageText() / HasNextImage() return false on the first check, so the corresponding loop body simply never runs.

Which header do I include for a specific facade class?

Each facade class ships its own header under aspose/pdf/facades/, matching the class name: pdf_extractor.hpp for PdfExtractor, pdf_bookmark_editor.hpp for PdfBookmarkEditor, form_editor.hpp for FormEditor, and bookmark.hpp for the Bookmark / Bookmarks value types.

See Also