Wie man ein Dokument in C++ lädt

Wie man ein Dokument in C++ lädt

Aspose.PDF FOSS für C++ öffnet ein vorhandenes PDF über die Document Klasse — von einem einfachen Dateipfad aus oder mit einem Passwort, wenn die Quelle verschlüsselt ist — und stellt die /Info Metadaten der Datei über DocumentInfo bereit. Dieser Leitfaden behandelt das Laden eines Dokuments, das Erkennen und Öffnen passwortgeschützter Dateien, das Lesen und Aktualisieren von Titel/Autor/Producer-Metadaten und das Speichern des Ergebnisses. Die Bibliothek wird einem Projekt über CMake hinzugefügt; es gibt keinen Installationsschritt über einen Paket-Manager.

Schritt-für-Schritt-Anleitung

Schritt 1: Paket installieren

Fügen Sie die Bibliothek als CMake-Unterverzeichnis hinzu und linken Sie gegen das aspose_pdf_foss Ziel:

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

Verifizieren Sie, dass die Toolchain und Header aufgelöst werden, indem Sie ein Minimalprogramm kompilieren:

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

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

Ein erfolgreicher Build, der pages: 0 ausgibt, bestätigt, dass die Bibliothek korrekt verlinkt ist.


Schritt 2: Erforderliche Klassen importieren

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

using namespace Aspose::Pdf;

Document und DocumentInfo sind beide direkt unter dem Aspose::Pdf-Namespace deklariert.


Schritt 3: Öffnen eines PDF-Dokuments über einen Dateipfad

Der Document(filename)-Konstruktor liest die Datei, analysiert deren Cross-Reference-Tabelle und Seitenbaum und erstellt das In-Memory-Modell. Er wirft std::system_error, wenn die Datei nicht existiert oder nicht gelesen werden kann, und std::runtime_error, wenn die Datei kein gültiges PDF ist:

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

Schritt 4: Öffnen eines passwortgeschützten Dokuments

Der ein-Argument-Konstruktor aus Schritt 3 authentifiziert niemals ein Passwort und prüft nicht den /Encrypt-Eintrag im Trailer, sodass IsEncrypted() bei auf diese Weise geöffneten Dokumenten stets false meldet – selbst wenn die Quelldatei tatsächlich verschlüsselt ist. Um ein verschlüsseltes PDF zu erkennen und zu öffnen, verwenden Sie den Zwei-Argument-Konstruktor, der /Encrypt liest und das von Ihnen angegebene Passwort authentifiziert:

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

Wenn das Quell-PDF nicht verschlüsselt ist, wird das Passwort-Argument einfach ignoriert und das Dokument öffnet sich normal – daher ist es sicher, den Zwei-Argument-Konstruktor zu verwenden, selbst wenn Sie nicht sicher sind, ob eine Datei geschützt ist.


Schritt 5: Dokumentmetadaten mit DocumentInfo lesen

Document.Info() gibt ein DocumentInfo& zurück, das an das /Info-Wörterbuch des Dokuments gebunden ist. Jedes vordefinierte Feld hat seinen eigenen Lesezugriff, der einen leeren String zurückgibt, wenn der Schlüssel in der Quelldatei fehlt:

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 gibt an, ob ein gegebener /Info-Schlüsselname zu diesen eingebauten Feldern gehört, im Gegensatz zu einem benutzerdefinierten Schlüssel, der mit Add hinzugefügt wurde:

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

Schritt 6: Metadaten aktualisieren und das Dokument speichern

Setzen Sie Metadaten über die passenden Setter-Überladungen oder über die SetTitle-Bequemlichkeitsmethode auf Document, und speichern Sie die Änderung anschließend mit Save:

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

doc.Save("output.pdf");

Metadatenänderungen werden im Speicher vorgemerkt und erst beim nächsten Aufruf von Save geschrieben. Rufen Sie Save(outputFileName) auf, um in einen neuen Pfad zu schreiben, oder die argumentlose Save(), um die Datei zu überschreiben, aus der das Dokument ursprünglich geöffnet wurde:

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

Häufige Probleme und Lösungen

IsEncrypted() returns false für ein PDF, von dem ich weiß, dass es passwortgeschützt ist

Der einargumentige Document(path)-Konstruktor authentifiziert nie gegen das /Encrypt-Dictionary der Datei, sodass IsEncrypted() immer false bei einem auf diese Weise geöffneten Dokument meldet, unabhängig davon, ob die Quelle tatsächlich verschlüsselt ist. Öffnen Sie die Datei stattdessen mit dem zweiargumentigen Document(path, password)-Konstruktor – er ist die einzige Überladung, die den Verschlüsselungszustand füllt.

Der Konstruktor mit zwei Argumenten wirft std::runtime_error

Das bedeutet, dass das Quell-PDF einen /Encrypt-Eintrag in seinem Trailer hat und das angegebene Passwort weder dem dort gespeicherten Benutzer- noch dem Eigentümer-Passwort entspricht. Fangen Sie std::runtime_error ab und fragen Sie nach dem richtigen Passwort, oder bestätigen Sie das Passwort außerhalb des Kanals, bevor Sie es erneut versuchen.

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

Der null-Argument-Save() schreibt zurück in den Pfad, aus dem das Dokument erstellt wurde. Ein Document, das mit dem null-Argument-Konstruktor erzeugt wurde – ein frisches, im Speicher befindliches Dokument ohne Quelldatei – hat keinen Pfad, in den zurückgeschrieben werden kann, sodass Save() wirft. Rufen Sie stattdessen Save(outputFileName) auf.

Decrypt() scheint keine ungeschützte Datei zu erzeugen

Decrypt() löscht das im Speicher befindliche IsEncrypted()-Flag, sodass nachfolgende Lesevorgänge das Dokument als Klartext behandeln, aber in der aktuellen Version wird das /Encrypt-Dictionary des Trailers nicht neu geschrieben und verschlüsselte Zeichenketten und Streams werden nicht neu kodiert. Ein Aufruf von Save() nach Decrypt() schreibt weiterhin die originalen Bytes zurück, einschließlich der ursprünglichen Verschlüsselung – diese Methode erzeugt noch keine Klartextkopie auf dem Datenträger.

Titel/Autor/etc. werden als leere Zeichenketten ausgegeben

DocumentInfo-Zugriffsfunktionen geben eine leere Zeichenkette zurück, keinen Fehler, wenn der entsprechende /Info-Schlüssel im Quell-PDF fehlt. Ein leeres Ergebnis bedeutet, dass das Feld in diesem Dokument nie gesetzt wurde, nicht dass das Lesen fehlgeschlagen ist.

Häufig gestellte Fragen

Funktioniert Document(path) bei einem verschlüsselten PDF?

Es analysiert typischerweise den Seitenbaum, ohne eine Ausnahme zu werfen, authentifiziert jedoch nie ein Passwort und lässt IsEncrypted() immer bei false. Verwenden Sie den Konstruktor mit zwei Argumenten, wenn die Quelle verschlüsselt sein könnte.

Ist es sicher, ein Passwort an Document(path, password) zu übergeben, wenn sich herausstellt, dass die Datei nicht verschlüsselt ist?

Ja. Wenn der Trailer keinen /Encrypt-Eintrag enthält, wird das Passwort-Argument ignoriert und das Dokument wird auf dieselbe Weise geöffnet, wie es mit dem Konstruktor mit einem Argument geschehen würde.

Wie erkenne ich einen benutzerdefinierten /Info-Schlüssel von einem eingebauten?

Rufen Sie das statische DocumentInfo::IsPredefinedKey(key) auf. Es gibt true für Title, Author, Subject, Keywords, Creator, Producer und Trapped zurück, und false für alles andere.

Kann ich die gerade geladene Datei überschreiben, anstatt sie in einen neuen Pfad zu schreiben?

Ja — rufen Sie das argumentlose Save() an einem Document auf, das aus einem Dateipfad konstruiert wurde; es schreibt zurück in denselben Quellpfad. Es wirft eine Ausnahme bei Dokumenten, die mit dem argumentlosen Konstruktor erstellt wurden und keinen Quellpfad besitzen.

Entfernt das Speichern nach Decrypt() den Passwortschutz des PDFs?

Nein, nicht in der aktuellen Version — siehe oben die häufigen Probleme. Decrypt() beeinflusst nur den im Speicher befindlichen Zustand, der von Inhaltslesern verwendet wird; die von Save() geschriebene Datei enthält weiterhin das ursprüngliche /Encrypt-Verzeichnis.

Siehe auch

 Deutsch