Come caricare un documento in C++
Aspose.PDF FOSS per C++ apre un PDF esistente tramite la classe Document — da un percorso file semplice, o con una password quando la sorgente è crittografata — e espone i metadati /Info del file tramite DocumentInfo. Questa guida copre il caricamento di un documento, la rilevazione e l’apertura di file protetti da password, la lettura e l’aggiornamento dei metadati titolo/autore/produttore, e il salvataggio del risultato. La libreria viene aggiunta a un progetto tramite CMake; non è previsto alcun passaggio di installazione tramite gestore di pacchetti.
Guida passo-passo
Passo 1: Installa il pacchetto
Aggiungi la libreria come sottodirectory CMake e collega al target aspose_pdf_foss:
add_subdirectory(aspose.pdf-foss-for-cpp)
target_link_libraries(your_app PRIVATE aspose_pdf_foss)Verifica che la toolchain e gli header vengano risolti compilando un programma minimale:
#include <aspose/pdf/document.hpp>
#include <iostream>
int main() {
Aspose::Pdf::Document doc;
std::cout << "Linked OK — pages: " << doc.Pages().Count() << "\n";
}Una compilazione riuscita che stampa pages: 0 conferma che la libreria è collegata correttamente.
Passo 2: Importa le classi richieste
#include <aspose/pdf/document.hpp>
#include <aspose/pdf/document_info.hpp>
using namespace Aspose::Pdf;Document e DocumentInfo sono entrambi dichiarati direttamente sotto lo spazio dei nomi Aspose::Pdf.
Passo 3: Apri un documento PDF da un percorso file
Il costruttore Document(filename) legge il file, analizza la sua tabella di riferimento incrociato e l’albero delle pagine, e costruisce il modello in memoria. Lancia std::system_error quando il file non esiste o non può essere letto, e std::runtime_error quando il file non è un PDF valido:
#include <iostream>
#include <stdexcept>
try {
Document doc("input.pdf");
std::cout << "Pages: " << doc.Pages().Count() << "\n";
} catch (const std::runtime_error& e) {
std::cerr << "Not a valid PDF: " << e.what() << "\n";
} catch (const std::system_error& e) {
std::cerr << "Could not read file: " << e.what() << "\n";
}Passo 4: Apri un documento protetto da password
Il costruttore a singolo argomento del Passo 3 non autentica mai una password né controlla l’elemento /Encrypt del trailer, quindi IsEncrypted() su un documento aperto in questo modo segnala sempre false — anche quando il file sorgente è effettivamente cifrato. Per rilevare e aprire un PDF cifrato, utilizza il costruttore a due argomenti, che legge /Encrypt e autentica la password fornita:
try {
Document doc("input.pdf", "user-password");
if (doc.IsEncrypted()) {
std::cout << "Opened an encrypted document.\n";
}
} catch (const std::runtime_error& e) {
// Thrown when /Encrypt is present and the password matches
// neither the user nor the owner entry in the trailer.
std::cerr << "Wrong password or unreadable /Encrypt dictionary: "
<< e.what() << "\n";
}Se il PDF sorgente non è cifrato, l’argomento password viene semplicemente ignorato e il documento si apre normalmente — quindi è sicuro usare il costruttore a due argomenti anche quando non sei certo che un file sia protetto.
Passo 5: Leggi i metadati del documento con DocumentInfo
Document.Info() restituisce un DocumentInfo& legato al dizionario /Info del documento. Ogni campo predefinito ha il proprio accessor di lettura, che restituisce una stringa vuota quando la chiave è assente dal file sorgente:
Document doc("input.pdf");
DocumentInfo& info = doc.Info();
std::cout << "Title: " << info.Title() << "\n";
std::cout << "Author: " << info.Author() << "\n";
std::cout << "Subject: " << info.Subject() << "\n";
std::cout << "Producer: " << info.Producer() << "\n";
std::cout << "Creator: " << info.Creator() << "\n";
std::cout << "Keywords: " << info.Keywords() << "\n";DocumentInfo::IsPredefinedKey segnala se un determinato nome chiave /Info è uno di questi campi integrati, rispetto a una chiave personalizzata aggiunta con Add:
bool builtin = DocumentInfo::IsPredefinedKey("Title"); // true
bool custom = DocumentInfo::IsPredefinedKey("MyKey"); // false
Passo 6: Aggiorna i Metadati e Salva il Documento
Imposta i metadati tramite le overload del setter corrispondenti, o tramite il metodo di convenienza SetTitle su Document, quindi persisti la modifica con Save:
Document doc("input.pdf");
doc.Info().Author("Report Generator");
doc.SetTitle("Quarterly Report"); // equivalent to doc.Info().Title(title)
doc.Save("output.pdf");Le modifiche ai metadati sono preparate in memoria e vengono scritte solo alla prossima chiamata di Save. Chiama Save(outputFileName) per scrivere su un nuovo percorso, o il Save() senza argomenti per sovrascrivere il file da cui il documento è stato originariamente aperto:
Document doc("input.pdf");
doc.SetTitle("Updated In Place");
doc.Save(); // writes back to "input.pdf"
Problemi Comuni e Correzioni
IsEncrypted() returns false per un PDF che so essere protetto da password
Il costruttore a singolo argomento Document(path) non autentica mai contro il dizionario /Encrypt del file, così IsEncrypted() segnala sempre false su un documento aperto in questo modo, indipendentemente dal fatto che la sorgente sia effettivamente crittata. Apri il file con il costruttore a due argomenti Document(path, password) invece — è l’unica sovraccarico che popola lo stato di crittografia.
Il costruttore a due argomenti lancia std::runtime_error
Ciò significa che il PDF di origine ha una voce /Encrypt nel suo trailer e la password fornita non corrisponde né alla password utente né a quella proprietaria registrata lì. Cattura std::runtime_error e richiedi la password corretta, oppure conferma la password fuori banda prima di riprovare.
Save() lancia “no source filename to save to”
Il Save() senza argomenti scrive nuovamente sul percorso da cui è stato costruito il documento. Un Document creato con il costruttore senza argomenti — un documento fresco in memoria senza file di origine — non ha alcun percorso su cui scrivere, quindi Save() lancia. Chiama Save(outputFileName) invece.
Decrypt() non sembra produrre un file non protetto
Decrypt() cancella il flag IsEncrypted() in memoria in modo che le letture successive trattino il documento come testo in chiaro, ma nella versione attuale non riscrive il dizionario /Encrypt del trailer né ricodifica le stringhe e i flussi crittati. Una chiamata Save() dopo Decrypt() scrive ancora i byte originali, inclusa la crittografia originale — questo metodo non produce ancora una copia in testo chiaro su disco.
Titolo/Autore/ecc. vengono stampati come stringhe vuote
Gli accessor DocumentInfo restituiscono una stringa vuota, non un errore, quando la chiave /Info corrispondente è assente dal PDF di origine. Un risultato vuoto indica che il campo non è mai stato impostato in quel documento, non che la lettura è fallita.
Domande Frequenti
Il Document(path) funziona su un PDF crittografato?
Tipicamente analizza l’albero delle pagine senza lanciare, ma non autentica mai una password e lascia sempre IsEncrypted() a false. Usa il costruttore a due argomenti ogni volta che la sorgente potrebbe essere crittografata.
È sicuro passare una password a Document(path, password) per un file che si scopre non sia crittografato?
Sì. Quando il trailer non contiene una voce /Encrypt, il parametro password viene ignorato e il documento si apre nello stesso modo in cui lo farebbe con il costruttore a singolo argomento.
Come faccio a distinguere una chiave /Info personalizzata da una predefinita?
Chiama il metodo statico DocumentInfo::IsPredefinedKey(key). Restituisce true per Title, Author, Subject, Keywords, Creator, Producer e Trapped, e false per qualsiasi altro valore.
Posso sovrascrivere il file che ho appena caricato invece di scrivere su un nuovo percorso?
Sì — chiama il Save() senza argomenti su un Document che è stato costruito da un percorso file; scrive nuovamente sullo stesso percorso di origine. Genera un’eccezione per i documenti creati con il costruttore senza argomenti, i quali non hanno un percorso di origine.
Il salvataggio dopo Decrypt() rimuove la protezione con password del PDF?
No, non nella versione attuale — see Common Issues above. Decrypt() influisce solo sullo stato in memoria usato dai lettori di contenuto; il file scritto da Save() mantiene ancora il dizionario /Encrypt originale.