Comment charger un document en C++

Comment charger un document en C++

Aspose.PDF FOSS for C++ ouvre un PDF existant via la classe Document — à partir d’un chemin de fichier simple, ou avec un mot de passe lorsque la source est chiffrée — et expose les métadonnées /Info du fichier via DocumentInfo. Ce guide couvre le chargement d’un document, la détection et l’ouverture de fichiers protégés par mot de passe, la lecture et la mise à jour des métadonnées titre/auteur/producteur, ainsi que l’enregistrement du résultat. La bibliothèque est ajoutée à un projet via CMake; il n’y a aucune étape d’installation via un gestionnaire de paquets.

Guide étape par étape

Étape 1: Installer le paquet

Ajoutez la bibliothèque comme sous-répertoire CMake et liez-vous à la cible aspose_pdf_foss:

add_subdirectory(aspose.pdf-foss-for-cpp)
target_link_libraries(your_app PRIVATE aspose_pdf_foss)

Vérifiez que la chaîne d’outils et les en-têtes se résolvent en compilant un programme minimal:

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

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

Une compilation réussie affichant pages: 0 confirme que la bibliothèque est correctement liée.


Étape 2: Importer les classes requises

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

using namespace Aspose::Pdf;

Document et DocumentInfo sont tous deux déclarés directement sous l’espace de noms Aspose::Pdf.


Étape 3: Ouvrir un document PDF à partir d’un chemin de fichier

Le constructeur Document(filename) lit le fichier, analyse sa table de références croisées et son arbre de pages, et construit le modèle en mémoire. Il lève std::system_error lorsque le fichier n’existe pas ou ne peut pas être lu, et std::runtime_error lorsque le fichier n’est pas un PDF valide:

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

Étape 4: Ouvrir un document protégé par mot de passe

Le constructeur à un argument de l’étape 3 n’authentifie jamais le mot de passe et n’inspecte pas l’entrée /Encrypt du trailer, de sorte que IsEncrypted() sur un document ouvert de cette manière signale toujours false — même lorsque le fichier source est réellement chiffré. Pour détecter et ouvrir un PDF chiffré, utilisez le constructeur à deux arguments, qui lit /Encrypt et authentifie le mot de passe que vous fournissez:

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

Si le PDF source n’est pas chiffré, l’argument du mot de passe est simplement ignoré et le document s’ouvre normalement — il est donc sûr d’utiliser le constructeur à deux arguments même si vous n’êtes pas certain qu’un fichier soit protégé.


Étape 5: Lire les métadonnées du document avec DocumentInfo

Document.Info() renvoie un DocumentInfo& lié au dictionnaire /Info du document. Chaque champ prédéfini possède son propre accesseur en lecture, qui renvoie une chaîne vide lorsque la clé est absente du fichier source :

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 indique si un nom de clé /Info donné fait partie de ces champs intégrés, par opposition à une clé personnalisée ajoutée avec Add :

bool builtin = DocumentInfo::IsPredefinedKey("Title");   // true
bool custom  = DocumentInfo::IsPredefinedKey("MyKey");   // false

Étape 6: Mettre à jour les métadonnées et enregistrer le document

Définissez les métadonnées via les surcharges du setter correspondant, ou via la méthode pratique SetTitle sur Document, puis persistez la modification avec Save :

Document doc("input.pdf");
doc.Info().Author("Report Generator");
doc.SetTitle("Quarterly Report");   // equivalent to doc.Info().Title(title)

doc.Save("output.pdf");

Les modifications de métadonnées sont mises en mémoire tampon et n’écrites qu’à l’appel suivant de Save. Appelez Save(outputFileName) pour écrire vers un nouveau chemin, ou la forme sans argument Save() pour écraser le fichier à partir duquel le document a été initialement ouvert :

Document doc("input.pdf");
doc.SetTitle("Updated In Place");
doc.Save();   // writes back to "input.pdf"

Problèmes courants et correctifs

IsEncrypted() returns false pour un PDF que je sais être protégé par mot de passe

Le constructeur à un seul argument Document(path) n’authentifie jamais contre le dictionnaire /Encrypt du fichier, de sorte que IsEncrypted() signale toujours false sur un document ouvert de cette manière, quel que soit le fait que la source soit réellement chiffrée. Ouvrez le fichier avec le constructeur à deux arguments Document(path, password) à la place — c’est la seule surcharge qui remplit l’état de chiffrement.

Le constructeur à deux arguments lance std::runtime_error

Cela signifie que le PDF source possède une entrée /Encrypt dans son trailer et que le mot de passe fourni ne correspond ni au mot de passe utilisateur ni au mot de passe propriétaire enregistré. Capturez std::runtime_error et invitez à saisir le bon mot de passe, ou confirmez le mot de passe hors bande avant de réessayer.

Save() lance “no source filename to save to”

Le Save() sans argument écrit de nouveau vers le chemin à partir duquel le document a été construit. Un Document créé avec le constructeur sans argument — un document frais en mémoire sans fichier source — n’a aucun chemin vers lequel écrire, de sorte que Save() lance une exception. Appelez Save(outputFileName) à la place.

Decrypt() ne semble pas produire un fichier non protégé

Decrypt() efface le drapeau IsEncrypted() en mémoire afin que les lectures en aval traitent le document comme du texte brut, mais dans la version actuelle il ne réécrit pas le dictionnaire /Encrypt du trailer ni ne ré-encode les chaînes et flux chiffrés. Un appel Save() après Decrypt() réécrit toujours les octets originaux, y compris le chiffrement d’origine — cette méthode ne produit pas encore de copie en texte clair sur le disque.

Title/Author/etc. s’affichent comme des chaînes vides

Les accesseurs DocumentInfo renvoient une chaîne vide, pas une erreur, lorsque la clé /Info correspondante est absente du PDF source. Un résultat vide signifie que le champ n’a jamais été défini dans ce document, et non que la lecture a échoué.

Foire aux questions

Est-ce que Document(path) fonctionne sur un PDF chiffré?

Il analyse généralement l’arborescence des pages sans lever d’exception, mais il n’authentifie jamais un mot de passe et laisse toujours IsEncrypted() à false. Utilisez le constructeur à deux arguments chaque fois que la source pourrait être chiffrée.

Est-il sûr de transmettre un mot de passe à Document(path, password) pour un fichier qui s’avère ne pas être chiffré?

Oui. Lorsque le trailer ne comporte aucune entrée /Encrypt, l’argument mot de passe est ignoré et le document s’ouvre de la même manière qu’avec le constructeur à un seul argument.

Comment distinguer une clé /Info personnalisée d’une clé intégrée?

Appelez le DocumentInfo::IsPredefinedKey(key) statique. Il renvoie true pour Title, Author, Subject, Keywords, Creator, Producer et Trapped, et false pour tout le reste.

Puis-je écraser le fichier que je viens de charger au lieu d’écrire vers un nouveau chemin?

Oui — appelez le Save() sans argument sur un Document qui a été construit à partir d’un chemin de fichier; il réécrit sur ce même chemin source. Il lève une exception pour les documents créés avec le constructeur sans argument, qui n’ont pas de chemin source.

L’enregistrement après Decrypt() supprime-t-il la protection par mot de passe du PDF?

Non, pas dans la version actuelle — voir Common Issues ci-dessus. Decrypt() n’affecte que l’état en mémoire utilisé par les lecteurs de contenu; le fichier écrit par Save() conserve toujours le dictionnaire /Encrypt original.

Voir aussi

 Français