Cách làm việc với chú thích PDF trong C++
Aspose.PDF FOSS cho C++ biểu diễn mỗi chú thích PDF như một lớp con của lớp cơ sở chung Annotation, và cung cấp các chú thích trên một trang thông qua AnnotationCollection được trả về bởi Page::Annotations(). Hướng dẫn này thêm một chú thích ghi chú văn bản thuần và một chú thích có kiểu dáng vào một trang bằng TextAnnotation, lưu tài liệu, sau đó mở lại để đọc lại các chú thích và xóa một chú thích. Thư viện được tích hợp vào dự án CMake như một phụ thuộc thư mục con — không có bước cài đặt qua kho gói.
Hướng dẫn từng bước
Bước 1: Cài đặt gói
Thêm thư viện như một thư mục con CMake và liên kết mục tiêu thư viện tĩnh:
add_subdirectory(aspose.pdf-foss-for-cpp)
target_link_libraries(your_app PRIVATE aspose_pdf_foss)Xác minh chuỗi công cụ và bước liên kết được giải quyết đúng với một chương trình tối thiểu:
#include <aspose/pdf/document.hpp>
#include <iostream>
int main() {
Aspose::Pdf::Document doc;
std::cout << "Linked OK — pages: " << doc.Pages().Count() << "\n";
}Một bản dựng thành công in ra pages: 0 xác nhận rằng thư viện đã được liên kết.
Bước 2: Nhập các lớp cần thiết
#include <aspose/pdf/document.hpp>
#include <aspose/pdf/page_collection.hpp>
#include <aspose/pdf/rectangle.hpp>
#include <aspose/pdf/color.hpp>
#include <aspose/pdf/annotations/annotation.hpp>
#include <aspose/pdf/annotations/annotation_collection.hpp>
#include <aspose/pdf/annotations/annotation_type.hpp>
#include <aspose/pdf/annotations/annotation_flags.hpp>
#include <aspose/pdf/annotations/border.hpp>
#include <aspose/pdf/annotations/border_style.hpp>
#include <aspose/pdf/annotations/text_annotation.hpp>
using namespace Aspose::Pdf;
using namespace Aspose::Pdf::Annotations;Bước 3: Tạo tài liệu và Thêm trang
Tạo một tài liệu mới và thêm một trang vào nó. PageCollection::Add() trả về Page vừa được thêm:
Document doc;
Page page = doc.Pages().Add();Bước 4: Thêm chú thích văn bản vào trang
TextAnnotation hiển thị dưới dạng nhận xét kiểu ghi chú dán. Tạo nó từ Document sở hữu, đặt vị trí bằng Rect() và tin nhắn bằng Contents(), sau đó thêm vào AnnotationCollection của trang:
TextAnnotation note{doc};
note.Rect(Rectangle(100.0, 700.0, 200.0, 720.0, false));
note.Contents("Reviewed and approved.");
page.Annotations().Add(note);Bước 5: Định dạng một chú thích thứ hai với màu, viền và các cờ
Annotation cũng cung cấp Color(), Border() và Flags(). Flags() nhận một trường bit AnnotationFlags — kết hợp các giá trị bằng phép OR bitwise để đặt nhiều cờ cùng lúc:
TextAnnotation flagged{doc};
flagged.Rect(Rectangle(100.0, 600.0, 300.0, 650.0, false));
flagged.Contents("Needs follow-up");
flagged.Color(Color::FromRgb(220, 20, 20));
flagged.Flags(AnnotationFlags::Print | AnnotationFlags::ReadOnly);
flagged.Border().Width(2);
flagged.Border().Style(BorderStyle::Dashed);
page.Annotations().Add(flagged);Bước 6: Lưu tài liệu
Không có gì được ghi vào đĩa cho đến khi Save() chạy:
doc.Save("annotated.pdf");Bước 7: Mở lại tệp PDF và Đọc các chú thích của nó
Mở lại tệp đã lưu và đọc lại AnnotationCollection của trang đầu tiên. AnnotationCollection là chỉ số bắt đầu từ 0, và Count() báo cáo số lượng chú thích mà trang chứa:
Document reopened("annotated.pdf");
auto& annots = reopened.Pages()[1].Annotations();
std::cout << "Annotation count: " << annots.Count() << "\n";
for (int i = 0; i < annots.Count(); ++i) {
const auto& a = annots[i];
if (a.AnnotationType() == AnnotationType::Text) {
std::cout << "Text annotation: " << a.Contents() << "\n";
}
}Bước 8: Xóa một chú thích và lưu lại
AnnotationCollection::Delete(index) xóa một chú thích theo vị trí bắt đầu từ 0. Xóa chú thích đầu tiên và lưu kết quả vào một tệp mới:
annots.Delete(0);
reopened.Save("annotated-cleaned.pdf");Các vấn đề thường gặp và cách khắc phục
Không có gì thay đổi trong PDF đã lưu sau khi gọi Annotations().Add()
Hai điều thường gặp gây ra lỗi ở đây. Thứ nhất, PageCollection là dựa trên chỉ số bắt đầu từ 1 (doc.Pages()[1] là trang đầu tiên) trong khi AnnotationCollection là dựa trên chỉ số bắt đầu từ 0 (annots[0] là chú thích đầu tiên) — việc nhầm lẫn hai cách đánh chỉ số này dẫn đến thao tác trên đối tượng sai. Thứ hai, hãy xác nhận Document::Save() thực sự chạy sau khi chú thích được thêm; cho đến lúc đó không có gì được ghi vào đĩa.
AnnotationCollection đánh chỉ mục hoặc Delete(index) throws std::out_of_range
Các chỉ số hợp lệ chạy từ 0 đến Count() - 1. Truyền một chỉ số âm hoặc một chỉ số bằng hoặc lớn hơn Count() sẽ ném std::out_of_range theo thiết kế. Gọi Count() trước để giới hạn bất kỳ vòng lặp hoặc tra cứu nào.
Remove() returns false lần thứ hai tôi gọi nó trên cùng một chú thích
Đây không phải là lỗi. Remove() báo cáo liệu chú thích có được tìm thấy và xóa như một bool; gọi lại nó trên một chú thích đã bị xóa là một thao tác không làm gì và trả về false. Kiểm tra giá trị trả về thay vì giả định Remove() luôn thành công.
Đặt một giá trị mới AnnotationFlags giá trị sẽ xóa các cờ tôi đã đặt trước
Flags(value) thay thế toàn bộ bộ cờ — nó không hợp nhất với giá trị trước. Để thêm hoặc xóa một cờ riêng lẻ, hãy đọc các cờ hiện tại trước và kết hợp chúng bằng các toán tử bitwise, ví dụ a.Flags(a.Flags() | AnnotationFlags::Print) để thêm một cờ, hoặc a.Flags(a.Flags() & ~AnnotationFlags::Print) để xóa một cờ trong khi để lại các cờ còn lại không thay đổi.
Câu hỏi thường gặp
Mối quan hệ giữa Annotation, TextAnnotation và các kiểu phụ chú khác là gì?
Annotation là lớp cơ sở chung. TextAnnotation và các kiểu chú thích cụ thể khác mỗi cái đều chuyên biệt cho một kiểu phụ chú PDF, trong khi vẫn chia sẻ các bộ truy cập Rect(), Contents(), Color(), Flags() và Border() của lớp cơ sở.
Các chú thích có phạm vi áp dụng cho toàn bộ tài liệu hay chỉ cho một trang?
Mỗi trang có AnnotationCollection riêng, được trả về bởi phương thức Annotations() của trang đó. Các chú thích luôn có phạm vi áp dụng cho trang mà chúng được thêm vào, không phải cho toàn bộ tài liệu.
Làm thế nào để tôi đếm số lượng chú thích trên một trang?
Gọi Count() trên AnnotationCollection được trả về bởi Page::Annotations().
Một chú thích có thể vừa có thể in được vừa chỉ đọc cùng một lúc không?
Có. AnnotationFlags là một trường bit, vì vậy hãy kết hợp các giá trị bằng phép OR bitwise, ví dụ AnnotationFlags::Print | AnnotationFlags::ReadOnly.
Việc xóa chú thích khỏi AnnotationCollection có loại bỏ nó khỏi tệp PDF trên đĩa không?
Chỉ sau khi Document::Save() chạy. Delete(), Remove() và Clear() chỉ sửa đổi bộ sưu tập trong bộ nhớ — tệp PDF trên đĩa không thay đổi cho đến khi tài liệu được lưu.