วิธีทำงานกับหมายเหตุ PDF ใน C++

วิธีทำงานกับหมายเหตุ 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 บนดิสก์จะไม่เปลี่ยนแปจนกว่าจะบันทึกเอกสาร.

ดูเพิ่มเติม

 ภาษาไทย