วิธีทำงานกับหมายเหตุ PDF ใน C++
Aspose.PDF FOSS สำหรับ C++ แสดงแต่ละหมายเหตุ PDF เป็นคลาสย่อยของคลาสฐาน Annotation ร่วมกัน, และเปิดเผยหมายเหตุบนหน้าโดยผ่าน AnnotationCollection ที่ส่งคืนโดย Page::Annotations(). คู่มือนี้เพิ่มหมายเหตุข้อความธรรมดาและหมายเหตุที่มีรูปแบบลงในหน้าโดยใช้ TextAnnotation, บันทึกเอกสาร, จากนั้นเปิดใหม่เพื่ออ่านหมายเหตุกลับและลบหนึ่งรายการ. ไลบรารีถูกบูรณาการเข้าในโครงการ CMake เป็นการพึ่งพาไดเรกทอรีย่อย — ไม่มีขั้นตอนการติดตั้งจากที่เก็บแพ็กเกจ.
คู่มือแบบขั้นตอนต่อขั้นตอน
ขั้นตอนที่ 1: ติดตั้งแพ็กเกจ
เพิ่มไลบรารีเป็นไดเรกทอรีย่อยของ CMake และเชื่อมโยงเป้าหมายไลบรารีสแตติก:
add_subdirectory(aspose.pdf-foss-for-cpp)
target_link_libraries(your_app PRIVATE aspose_pdf_foss)ตรวจสอบว่า toolchain และขั้นตอนการลิงก์แก้ปัญหาได้อย่างถูกต้องด้วยโปรแกรมขนาดเล็ก:
#include <aspose/pdf/document.hpp>
#include <iostream>
int main() {
Aspose::Pdf::Document doc;
std::cout << "Linked OK — pages: " << doc.Pages().Count() << "\n";
}การสร้างที่สำเร็จและพิมพ์ pages: 0 ยืนยันว่าไลบรารีถูกเชื่อมโยงแล้ว.
ขั้นตอนที่ 2: นำเข้าคลาสที่จำเป็น
#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;ขั้นตอนที่ 3: สร้างเอกสารและเพิ่มหน้า
สร้างเอกสารใหม่และเพิ่มหน้าเข้าไป PageCollection::Add() จะคืนค่า Page ที่เพิ่งเพิ่มใหม่:
Document doc;
Page page = doc.Pages().Add();ขั้นตอนที่ 4: เพิ่มคำอธิบายข้อความลงในหน้า
TextAnnotation แสดงเป็นคอมเมนต์สไตล์โน้ตติดกาว. สร้างจาก Document ที่เป็นเจ้าของ, ตั้งตำแหน่งด้วย Rect() และข้อความด้วย Contents(), จากนั้นเพิ่มลงใน AnnotationCollection ของหน้า:
TextAnnotation note{doc};
note.Rect(Rectangle(100.0, 700.0, 200.0, 720.0, false));
note.Contents("Reviewed and approved.");
page.Annotations().Add(note);ขั้นตอนที่ 5: กำหนดสไตล์ให้คำอธิบายที่สองด้วยสี, เส้นขอบ, และแฟล็ก
Annotation ยังเปิดเผย Color(), Border() และ Flags(). Flags() รับฟิลด์บิตประเภท AnnotationFlags — รวมค่าด้วยการทำ OR แบบบิตเพื่อกำหนดหลายแฟล็กพร้อมกัน:
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);ขั้นตอนที่ 6: บันทึกเอกสาร
จะไม่มีการเขียนใด ๆ ลงดิสก์จนกว่า Save() จะทำงาน:
doc.Save("annotated.pdf");ขั้นตอนที่ 7: เปิด PDF ใหม่และอ่านคำอธิบายประกอบของมัน
เปิดไฟล์ที่บันทึกไว้ใหม่และอ่าน AnnotationCollection ของหน้าที่หนึ่งกลับมา AnnotationCollection ใช้เลขฐานศูนย์, และ Count() รายงานว่าหน้านั้นมีคำอธิบายประกอบกี่รายการ:
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";
}
}ขั้นตอนที่ 8: ลบคำอธิบายประกอบและบันทึกใหม่
AnnotationCollection::Delete(index) ลบคำอธิบายประกอบตามตำแหน่งที่ใช้เลขฐานศูนย์. ลบคำอธิบายประกอบแรกและบันทึกผลลัพธ์ลงไฟล์ใหม่:
annots.Delete(0);
reopened.Save("annotated-cleaned.pdf");ปัญหาทั่วไปและการแก้ไข
ไม่มีอะไรเปลี่ยนแปลงในไฟล์ PDF ที่บันทึกหลังจากเรียก Annotations().Add()
สองสิ่งมักทำให้เกิดข้อผิดพลาดที่นี่ ประการแรก PageCollection ใช้การนับจาก 1 (doc.Pages()[1] คือหน้าที่หนึ่ง) ในขณะที่ AnnotationCollection ใช้การนับจาก 0 (annots[0] คือคำอธิบายแรก) — การสลับสองรูปแบบการนับนี้ทำให้ทำงานกับวัตถุผิด ประการที่สอง ให้ตรวจสอบว่า Document::Save() ทำงานจริงหลังจากเพิ่มคำอธิบายแล้ว; ไม่มีอะไรถูกเขียนลงดิสก์จนกว่าจะถึงจุดนั้น.
AnnotationCollection การทำดัชนีหรือ Delete(index) throws std::out_of_range
ดัชนีที่ถูกต้องอยู่ตั้งแต่ 0 ถึง Count() - 1. การส่งดัชนีเป็นค่าติดลบหรือดัชนีที่เท่ากับหรือมากกว่า Count() จะทำให้เกิด std::out_of_range ตามออกแบบ. เรียก Count() ก่อนเพื่อจำกัดลูปหรือการค้นหาใดๆ.
Remove() returns false ครั้งที่สองที่ฉันเรียกใช้บนคำอธิบายเดียวกัน
นี่ไม่ใช่ข้อผิดพลาด. Remove() รายงานว่าคำอธิบายถูกพบและลบเป็น bool; การเรียกอีกครั้งบนคำอธิบายที่หายไปแล้วเป็นการทำอะไรไม่ได้และจะคืนค่า false. ตรวจสอบค่าที่คืนกลับแทนการสมมติว่า Remove() สำเร็จเสมอ.
การตั้งค่าใหม่ AnnotationFlags ค่าจะล้างแฟล็กที่ฉันได้ตั้งไว้แล้ว
Flags(value) แทนที่ชุด flag ทั้งหมด — ไม่ได้ทำการรวมกับค่าก่อนหน้า. เพื่อเพิ่มหรือเคลียร์ flag เดียว, อ่าน flag ปัจจุบันก่อนและรวมด้วยตัวดำเนินการบิต, ตัวอย่างเช่น a.Flags(a.Flags() | AnnotationFlags::Print) เพื่อเพิ่ม flag, หรือ a.Flags(a.Flags() & ~AnnotationFlags::Print) เพื่อเคลียร์ flag หนึ่งขณะยังคงเหลืออื่นๆ ไม่เปลี่ยน.
คำถามที่พบบ่อย
ความสัมพันธ์ระหว่าง Annotation, TextAnnotation กับประเภทย่อยของคำอธิบายอื่น ๆ คืออะไร?
Annotation เป็นคลาสฐานทั่วไป. TextAnnotation และประเภทคำอธิบายที่เป็นรูปธรรมอื่น ๆ แต่ละประเภทจะปรับให้เข้ากับประเภทย่อยของคำอธิบาย PDF หนึ่ง, ในขณะที่แชร์ตัวเข้าถึง Rect(), Contents(), Color(), Flags(), และ Border() ของคลาสฐาน.
คำอธิบายถูกกำหนดขอบเขตไปที่เอกสารทั้งหมดหรือเพียงหน้าเดียว?
แต่ละหน้ามี AnnotationCollection ของตนเอง, ซึ่งคืนค่าจากเมธอด Annotations() ของหน้านั้น. คำอธิบายจะถูกกำหนดขอบเขตเสมอให้กับหน้าที่เพิ่มเข้ามา, ไม่ใช่ทั้งเอกสารทั้งหมด.
ฉันจะนับจำนวนคำอธิบายที่อยู่บนหน้าได้อย่างไร?
เรียก Count() บน AnnotationCollection ที่คืนค่าจาก Page::Annotations().
คำอธิบายสามารถเป็นทั้งพิมพ์ได้และอ่านอย่างเดียวได้พร้อมกันหรือไม่?
ใช่. AnnotationFlags เป็นฟิลด์บิต, ดังนั้นให้รวมค่าด้วยการ OR แบบบิต, เช่น AnnotationFlags::Print | AnnotationFlags::ReadOnly.
การลบหมายเหตุจาก AnnotationCollection จะทำให้มันถูกลบออกจากไฟล์ PDF บนดิสก์หรือไม่?
เฉพาะหลังจาก Document::Save() ทำงานแล้ว Delete(), Remove() และ Clear() จะปรับเปลี่ยนคอลเลกชันในหน่วยความจำเท่านั้น — PDF บนดิสก์จะไม่เปลี่ยนแปจนกว่าจะบันทึกเอกสาร.