איך לעבוד עם הערות PDF ב-C++

איך לעבוד עם הערות PDF ב-C++

Aspose.PDF FOSS for C++ מייצגת כל הערת PDF (Annotation) כתת-מחלקה של מחלקת הבסיס המשותפת Annotation, וחושפת את ההערות בעמוד דרך AnnotationCollection המוחזר מ-Page::Annotations(). מדריך זה מוסיף לעמוד הערת טקסט פשוטה והערה מעוצבת באמצעות TextAnnotation, שומר את המסמך, פותח אותו מחדש כדי לקרוא את ההערות ולהסיר אחת מהן. ניתן להתקין את הספרייה מ-NuGet (Aspose.PDF.Cpp.FOSS) ב-Visual Studio, או לשלב אותה בפרויקט 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 על הדיסק נשאר ללא שינוי עד שהמסמך נשמר.

ראה גם

 עברית