Jak načíst dokument v C++
Aspose.PDF FOSS pro C++ otevírá existující PDF pomocí třídy Document — z běžné cesty k souboru nebo s heslem, pokud je zdroj šifrovaný — a zpřístupňuje metadata souboru /Info prostřednictvím DocumentInfo. Tento průvodce pokrývá načítání dokumentu, detekci a otevírání souborů chráněných heslem, čtení a aktualizaci metadat název/autor/výrobce a uložení výsledku. Knihovna se do projektu přidává pomocí CMake; neexistuje krok instalace přes správce balíčků.
Průvodce krok za krokem
Krok 1: Nainstalujte balíček
Přidejte knihovnu jako podadresář CMake a propojte ji s cílem aspose_pdf_foss:
add_subdirectory(aspose.pdf-foss-for-cpp)
target_link_libraries(your_app PRIVATE aspose_pdf_foss)Ověřte, že toolchain a hlavičky jsou nalezeny, tím že zkompilujete minimální program:
#include <aspose/pdf/document.hpp>
#include <iostream>
int main() {
Aspose::Pdf::Document doc;
std::cout << "Linked OK — pages: " << doc.Pages().Count() << "\n";
}Úspěšná kompilace, která vypíše pages: 0, potvrzuje, že je knihovna správně propojena.
Krok 2: Naimportujte požadované třídy
#include <aspose/pdf/document.hpp>
#include <aspose/pdf/document_info.hpp>
using namespace Aspose::Pdf;Document a DocumentInfo jsou oba deklarovány přímo pod jmenným prostorem Aspose::Pdf.
Krok 3: Otevřete PDF dokument z cesty k souboru
Konstruktor Document(filename) načte soubor, parsuje jeho tabulku křížových odkazů a strom stránek a vytvoří model v paměti. Vyvolá výjimku std::system_error, když soubor neexistuje nebo jej nelze přečíst, a std::runtime_error, když soubor není platný 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";
}Krok 4: Otevřete dokument chráněný heslem
Jednoargumentový konstruktor ze Krok 3 nikdy neověřuje heslo ani nekontroluje položku /Encrypt v traileru, takže IsEncrypted() u dokumentu otevřeného tímto způsobem vždy hlásí false — i když je zdrojový soubor ve skutečnosti zašifrovaný. Pro detekci a otevření zašifrovaného PDF použijte dvouargumentový konstruktor, který načte /Encrypt a ověří zadané heslo:
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";
}Pokud zdrojové PDF není zašifrované, argument hesla se jednoduše ignoruje a dokument se otevře normálně — takže je bezpečné použít dvouargumentový konstruktor i tehdy, když si nejste jisti, že je soubor chráněn.
Krok 5: Načtěte metadata dokumentu pomocí DocumentInfo
Document.Info() vrací DocumentInfo& vázaný na slovník /Info dokumentu. Každé předdefinované pole má svůj vlastní čtecí přístup, který vrátí prázdný řetězec, pokud klíč v zdrojovém souboru chybí:
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 oznamuje, zda je daný název klíče /Info jedním z těchto vestavěných polí, na rozdíl od vlastního klíče přidaného pomocí Add:
bool builtin = DocumentInfo::IsPredefinedKey("Title"); // true
bool custom = DocumentInfo::IsPredefinedKey("MyKey"); // false
Krok 6: Aktualizovat metadata a uložit dokument
Nastavte metadata pomocí odpovídajících přetížených setterů nebo pomocí pohodlné metody SetTitle na Document, a poté změnu uložte pomocí Save:
Document doc("input.pdf");
doc.Info().Author("Report Generator");
doc.SetTitle("Quarterly Report"); // equivalent to doc.Info().Title(title)
doc.Save("output.pdf");Úpravy metadat jsou připraveny v paměti a jsou zapsány až při dalším volání Save. Zavolejte Save(outputFileName) pro zápis na novou cestu nebo bezargumentovou Save() pro přepsání souboru, ze kterého byl dokument původně otevřen:
Document doc("input.pdf");
doc.SetTitle("Updated In Place");
doc.Save(); // writes back to "input.pdf"
Běžné problémy a opravy
IsEncrypted() returns false pro PDF, o kterém vím, že je chráněno heslem
Jednoargumentový konstruktor Document(path) nikdy neověřuje proti slovníku /Encrypt souboru, takže IsEncrypted() vždy hlásí false u dokumentu otevřeného tímto způsobem, bez ohledu na to, zda je zdroj skutečně zašifrován. Otevřete soubor místo toho dvouargumentovým konstruktorem Document(path, password) — je to jediný přetížený konstruktor, který naplní stav šifrování.
Dvouargumentový konstruktor vyhazuje std::runtime_error
To znamená, že zdrojové PDF má v traileru položku /Encrypt a zadané heslo neodpovídá ani uživatelskému, ani vlastníckému heslu tam zaznamenanému. Zachyťte std::runtime_error a vyzvěte k zadání správného hesla, nebo heslo potvrďte mimo kanál před opětovným pokusem.
Save() vyhazuje “no source filename to save to”
Konstruktor bez argumentů Save() zapisuje zpět do cesty, ze které byl dokument vytvořen. Document vytvořený pomocí konstruktoru bez argumentů — čerstvý, paměťový dokument bez zdrojového souboru — nemá žádnou cestu, do které by mohl zapisovat, takže Save() vyhazuje výjimku. Místo toho zavolejte Save(outputFileName).
Decrypt() nezdá se, že by vytvořil nechráněný soubor
Decrypt() vymaže paměťový příznak IsEncrypted(), takže následné čtení považuje dokument za prostý text, ale v aktuálním vydání nepřepíše slovník /Encrypt v traileru ani neenkóduje znovu zašifrované řetězce a proudy. Volání Save() po Decrypt() stále zapisuje původní bajty, včetně původního šifrování — tato metoda zatím nevytváří kopii v prostém textu na disku.
Title/Author/etc. se vypisují jako prázdné řetězce
DocumentInfo accessors vrací prázdný řetězec, ne chybu, když odpovídající klíč /Info chybí ve zdrojovém PDF. Prázdný výsledek znamená, že pole nebylo v tomto dokumentu nikdy nastaveno, ne že čtení selhalo.
Často kladené otázky
Funguje Document(path) na šifrovaném PDF?
Obvykle analyzuje strom stránek bez výjimky, ale nikdy neověřuje heslo a vždy nechává IsEncrypted() na false. Používejte dvouargumentový konstruktor, kdykoli může být zdroj šifrován.
Je bezpečné předat heslo Document(path, password) pro soubor, který se ukáže jako nešifrovaný?
Ano. Když trailer neobsahuje položku /Encrypt, argument hesla se ignoruje a dokument se otevře stejným způsobem, jako by byl použit jednoparametrový konstruktor.
Jak rozeznám vlastní klíč /Info od vestavěného?
Zavolejte statický DocumentInfo::IsPredefinedKey(key). Vrací true pro Title, Author, Subject, Keywords, Creator, Producer a Trapped, a false pro cokoli jiného.
Mohu přepsat soubor, který jsem právě načetl, místo zápisu na novou cestu?
Ano — zavolejte Save() bez argumentů na Document, která byla vytvořena ze souborové cesty; zapíše zpět na stejnou zdrojovou cestu. Vyvolá výjimku u dokumentů vytvořených pomocí konstruktoru bez argumentů, které nemají zdrojovou cestu.
Odstraní uložení po Decrypt() ochranu PDF heslem?
Ne, ne v současném vydání — viz výše sekce Common Issues. Decrypt() ovlivňuje pouze stav v paměti používaný čtečkami obsahu; soubor zapsaný pomocí Save() stále obsahuje původní slovník /Encrypt.