Πώς να φορτώσετε ένα έγγραφο σε C++

Πώς να φορτώσετε ένα έγγραφο σε C++

Aspose.PDF FOSS for C++ ανοίγει ένα υπάρχον PDF μέσω της κλάσης Document — από απλή διαδρομή αρχείου, ή με κωδικό πρόσβασης όταν η πηγή είναι κρυπτογραφημένη — και αποκαλύπτει τα μεταδεδομένα /Info του αρχείου μέσω DocumentInfo. Αυτός ο οδηγός καλύπτει τη φόρτωση ενός εγγράφου, την ανίχνευση και το άνοιγμα αρχείων προστατευμένων με κωδικό πρόσβασης, την ανάγνωση και ενημέρωση των μεταδεδομένων τίτλου/συγγραφέα/παραγωγού, και την αποθήκευση του αποτελέσματος. Η βιβλιοθήκη προστίθεται σε ένα έργο μέσω CMake· δεν υπάρχει βήμα εγκατάστασης μέσω διαχειριστή πακέτων.

Οδηγός βήμα-βήμα

Βήμα 1: Εγκατάσταση του πακέτου

Προσθέστε τη βιβλιοθήκη ως υποκατάλογο CMake και συνδέστε την με τον προορισμό aspose_pdf_foss:

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

Επαληθεύστε ότι η αλυσίδα εργαλείων και οι κεφαλίδες επιλύονται, κάνοντας μεταγλώττιση ενός ελάχιστου προγράμματος:

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

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

Μια επιτυχημένη κατασκευή που εκτυπώνει pages: 0 επιβεβαιώνει ότι η βιβλιοθήκη έχει συνδεθεί σωστά.


Βήμα 2: Εισαγωγή Απαιτούμενων Κλάσεων

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

using namespace Aspose::Pdf;

Document και DocumentInfo δηλώνονται και τα δύο απευθείας κάτω από το χώρο ονομάτων Aspose::Pdf.


Βήμα 3: Άνοιγμα εγγράφου PDF από διαδρομή αρχείου

Ο κατασκευαστής Document(filename) διαβάζει το αρχείο, αναλύει τον πίνακα διασταυρώσεων και το δέντρο σελίδων, και δημιουργεί το μοντέλο στη μνήμη. Ρίχνει std::system_error όταν το αρχείο δεν υπάρχει ή δεν μπορεί να διαβαστεί, και std::runtime_error όταν το αρχείο δεν είναι έγκυρο PDF:

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

Βήμα 4: Άνοιγμα εγγράφου προστατευμένου με κωδικό πρόσβασης

Ο κατασκευαστής με ένα μόνο όρισμα από το Βήμα 3 δεν αυθεντικοποιεί ποτέ κωδικό πρόσβασης ούτε ελέγχει την καταχώρηση /Encrypt του trailer, έτσι το IsEncrypted() σε ένα έγγραφο που ανοίγεται με αυτόν τον τρόπο πάντα αναφέρει false — ακόμη και όταν το αρχικό αρχείο είναι πράγματι κρυπτογραφημένο. Για να ανιχνεύσετε και να ανοίξετε ένα κρυπτογραφημένο PDF, χρησιμοποιήστε τον κατασκευαστή με δύο ορίσματα, ο οποίος διαβάζει /Encrypt και αυθεντικοποιεί τον κωδικό πρόσβασης που παρέχετε:

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

Εάν το πηγαίο PDF δεν είναι κρυπτογραφημένο, το όρισμα κωδικού πρόσβασης αγνοείται απλώς και το έγγραφο ανοίγει κανονικά — έτσι είναι ασφαλές να χρησιμοποιήσετε τον κατασκευαστή με δύο ορίσματα ακόμη και όταν δεν είστε σίγουροι ότι ένα αρχείο είναι προστατευμένο.


Βήμα 5: Ανάγνωση μεταδεδομένων εγγράφου με DocumentInfo

Document.Info() επιστρέφει ένα DocumentInfo& δεσμευμένο στο /Info λεξικό του εγγράφου. Κάθε προεγκατεστημένο πεδίο έχει το δικό του αναγνώστη ανάγνωσης, ο οποίος επιστρέφει μια κενή συμβολοσειρά όταν το κλειδί λείπει από το αρχείο προέλευσης:

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 αναφέρει εάν ένα δεδομένο όνομα κλειδιού /Info είναι ένα από αυτά τα ενσωματωμένα πεδία, σε αντίθεση με ένα προσαρμοσμένο κλειδί που προστέθηκε με το Add:

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

Βήμα 6: Ενημέρωση Μεταδεδομένων και Αποθήκευση του Εγγράφου

Ορίστε τα μεταδεδομένα μέσω των αντίστοιχων υπερφορτώσεων του setter, ή μέσω της μεθόδου ευκολίας SetTitle στο Document, στη συνέχεια διατηρήστε την αλλαγή με το Save:

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

doc.Save("output.pdf");

Οι επεξεργασίες μεταδεδομένων προετοιμάζονται στη μνήμη και γράφονται μόνο στην επόμενη κλήση του Save. Καλέστε το Save(outputFileName) για να γράψετε σε νέο μονοπάτι, ή το Save() χωρίς ορίσματα για να αντικαταστήσετε το αρχείο από το οποίο το έγγραφο αρχικά άνοιξε:

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

Συνηθισμένα Προβλήματα και Διορθώσεις

IsEncrypted() returns false για ένα PDF που γνωρίζω ότι είναι προστατευμένο με κωδικό

Ο κατασκευαστής Document(path) με ένα όρισμα δεν πιστοποιεί ποτέ έναντι του λεξικού /Encrypt του αρχείου, έτσι το IsEncrypted() πάντα αναφέρει false σε ένα έγγραφο που ανοίχτηκε με αυτόν τον τρόπο, ανεξάρτητα από το αν η πηγή είναι πραγματικά κρυπτογραφημένη. Ανοίξτε το αρχείο με τον κατασκευαστή Document(path, password) με δύο ορίσματα αντί για αυτόν — είναι η μοναδική υπερφόρτωση που γεμίζει την κατάσταση κρυπτογράφησης.

Ο κατασκευαστής με δύο ορίσματα εκσπέρνει std::runtime_error

Αυτό σημαίνει ότι το πηγαίο PDF έχει μια καταχώριση /Encrypt στο trailer του και ο παρεχόμενος κωδικός πρόσβασης δεν ταιριάζει ούτε με τον κωδικό χρήστη ούτε με τον κωδικό ιδιοκτήτη που είναι καταγεγραμμένοι εκεί. Πιάνετε το std::runtime_error και ζητήστε τον σωστό κωδικό πρόσβασης, ή επιβεβαιώστε τον κωδικό εκτός καναλιού πριν προσπαθήσετε ξανά.

Save() εκσπέρνει “no source filename to save to”

Ο Save() χωρίς ορίσματα γράφει πίσω στο μονοπάτι από το οποίο δημιουργήθηκε το έγγραφο. Ένα Document που δημιουργήθηκε με τον κατασκευαστή χωρίς ορίσματα — ένα νέο, ενθυλακωμένο στη μνήμη έγγραφο χωρίς πηγαίο αρχείο — δεν έχει μονοπάτι για να γράψει πίσω, έτσι το Save() ρίχνει. Καλέστε το Save(outputFileName) αντί αυτού.

Decrypt() δεν φαίνεται να παράγει ένα μη προστατευμένο αρχείο

Decrypt() καθαρίζει τη σημαία IsEncrypted() στη μνήμη ώστε οι επόμενες αναγνώσεις να αντιμετωπίζουν το έγγραφο ως απλό κείμενο, αλλά στην τρέχουσα έκδοση δεν ξαναγράφει το λεξικό /Encrypt του trailer ή δεν επανακωδικοποιεί τις κρυπτογραφημένες συμβολοσειρές και ροές. Μια κλήση Save() μετά από Decrypt() εξακολουθεί να γράφει τα αρχικά bytes, συμπεριλαμβανομένης της αρχικής κρυπτογράφησης — αυτή η μέθοδος δεν παράγει ακόμη αντίγραφο απλού κειμένου στο δίσκο.

Title/Author/κτλ. εκτυπώνονται ως κενές συμβολοσειρές

DocumentInfo οι μέθοδοι πρόσβασης επιστρέφουν μια κενή συμβολοσειρά, όχι σφάλμα, όταν το αντίστοιχο κλειδί /Info λείπει από το πηγαίο PDF. Ένα κενό αποτέλεσμα σημαίνει ότι το πεδίο δεν είχε ποτέ οριστεί σε αυτό το έγγραφο, όχι ότι η ανάγνωση απέτυχε.

Συχνές Ερωτήσεις

Λειτουργεί το Document(path) σε κρυπτογραφημένο PDF;

Κανονικά αναλύει το δέντρο σελίδων χωρίς να πετάξει εξαίρεση, αλλά ποτέ δεν επαληθεύει έναν κωδικό πρόσβασης και πάντα αφήνει το IsEncrypted() στο false. Χρησιμοποιήστε τον κατασκευαστή με δύο ορίσματα όποτε η πηγή μπορεί να είναι κρυπτογραφημένη.

Είναι ασφαλές να περάσετε έναν κωδικό πρόσβασης στο Document(path, password) για ένα αρχείο που αποδεικνύεται ότι δεν είναι κρυπτογραφημένο;

Ναι. Όταν η trailer δεν έχει καταχώρηση /Encrypt, το όρισμα κωδικού αγνοείται και το έγγραφο ανοίγει με τον ίδιο τρόπο όπως θα έκανε με τον κατασκευαστή ενός ορίσματος.

Πώς μπορώ να ξεχωρίσω ένα προσαρμοσμένο κλειδί /Info από ένα ενσωματωμένο;

Καλέστε το στατικό DocumentInfo::IsPredefinedKey(key). Επιστρέφει true για Title, Author, Subject, Keywords, Creator, Producer και Trapped, και false για οτιδήποτε άλλο.

Μπορώ να αντικαταστήσω το αρχείο που μόλις φόρτωσα αντί να γράψω σε νέο μονοπάτι;

Ναι — καλέστε το χωρίς-όρισμα Save() σε ένα Document που δημιουργήθηκε από διαδρομή αρχείου· γράφει πίσω στην ίδια διαδρομή προέλευσης. Εξαίρει για έγγραφα που δημιουργήθηκαν με τον κατασκευαστή χωρίς όρισμα, τα οποία δεν έχουν διαδρομή προέλευσης.

Αφαιρεί η αποθήκευση μετά το Decrypt() την προστασία κωδικού πρόσβασης του PDF;

Όχι, όχι στην τρέχουσα έκδοση — δείτε τα Common Issues παραπάνω. Το Decrypt() επηρεάζει μόνο την κατάσταση στη μνήμη που χρησιμοποιείται από τους αναγνώστες περιεχομένου· το αρχείο που γράφεται από το Save() εξακολουθεί να περιέχει το αρχικό λεξικό /Encrypt.

Δείτε επίσης

 Ελληνικά