Come lavorare con i documenti PDF in C++

Come lavorare con i documenti PDF in C++

Aspose.PDF FOSS per C++ è una libreria C++20 con licenza MIT, senza dipendenze, costruita e collegata con CMake — non è necessario aggiungere alcuna importazione da gestore di pacchetti. Questa guida percorre il flusso di lavoro centrale basato su Document: aprire un PDF esistente, ispezionare le sue pagine e i metadati, estrarre il testo e renderizzare una pagina in un’immagine raster.

Guida passo-passo

Passo 1: Installa il pacchetto

Clona il repository e aggiungilo al tuo progetto CMake come sottodirectory:

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)

Oppure configurarlo e compilarlo in modalità standalone:

cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build

Verifica che la toolchain risolva compilando un programma minimale contro le intestazioni:

#include <aspose/pdf/document.hpp>
#include <iostream>

int main() {
    Aspose::Pdf::Document doc;
    std::cout << "Linked OK - pages: " << doc.Pages().Count() << "\n";
}

Una build riuscita che stampa pages: 0 per il Document appena costruito e vuoto conferma che la libreria è collegata correttamente.


Passo 2: Importa le classi necessarie

#include <aspose/pdf/document.hpp>
#include <aspose/pdf/document_info.hpp>
#include <aspose/pdf/page.hpp>
#include <aspose/pdf/page_collection.hpp>
#include <aspose/pdf/text_absorber.hpp>
#include <aspose/pdf/bmp_device.hpp>
#include <aspose/pdf/resolution.hpp>
#include <fstream>
#include <iostream>

Passo 3: Apri un documento PDF e conta le sue pagine

Costruisci un Document da un percorso file per aprire un PDF esistente. Document::Pages() restituisce il PageCollection, e Count() indica quante pagine contiene:

Aspose::Pdf::Document doc("input.pdf");
std::cout << "Page count: " << doc.Pages().Count() << "\n";

Passo 4: Leggi i metadati del documento

Document::Info() restituisce un oggetto DocumentInfo con accessor di lettura/scrittura tipizzati per le voci standard del dizionario /Info:

auto& info = doc.Info();
std::cout << "Title: "    << info.Title()    << "\n";
std::cout << "Author: "   << info.Author()   << "\n";
std::cout << "Producer: " << info.Producer() << "\n";

Passo 5: Estrai il testo da una pagina

Aspose::Pdf::Text::TextAbsorber percorre un Document o un singolo Page e accumula il testo che incontra; Text() restituisce il risultato in seguito. PageCollection è indicizzato a partire da 1, quindi Pages()[1] è la prima pagina:

auto page = doc.Pages()[1];

Aspose::Pdf::Text::TextAbsorber absorber;
absorber.Visit(page);
std::cout << absorber.Text() << "\n";

Visit() accetta anche l’intero Document direttamente (absorber.Visit(doc)) quando vuoi che il testo di tutte le pagine sia concatenato insieme invece di una singola pagina.


Passo 6: Renderizza la pagina in un’immagine raster

BmpDevice rende un Page in un’immagine BMP non compressa. Il suo costruttore accetta un Resolution che controlla i DPI di output, e Process() scrive i byte renderizzati in qualsiasi std::ostream:

Aspose::Pdf::Devices::BmpDevice device(Aspose::Pdf::Devices::Resolution(150));

std::ofstream imageOut("page1.bmp", std::ios::binary);
device.Process(page, imageOut);

Passo 7: Aggiornare i metadati e salvare il documento

I setter su DocumentInfo preparano le modifiche che vengono applicate al prossimo esecuzione di Save() sul Document proprietario:

doc.Info().Title("Processed by Aspose.PDF FOSS for C++");
doc.Save("output.pdf");

Problemi comuni e soluzioni

Accessing Pages()[0] throws std::out_of_range

PageCollection è indicizzato a partire da1, in accordo con la semantica canonica di Aspose.PDF — la prima pagina è Pages()[1]. Un indice inferiore a1 o superiore a Count() genera un’eccezione.

TextAbsorber::Text() restituisce una stringa vuota

Text() restituisce ciò che è stato accumulato dalla chiamata più recente di Visit(). Verifica che Visit() sia stato effettivamente chiamato prima di leggere Text(), e che la pagina o il documento che hai visitato contenga testo estraibile anziché solo immagini scansionate.

Il file BMP renderizzato è inaspettatamente piccolo o appare vuoto

Un valore basso di Resolution produce un’immagine raster piccola. Aumenta i DPI forniti a Resolution — per esempio, Resolution(300) per un’output di qualità di stampa — e verifica che l’indice della pagina passato a Process() sia quello previsto.

DocumentInfo i campi vengono letti nuovamente come stringhe vuote

Non tutti i produttori di PDF scrivono voci standard /Info. Controlla Producer() e Creator() per valori vuoti prima di presumere che l’estrazione dei metadati sia fallita — una stringa vuota è il risultato definito per una chiave assente.

Modifiche apportate con Info().Title(...) non compaiono nel file salvato

Le mutazioni DocumentInfo sono messe in coda in memoria e vengono salvate solo al prossimo avvio di Save() sulla stessa istanza Document. Assicurati che la modifica dei metadati avvenga prima di Save(), non dopo.

Domande Frequenti

L’indicizzazione delle pagine è basata su zero o su uno in Aspose.PDF FOSS per C++?

Basata su uno. doc.Pages()[1] è sempre la prima pagina.

Può TextAbsorber estrarre il testo da una singola pagina invece che dall’intero documento?

Sì. Visit() è sovraccaricato per accettare o un Document — che estrae il testo di ogni pagina — o un singolo Page, che estrae solo il testo di quella pagina.

Devo chiamare Save() se leggo solo i dati dal documento?

No. Save() è necessario solo dopo modifiche che devono essere scritte su un file, come la modifica dei campi DocumentInfo. Leggere il conteggio delle pagine, estrarre testo o renderizzare una pagina non modifica il documento.

Come posso controllare la risoluzione di una pagina renderizzata?

Passa un valore Resolution al costruttore del dispositivo — ad esempio, Resolution(150) per 150 DPI. Valori più alti producono immagini raster più grandi e di maggiore fedeltà.

Quale formato produce BmpDevice?

Un’immagine BMP non compressa scritta direttamente al std::ostream passato a Process().

Vedi anche

 Italiano