Cara Memuat Dokumen di C++
Aspose.PDF FOSS untuk C++ membuka PDF yang ada melalui kelas Document — dari jalur file biasa, atau dengan kata sandi ketika sumbernya terenkripsi — dan mengekspose metadata /Info file melalui DocumentInfo. Panduan ini mencakup memuat dokumen, mendeteksi dan membuka file yang dilindungi kata sandi, membaca dan memperbarui metadata judul/penulis/producer, serta menyimpan hasilnya. Perpustakaan ditambahkan ke proyek melalui CMake; tidak ada langkah instalasi manajer paket.
Panduan Langkah-demi-Langkah
Langkah 1: Instal Paket
Tambahkan perpustakaan sebagai subdirektori CMake dan tautkan terhadap target aspose_pdf_foss:
add_subdirectory(aspose.pdf-foss-for-cpp)
target_link_libraries(your_app PRIVATE aspose_pdf_foss)Verifikasi toolchain dan header terresolusi dengan mengompilasi program minimal:
#include <aspose/pdf/document.hpp>
#include <iostream>
int main() {
Aspose::Pdf::Document doc;
std::cout << "Linked OK — pages: " << doc.Pages().Count() << "\n";
}Build yang berhasil yang mencetak pages: 0 mengonfirmasi bahwa perpustakaan terhubung dengan benar.
Langkah 2: Impor Kelas yang Diperlukan
#include <aspose/pdf/document.hpp>
#include <aspose/pdf/document_info.hpp>
using namespace Aspose::Pdf;Document dan DocumentInfo keduanya dideklarasikan langsung di bawah namespace Aspose::Pdf.
Langkah 3: Buka Dokumen PDF dari Jalur Berkas
Konstruktor Document(filename) membaca berkas, mengurai tabel referensi silang dan pohon halaman, serta membangun model dalam memori. Ia melempar std::system_error ketika berkas tidak ada atau tidak dapat dibaca, dan std::runtime_error ketika berkas bukan PDF yang 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";
}Langkah 4: Buka Dokumen yang Dilindungi Kata Sandi
Konstruktor satu-argumen dari Langkah 3 tidak pernah mengautentikasi kata sandi atau memeriksa entri /Encrypt pada trailer, sehingga IsEncrypted() pada dokumen yang dibuka dengan cara itu selalu melaporkan false — bahkan ketika berkas sumber memang terenkripsi. Untuk mendeteksi dan membuka PDF terenkripsi, gunakan konstruktor dua-argumen, yang membaca /Encrypt dan mengautentikasi kata sandi yang Anda berikan:
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";
}Jika PDF sumber tidak terenkripsi, argumen kata sandi hanya diabaikan dan dokumen dibuka secara normal — sehingga aman menggunakan konstruktor dua-argumen bahkan ketika Anda tidak yakin sebuah berkas dilindungi.
Langkah 5: Baca Metadata Dokumen dengan DocumentInfo
Document.Info() mengembalikan DocumentInfo& yang terikat pada kamus /Info dokumen. Setiap bidang yang sudah ditentukan memiliki accessor baca masing-masing, yang mengembalikan string kosong ketika kunci tidak ada dalam file sumber:
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 melaporkan apakah nama kunci /Info yang diberikan merupakan salah satu bidang bawaan ini, bukan kunci khusus yang ditambahkan dengan Add:
bool builtin = DocumentInfo::IsPredefinedKey("Title"); // true
bool custom = DocumentInfo::IsPredefinedKey("MyKey"); // false
Langkah 6: Perbarui Metadata dan Simpan Dokumen
Atur metadata melalui overload setter yang cocok, atau melalui metode kenyamanan SetTitle pada Document, kemudian simpan perubahan dengan 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 metadata disiapkan di memori dan hanya dituliskan pada pemanggilan Save berikutnya. Panggil Save(outputFileName) untuk menulis ke jalur baru, atau Save() tanpa argumen untuk menimpa file tempat dokumen awalnya dibuka:
Document doc("input.pdf");
doc.SetTitle("Updated In Place");
doc.Save(); // writes back to "input.pdf"
Masalah Umum dan Solusinya
IsEncrypted() returns false untuk PDF yang saya tahu dilindungi kata sandi
Konstruktor Document(path) satu-argumen tidak pernah mengautentikasi terhadap kamus /Encrypt file, sehingga IsEncrypted() selalu melaporkan false pada dokumen yang dibuka dengan cara ini, terlepas apakah sumbernya sebenarnya terenkripsi atau tidak. Buka file dengan konstruktor Document(path, password) dua-argumen sebagai gantinya — itu satu-satunya overload yang mengisi status enkripsi.
Konstruktor dua argumen melempar std::runtime_error
Ini berarti PDF sumber memiliki entri /Encrypt di trailer-nya dan kata sandi yang diberikan tidak cocok dengan kata sandi pengguna maupun pemilik yang tercatat di sana. Tangkap std::runtime_error dan minta kata sandi yang benar, atau konfirmasi kata sandi secara out-of-band sebelum mencoba lagi.
Save() melempar “no source filename to save to”
Konstruktor Save() tanpa argumen menulis kembali ke jalur asal dokumen dibuat. Sebuah Document yang dibuat dengan konstruktor tanpa argumen — dokumen baru dalam memori tanpa file sumber — tidak memiliki jalur untuk menulis kembali, sehingga Save() melempar. Panggil Save(outputFileName) sebagai gantinya.
Decrypt() tampaknya tidak menghasilkan file yang tidak dilindungi
Decrypt() menghapus flag IsEncrypted() dalam memori sehingga pembacaan selanjutnya memperlakukan dokumen sebagai teks biasa, tetapi pada rilis saat ini tidak menulis ulang kamus /Encrypt trailer atau mengkode ulang string dan aliran yang terenkripsi. Panggilan Save() setelah Decrypt() masih menulis kembali byte asli, termasuk enkripsi asli — metode ini belum menghasilkan salinan teks biasa di disk.
Title/Author/etc. dicetak sebagai string kosong
Akses DocumentInfo mengembalikan string kosong, bukan error, ketika kunci /Info yang bersangkutan tidak ada dalam PDF sumber. Hasil kosong berarti bidang tersebut tidak pernah diatur pada dokumen itu, bukan bahwa pembacaan gagal.
Pertanyaan yang Sering Diajukan
Apakah Document(path) berfungsi pada PDF yang dienkripsi?
Biasanya ia mem-parsing pohon halaman tanpa melempar pengecualian, tetapi tidak pernah mengautentikasi kata sandi dan selalu meninggalkan IsEncrypted() pada false. Gunakan konstruktor dua-argumen setiap kali sumber mungkin terenkripsi.
Apakah aman memberikan kata sandi ke Document(path, password) untuk file yang ternyata tidak terenkripsi?
Ya. Ketika trailer tidak memiliki entri /Encrypt, argumen kata sandi diabaikan dan dokumen dibuka dengan cara yang sama seperti menggunakan konstruktor satu-argumen.
Bagaimana cara membedakan kunci /Info kustom dengan yang bawaan?
Panggil static DocumentInfo::IsPredefinedKey(key). Ia mengembalikan true untuk Title, Author, Subject, Keywords, Creator, Producer, dan Trapped, serta false untuk hal lainnya.
Apakah saya dapat menimpa file yang baru saja saya muat alih-alih menulis ke jalur baru?
Ya — panggil Save() tanpa argumen pada Document yang dibangun dari jalur file; ia menulis kembali ke jalur sumber yang sama. Ia melempar untuk dokumen yang dibuat dengan konstruktor tanpa argumen, yang tidak memiliki jalur sumber.
Apakah menyimpan setelah Decrypt() menghapus perlindungan kata sandi PDF?
Tidak, tidak dalam rilis saat ini — lihat Masalah Umum di atas. Decrypt() hanya memengaruhi keadaan dalam memori yang digunakan oleh pembaca konten; file yang ditulis oleh Save() masih membawa kamus /Encrypt asli.