Cum să încărcaţi un document în C++
Aspose.PDF FOSS pentru C++ deschide un PDF existent prin clasa Document — de la o cale simplă de fișier, sau cu o parolă când sursa este criptată — și expune metadatele /Info ale fișierului prin DocumentInfo. Acest ghid acoperă încărcarea unui document, detectarea și deschiderea fișierelor protejate prin parolă, citirea și actualizarea metadatelor titlu/autor/producător și salvarea rezultatului. Biblioteca este adăugată la un proiect prin CMake; nu există pas de instalare prin manager de pachete.
Ghid pas cu pas
Pasul 1: Instalează pachetul
Adaugă biblioteca ca subdirector CMake și leag-o de ținta aspose_pdf_foss:
add_subdirectory(aspose.pdf-foss-for-cpp)
target_link_libraries(your_app PRIVATE aspose_pdf_foss)Verifică că lanțul de instrumente și anteturile sunt rezolvate compilând un program minimal:
#include <aspose/pdf/document.hpp>
#include <iostream>
int main() {
Aspose::Pdf::Document doc;
std::cout << "Linked OK — pages: " << doc.Pages().Count() << "\n";
}O compilare reușită care afișează pages: 0 confirmă că biblioteca este legată corect.
Pasul 2: Importă clasele necesare
#include <aspose/pdf/document.hpp>
#include <aspose/pdf/document_info.hpp>
using namespace Aspose::Pdf;Document și DocumentInfo sunt ambele declarate direct în spațiul de nume Aspose::Pdf.
Pasul 3: Deschide un document PDF dintr-o cale de fișier
Constructorul Document(filename) citește fișierul, analizează tabelul său de referință încrucișată și arborele de pagini și construiește modelul în memorie. Aruncă std::system_error când fișierul nu există sau nu poate fi citit și std::runtime_error când fișierul nu este un PDF valid:
#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";
}Pasul 4: Deschide un document protejat prin parolă
Constructorul cu un singur argument din Pasul 3 nu autentifică niciodată o parolă și nu inspectează intrarea /Encrypt a trailer-ului, astfel că IsEncrypted() pe un document deschis în acest mod raportează întotdeauna false — chiar și atunci când fișierul sursă este cu adevărat criptat. Pentru a detecta și deschide un PDF criptat, folosește constructorul cu două argumente, care citește /Encrypt și autentifică parola pe care o furnizezi:
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";
}Dacă PDF-ul sursă nu este criptat, argumentul de parolă este pur și simplu ignorat și documentul se deschide normal — deci este sigur să folosești constructorul cu două argumente chiar și când nu ești sigur că un fișier este protejat.
Pasul 5: Citește metadatele documentului cu DocumentInfo
Document.Info() returnează un DocumentInfo& legat de dicționarul /Info al documentului. Fiecare câmp predefinit are propriul său accesator de citire, care returnează un șir gol atunci când cheia nu există în fișierul sursă:
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 raportează dacă un nume de cheie /Info dat este unul dintre aceste câmpuri încorporate, spre deosebire de o cheie personalizată adăugată cu Add:
bool builtin = DocumentInfo::IsPredefinedKey("Title"); // true
bool custom = DocumentInfo::IsPredefinedKey("MyKey"); // false
Pasul 6: Actualizează metadatele și salvează documentul
Setează metadatele prin suprasarcinile setter-ului corespunzătoare, sau prin metoda convenabilă SetTitle pe Document, apoi persișă schimbarea cu Save:
Document doc("input.pdf");
doc.Info().Author("Report Generator");
doc.SetTitle("Quarterly Report"); // equivalent to doc.Info().Title(title)
doc.Save("output.pdf");Editările de metadate sunt pregătite în memorie și scrise doar la următorul apel Save. Apelează Save(outputFileName) pentru a scrie într-o cale nouă, sau Save() fără argumente pentru a suprascrie fișierul din care documentul a fost deschis inițial:
Document doc("input.pdf");
doc.SetTitle("Updated In Place");
doc.Save(); // writes back to "input.pdf"
Probleme comune și remedii
IsEncrypted() returns false pentru un PDF pe care știu că este protejat prin parolă
Constructorul cu un singur argument Document(path) nu autentifică niciodată față de dicționarul /Encrypt al fișierului, astfel că IsEncrypted() raportează întotdeauna false pe un document deschis în acest mod, indiferent dacă sursa este cu adevărat criptată. Deschide fișierul cu constructorul cu două argumente Document(path, password) în schimb — este singura suprasarcină care populează starea de criptare.
Constructorul cu două argumente aruncă std::runtime_error
Aceasta înseamnă că PDF-ul sursă are o intrare /Encrypt în trailer și parola furnizată nu corespunde nici parolei de utilizator, nici celei de proprietar înregistrate acolo. Prinde std::runtime_error și solicită parola corectă, sau confirmă parola printr-un canal extern înainte de a încerca din nou.
Save() aruncă “no source filename to save to”
Constructorul fără argumente Save() scrie înapoi în calea din care a fost construit documentul. Un Document creat cu constructorul fără argumente — un document nou, în memorie, fără fișier sursă — nu are o cale în care să scrie înapoi, astfel că Save() aruncă. Apelează Save(outputFileName) în schimb.
Decrypt() nu pare să producă un fișier neprotejat
Decrypt() șterge flagul IsEncrypted() în memorie, astfel încât citirile ulterioare să trateze documentul ca text simplu, dar în versiunea curentă nu rescrie dicționarul /Encrypt al trailerului sau nu recodifică șirurile și fluxurile criptate. Un apel Save() după Decrypt() scrie în continuare octeții originali, inclusiv criptarea originală — această metodă nu produce încă o copie în text simplu pe disc.
Titlul/Autorul/etc. se afișează ca șiruri goale
Accesoriile DocumentInfo returnează un șir gol, nu o eroare, când cheia /Info corespunzătoare este absentă din PDF-ul sursă. Un rezultat gol înseamnă că câmpul nu a fost niciodată setat în acel document, nu că citirea a eșuat.
Întrebări frecvente
Funcționează Document(path) pe un PDF criptat?
În mod obișnuit analizează arborele de pagini fără a arunca excepții, dar nu autentifică niciodată o parolă și lasă întotdeauna IsEncrypted() la false. Folosiți constructorul cu două argumente ori de câte ori sursa ar putea fi criptată.
Este sigur să transmiteți o parolă către Document(path, password) pentru un fișier care se dovedește că nu este criptat?
Da. Când trailerul nu are o intrare /Encrypt, argumentul parolă este ignorat și documentul se deschide în același mod ca și cu constructorul cu un singur argument.
Cum pot distinge o cheie /Info personalizată de una încorporată?
Apelați static DocumentInfo::IsPredefinedKey(key). Returnează true pentru Title, Author, Subject, Keywords, Creator, Producer și Trapped, și false pentru orice altceva.
Pot să suprascriu fișierul pe care tocmai l-am încărcat în loc să scriu într-o cale nouă?
Da — apelează Save() fără argumente pe un Document care a fost construit dintr-o cale de fișier; scrie înapoi în aceeași cale sursă. Aruncă o excepție pentru documentele create cu constructorul fără argumente, care nu au o cale sursă.
Salvarea după Decrypt() elimină protecția cu parolă a PDF-ului?
Nu, nu în versiunea curentă — vezi Probleme comune de mai sus. Decrypt() afectează doar starea în memorie utilizată de cititorii de conținut; fișierul scris de Save() păstrează în continuare dicționarul /Encrypt original.