Cách làm việc với các Facade API trong Aspose.PDF FOSS for C++
Aspose.PDF FOSS for C++ nhóm một tập hợp các lớp facade và editor cấp cao — PdfExtractor, PdfBookmarkEditor, PdfContentEditor, PdfAnnotationEditor, FormEditor, PdfFileEditor, và PdfConverter trong số chúng — trong không gian tên Aspose::Pdf::Facades. Mỗi lớp bao bọc một tác vụ bảo trì tài liệu duy nhất dựa trên core Document API, cho phép bạn trích xuất nội dung, chỉnh sửa dấu trang, hoặc điền vào các trường biểu mẫu mà không cần tự viết mã để duyệt các trang và đối tượng nền tảng. Hướng dẫn này tập trung vào PdfExtractor, facade được dùng để lấy các tệp đính kèm nhúng, văn bản trang và hình ảnh nhúng ra khỏi một PDF hiện có.
Hướng dẫn từng bước
Bước 1: Cài đặt gói
Thêm Aspose.PDF FOSS for C++ như một thư mục con CMake và liên kết mục tiêu thư viện tĩnh:
git clone https://github.com/aspose-pdf-foss/Aspose.PDF-FOSS-for-Cpp.gitadd_subdirectory(Aspose.PDF-FOSS-for-Cpp)
target_link_libraries(your_app PRIVATE aspose_pdf_foss)Xác nhận chuỗi công cụ và bước liên kết được giải quyết đúng trước khi viết bất kỳ mã facade nào:
cmake -S . -B build
cmake --build buildQuá trình biên dịch sạch với trình biên dịch C++20 xác nhận aspose_pdf_foss đã được liên kết vào your_app.
Bước 2: Nhập các lớp cần thiết
PdfExtractor nằm dưới aspose/pdf/facades/, cùng với Document từ không gian tên core:
#include <aspose/pdf/document.hpp>
#include <aspose/pdf/facades/pdf_extractor.hpp>
using namespace Aspose::Pdf;
using namespace Aspose::Pdf::Facades;Bước 3: Gắn một tài liệu vào PdfExtractor
Mỗi lớp façade kế thừa từ một lớp cơ sở Facade chung, lớp này công khai BindPdf(srcFile) và BindPdf(srcDoc) để gắn nó vào tài liệu sau khi khởi tạo. PdfExtractor cũng chấp nhận một Document đã mở sẵn trực tiếp trong hàm khởi tạo của nó, đây là mẫu được sử dụng xuyên suốt trong hướng dẫn này:
Document doc("input.pdf");
PdfExtractor extractor(doc);Bước 4: Trích xuất các tệp đính kèm nhúng
Kiểm tra Document::EmbeddedFiles() trước, sau đó đọc tên các tệp đính kèm bằng GetAttachNames() và lấy dữ liệu byte của tệp đính kèm ra đĩa bằng GetAttachment():
#include <iostream>
if (doc.EmbeddedFiles().Count() > 0) {
std::vector<std::string> names = extractor.GetAttachNames();
for (const auto& name : names) {
std::cout << "Attachment: " << name << "\n";
}
// Writes the bytes of the first attachment to disk
extractor.GetAttachment("extracted_attachment.bin");
}Bước 5: Trích xuất văn bản từ mỗi trang
ExtractText() tiếp theo là GetText() ghi toàn bộ văn bản của tài liệu vào một tệp duy nhất:
extractor.ExtractText();
extractor.GetText("extracted_text.txt");Để thay thế ghi lại một tệp cho mỗi trang, hãy đặt phạm vi trang bằng StartPage() / EndPage(), sau đó chạy HasNextPageText() / GetNextPageText() trong một vòng lặp, cung cấp cho mỗi lần gọi đường dẫn đầu ra riêng của nó:
extractor.StartPage(1);
extractor.EndPage(doc.Pages().Count());
int pageNumber = extractor.StartPage();
while (extractor.HasNextPageText()) {
std::string outputFile = "page_" + std::to_string(pageNumber) + ".txt";
extractor.GetNextPageText(outputFile);
++pageNumber;
}Bước 6: Trích xuất hình ảnh nhúng
ExtractImage() khởi tạo con trỏ hình ảnh; HasNextImage() / GetNextImage() sau đó duyệt các hình ảnh từng cái một, ghi mỗi hình vào đường dẫn bạn truyền vào:
extractor.ExtractImage();
int imageIndex = 1;
while (extractor.HasNextImage()) {
std::string outputFile = "extracted_image_" + std::to_string(imageIndex);
if (extractor.GetNextImage(outputFile)) {
++imageIndex;
}
}Các vấn đề thường gặp và cách khắc phục
GetAttachNames() trả về một vector rỗng. Tệp PDF nguồn không có tệp nhúng. Kiểm tra doc.EmbeddedFiles().Count() trước khi gọi bất kỳ phương thức đính kèm nào trên PdfExtractor để bạn không cố gắng trích xuất từ tài liệu chưa bao giờ có đính kèm.
Vòng lặp văn bản trang không bao giờ vào phần thân. HasNextPageText() returns false ngay lập tức nếu StartPage() / EndPage() không bao giờ được đặt, hoặc nếu chúng được đặt thành một phạm vi ngoài số trang thực tế của tài liệu. Đặt phạm vi một cách rõ ràng từ doc.Pages().Count() trước khi kiểm tra HasNextPageText().
GetNextImage() returns false vào lần gọi đầu tiên. ExtractImage() phải được gọi một lần để khởi tạo con trỏ hình ảnh trước khi bạn kiểm tra HasNextImage() hoặc gọi GetNextImage(). Gọi GetNextImage() không có trước ExtractImage() lần gọi là không xác định từ góc nhìn của người gọi — luôn luôn gọi ExtractImage() đầu tiên.
Mỗi hình ảnh hoặc tệp văn bản trang được giải nén sẽ ghi đè lên tệp trước đó. GetNextImage() and GetNextPageText() mỗi cái đều lấy một đường dẫn đầu ra nguyên bản; facade không tự tạo tên tệp duy nhất cho bạn. Tạo một đường dẫn riêng cho mỗi vòng lặp (ví dụ, bằng cách thêm một bộ đếm tăng dần) như được minh họa trong Các bước 5 và 6.
Lỗi liên kết: tham chiếu không xác định tới aspose_pdf_foss các ký hiệu. Confirm add_subdirectory() chỉ tới gốc của kho lưu trữ đã sao chép và rằng target_link_libraries() đặt tên cho aspose_pdf_foss đích một cách chính xác, với tiêu chuẩn C++20 được cấu hình cho your_app.
Câu hỏi thường gặp
Sự khác nhau giữa Facades API và Document cốt lõi API là gì?
Core Document API (Document, PageCollection, Annotation, v.v.) trực tiếp phô bày mô hình đối tượng PDF. Các lớp Facade như PdfExtractor nằm trên nó và gói một nhiệm vụ đa bước cụ thể — trích xuất nội dung, chỉnh sửa dấu trang, điền vào các trường biểu mẫu — sau một giao diện hẹp hơn, được thiết kế riêng cho mục đích.
Tôi có thể chỉnh sửa dấu trang hoặc điền vào các trường biểu mẫu theo cách tôi trích xuất nội dung với PdfExtractor không?
Có. PdfBookmarkEditor (với CreateBookmarks(), ModifyBookmarks(), ExtractBookmarks(), và DeleteBookmarks()) và FormEditor (với AddField(), RemoveField(), và SetFieldAttribute()) cùng tồn tại trong cùng không gian tên Aspose::Pdf::Facades và tuân theo cùng mẫu include/construct được hiển thị trong Bước 2 và 3 — mỗi cái chỉ hoạt động trên một phần khác nhau của tài liệu.
Liệu PdfExtractor có thể đọc PDF được bảo vệ bằng mật khẩu không?
Đặt mật khẩu trước khi gọi bất kỳ phương thức giải nén nào:
extractor.Password("owner-or-user-password");PdfExtractor::Password() là một thuộc tính đọc/ghi đơn giản, vì vậy nó phải được đặt trước ExtractText(), ExtractImage(), hoặc các phương thức đính kèm.
Điều gì sẽ xảy ra nếu PDF không có văn bản, hình ảnh hoặc tệp đính kèm nào để trích xuất?
Không có lỗi nào được ném. GetAttachNames() trả về một vector rỗng, và HasNextPageText() / HasNextImage() trả về false trong lần kiểm tra đầu tiên, vì vậy phần thân vòng lặp tương ứng sẽ không bao giờ chạy.
Tôi nên bao gồm header nào cho một lớp facade cụ thể?
Mỗi lớp facade cung cấp header riêng của nó dưới aspose/pdf/facades/, khớp với tên lớp: pdf_extractor.hpp cho PdfExtractor, pdf_bookmark_editor.hpp cho PdfBookmarkEditor, form_editor.hpp cho FormEditor, và bookmark.hpp cho các kiểu giá trị Bookmark / Bookmarks.