איך לעבוד עם הערות 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)

ודא שרצף כלי השרשרת ושלב הקישור נפתרים כהלכה עם תוכנית מינימלית:

#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 הוא מבוסס על 0, ו-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) מסיר הערה לפי המיקום שלה שמבוסס על 0. מחק את ההערה הראשונה ושמור את התוצאה לקובץ חדש:

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) מחליף את כל קבוצת הדגלים — הוא לא ממזג עם הערך הקודם. כדי להוסיף או למחוק דגל בודד, קרא תחילה את הדגלים הנוכחיים ושלב אותם עם אופרטורים ביטיים, לדוגמה a.Flags(a.Flags() | AnnotationFlags::Print) כדי להוסיף דגל, או a.Flags(a.Flags() & ~AnnotationFlags::Print) כדי למחוק דגל אחד תוך כדי שהשאר נשארים ללא שינוי.

שאלות נפוצות

מה הקשר בין Annotation, TextAnnotation, ולתתי-סוגי ההערה האחרים?

Annotation היא מחלקת הבסיס המשותפת. TextAnnotation ושאר סוגי ההערה הקונקרטיים ממקמים אותה לכל תת-סוג של הערת PDF, תוך שיתוף של המחלקה הבסיסית את Rect(), Contents(), Color(), Flags() ו-Border().

האם ההערות משויכות לכל המסמך או לעמוד אחד?

לכל עמוד יש את ה-AnnotationCollection שלו, המוחזר על-ידי המתודה Annotations() של אותו עמוד. ההערות תמיד משויכות לעמוד שבו הן נוספו, ולא לכל המסמך כולו.

איך אני סופר כמה הערות יש בעמוד?

קרא ל-Count() על ה-AnnotationCollection שמוחזר על-ידי Page::Annotations().

האם אפשר שההערה תהיה גם ניתנת להדפסה וגם לקריאה- בלבד בו-זמנית?

כן. AnnotationFlags הוא שדה ביטים, ולכן יש לשלב ערכים באמצעות bitwise OR, לדוגמה AnnotationFlags::Print | AnnotationFlags::ReadOnly.

האם מחיקת הערה מ-AnnotationCollection מסירה אותה מקובץ ה-PDF על הדיסק?

רק אחרי שה-Document::Save() רץ. Delete(), Remove() ו-Clear() משנים רק את האוסף בזיכרון — ה-PDF על הדיסק נשאר ללא שינוי עד שהמסמך נשמר.

ראה גם

 עברית