Java pdf arrow annotations – دليل كامل وأفضل الممارسات (2025)

مقدمة

هل واجهت صعوبة في جعل فريقك يركز على أقسام محددة من مستند PDF أثناء المراجعات؟ لست وحدك. سواء كنت تدير وثائق تقنية، عقود قانونية، أو مواصفات مشروع، فإن الإشارة إلى المناطق الدقيقة للنقاش يمكن أن تكون محبطة بدون الأدوات المناسبة.

إليك الحل: تعليقات السهم في PDF باستخدام GroupDocs.Annotation API. هذه الطريقة القوية تتيح لك برمجيًا add arrow to pdf، مما يجعل التعاون سلسًا ومهنيًا. يمكنك الحصول على نسخة تجريبية عبر صفحة الترخيص المؤقتة لـ GroupDocs.

إجابات سريعة

  • ما المكتبة التي تسمح لي بإضافة سهم إلى PDF في Java؟ GroupDocs.Annotation for Java.
  • هل أحتاج إلى ترخيص للإنتاج؟ نعم، الترخيص التجاري يزيل العلامات المائية ويفتح مجموعة الميزات الكاملة. راجع GroupDocs pricing page للتفاصيل.
  • ما إصدار Java الموصى به؟ JDK 11 يقدم أفضل أداء ودعم طويل الأمد.
  • هل يمكنني إضافة عدة أسهم في مستند واحد؟ بالتأكيد – فقط أنشئ عدة كائنات ArrowAnnotation وأضفها إلى نفس Annotator.
  • هل تدعم المعالجة الدفعية؟ نعم، يمكنك التكرار عبر المستندات وإعادة استخدام نفس مثيل Annotator بعد التخلص المناسب منه.

ما هو إضافة سهم إلى PDF؟

عملية add arrow to pdf ترسم علامة اتجاهية على صفحة PDF لتسليط الضوء أو الإشارة إلى منطقة معينة. تُخزن تعليقات السهم ككائنات PDF، لذا تظل مرئية في أي عارض متوافق مع المعايير ويمكن تعديلها أو الرد عليها لاحقًا.

لماذا تختار GroupDocs.Annotation لتعليقات السهم في PDF باستخدام Java؟

يقدم GroupDocs.Annotation مجموعة غنية من أنواع التعليقات، دعمًا على مستوى المؤسسات، وواجهة برمجة تطبيقات Java بسيطة تقلل من الكود المتكرر. مقارنةً بالبدائل، يعالج أكثر من 50 تنسيقًا للمدخلات والمخرجات ويمكنه التعامل مع ملفات PDF تصل إلى 500 صفحة باستخدام أقل من 200 ميغابايت من الذاكرة المؤقتة، بفضل هندسة البث الخاصة به.

المتطلبات المسبقة - ما تحتاجه فعليًا

المكتبات والاعتمادات المطلوبة

أولاً، أضف اعتماد Maven الخاص بـ GroupDocs.Annotation. المقتطف أدناه يعكس الإحداثيات الدقيقة التي تحتاجها؛ استبدل العنصر النائب للإصدار بأحدث إصدار ثابت.

<repositories>
   <repository>
      <id>repository.groupdocs.com</id>
      <name>GroupDocs Repository</name>
      <url>https://releases.groupdocs.com/annotation/java/</url>
   </repository>
</repositories>
<dependencies>
   <dependency>
      <groupId>com.groupdocs</groupId>
      <artifactId>groupdocs-annotation</artifactId>
      <version>25.2</version>
   </dependency>
</dependencies>

نصيحة احترافية: تحقق من صفحة إصدارات GroupDocs للحصول على أحدث رقم إصدار. الإصدارات الجديدة غالبًا ما تتضمن تصحيحات أداء وأنماط تعليقات إضافية.

إعداد البيئة بدون مشاكل

  • JDK 8 أو أحدث – يُنصح بـ JDK 11 لتحسين جامع القمامة ونظام الوحدات.
  • Maven 3.6+ – قد تواجه إصدارات Maven القديمة صعوبة في التعامل مع الاعتمادات المتداخلة.
  • IDE – IntelliJ IDEA أو Eclipse يقدمان أفضل تجربة تصحيح لمكتبات Java.
  • الذاكرة – خصص على الأقل 2 GB من الذاكرة المؤقتة عند العمل مع ملفات PDF أكبر من 100 صفحة.

المتطلبات المعرفية (كن صادقًا مع نفسك)

يجب أن تكون مرتاحًا مع:

  • مجموعات Java الأساسية ومعالجة الاستثناءات.
  • إدارة الاعتمادات في Maven.
  • عمليات الإدخال/الإخراج الأساسية للملفات (قراءة وكتابة تدفقات ثنائية).

إذا شعرت أن أيًا من هذه المجالات ضعيفة، فكر في مراجعة سريعة قبل الغوص في كود التعليقات.

إعداد GroupDocs.Annotation - الطريقة الصحيحة

الخطوة 1: تكوين Maven (مع استكشاف الأخطاء)

أضف المستودع والاعتماد الموضحين سابقًا. إذا فشل Maven في حل العنصر، تأكد من تعريف مستودع GroupDocs العام في ملف pom.xml الخاص بك:

<properties>
    <maven.compiler.source>11</maven.compiler.source>
    <maven.compiler.target>11</maven.compiler.target>
</properties>

الخطوة 2: إعداد الترخيص (ضروري للإنتاج)

للتطوير يمكنك استخدام ترخيص تجريبي مؤقت:

// For evaluation purposes
License license = new License();
// license.setLicense("path/to/license.lic"); // Comment this out for trial

تحقق من الواقع: الترخيص التجريبي يضيف علامة مائية مرئية إلى كل PDF محفوظ. الترخيص الإنتاجي يزيل هذه العلامة المائية ويفتح مجموعة الميزات الكاملة للتعليقات.

الخطوة 3: نمط التهيئة الأساسي

Annotator هو الفئة الأساسية لتحميل مستند PDF وتطبيق التعليقات.
دائمًا احيط Annotator بكتلة try‑finally حتى يتم تحرير الموارد الأساسية على الفور:

Annotator annotator = null;
try {
    annotator = new Annotator("YOUR_DOCUMENT_DIRECTORY/input.pdf");
    // Your annotation code here
} finally {
    if (annotator != null) {
        annotator.dispose();
    }
}

لماذا كتلة try‑finally؟ تقوم GroupDocs بحجز ذاكرة أصلية لتحليل PDF؛ عدم التخلص من Annotator قد يؤدي إلى تسرب الذاكرة، خاصةً عند معالجة العديد من المستندات في وظيفة دفعية.

دليل التنفيذ الكامل - من الصفر إلى الإنتاج

فهم تعليقات السهم في السياق

تعمل تعليقات السهم كإشارات بصرية في سير عمل مراجعة المستندات. تشمل حالات الاستخدام النموذجية:

  1. ملاحظات المراجعة – “هذا البند يحتاج إلى توضيح.”
  2. ربط المراجع – “انظر المخطط في الصفحة 12.”
  3. إرشاد العملية – “ابدأ التدقيق من هنا.”
  4. تمييز المشكلة – “خطأ إملائي محتمل في هذه الفقرة.”

تصميم واجهة المستخدم للتعليقات حول هذه السيناريوهات يساعد المستخدمين على تبني الأداة بسرعة أكبر.

الخطوة 1: بناء ردود التعليقات (الطريقة الذكية)

تحول الردود السهم الثابت إلى نقطة نقاش تفاعلية. في المرة الأولى التي تذكر فيها فئة Reply، عرّفها باختصار:

مرساة التعريف: Reply تمثل تعليقًا نصيًا مرفقًا بتعليق، تخزن معلومات المؤلف والطابع الزمني.

Reply reply1 = new Reply();
reply1.setComment("First comment");
reply1.setRepliedOn(Calendar.getInstance().getTime());

Reply reply2 = new Reply();
reply2.setComment("Second comment");
reply2.setRepliedOn(Calendar.getInstance().getTime());

List<Reply> replies = new ArrayList<>();
replies.add(reply1);
replies.add(reply2);

نصيحة احترافية: احفظ معرف المستخدم والدور في بيانات التعليق؛ هذا يسهل تصفية التعليقات لاحقًا.

الخطوة 2: إنشاء تعليقات السهم (مع اعتبارات واقعية)

مرساة التعريف: ArrowAnnotation هو كائن GroupDocs الذي يرسم سهمًا اتجاهيًا على صفحة PDF.

ArrowAnnotation arrow = new ArrowAnnotation();
arrow.setBox(new Rectangle(100, 100, 100, 100)); // Position and size
arrow.setCreatedOn(Calendar.getInstance().getTime()); // Creation time
arrow.setMessage("This is an arrow annotation"); // Annotation message
arrow.setOpacity(0.7); // Opacity level
arrow.setPageNumber(0); // Page number
arrow.setPenColor(65535); // ARGB pen color
arrow.setPenStyle(PenStyle.DOT); // Pen style
arrow.setPenWidth((byte) 3); // Arrow line width
arrow.setReplies(replies); // Attach replies

معلمات المفتاح المشروحة:

  • إحداثيات المستطيل – (x, y, width, height) حيث (x, y) هو الزاوية العليا اليسرى للمستطيل المحيط.
  • PenColor – يستخدم عدد صحيح ARGB؛ 65535 ينتج لونًا أزرقًا زاهيًا. استخدم محولًا عبر الإنترنت للألوان المخصصة.
  • PenStyle – الخيارات تشمل DOT, DASH, SOLID, DASHDOT, DASHDOTDOT. اختر SOLID لمعظم الحالات.
  • Opacity – يتراوح بين 0.0 (شفاف) إلى 1.0 (معتم). القيمة 0.7 توازن بين الوضوح وقراءة المحتوى الأساسي.

الخطوة 3: الإضافة والحفظ (مع معالجة الأخطاء)

مرساة التعريف: Annotator.save يحفظ جميع تغييرات التعليقات المعلقة إلى ملف PDF الهدف.

try {
    annotator.add(arrow);
    annotator.save("YOUR_OUTPUT_DIRECTORY/output.pdf");
    System.out.println("Arrow annotation added successfully!");
} catch (Exception e) {
    System.err.println("Failed to add annotation: " + e.getMessage());
    // Log the full stack trace in production
    e.printStackTrace();
} finally {
    annotator.dispose();
}

دائمًا امسك IOException و AnnotationException لمعالجة الملفات الفاسدة، المسارات غير الصالحة، أو مشاكل الأذونات. تسجيل تتبع الأخطاء يساعدك على تشخيص المشكلات في الإنتاج.

الأخطاء الشائعة وكيفية تجنبها

المشكلة 1: الإحداثيات لا تتطابق مع الموضع المتوقع

المشكلة: يظهر السهم في موضع مختلف عن المطلوب.

الحل: أصل إحداثيات PDF هو الزاوية السفلية اليسرى، بينما تتوقع GroupDocs الزاوية العليا اليسرى. حوّل إحداثيات واجهة المستخدم وفقًا لذلك، أو استخدم المساعد المدمج convertToPdfCoordinates:

// If arrows appear in wrong positions, try adjusting the Y coordinate
int adjustedY = pageHeight - originalY - annotationHeight;
arrow.setBox(new Rectangle(x, adjustedY, width, height));

المشكلة 2: اختفاء التعليقات بعد الحفظ

المشكلة: تظهر الأسهم أثناء المعالجة ولكنها غائبة في PDF النهائي.

الحل: هذا غالبًا ما يشير إلى مشكلة ترخيص. تأكد من تحميل ملف الترخيص قبل إنشاء أي مثيل Annotator:

License license = new License();
try {
    license.setLicense("GroupDocs.Annotation.lic");
} catch (Exception e) {
    System.out.println("License not found, using trial mode");
}

المشكلة 3: تسرب الذاكرة في المعالجة الدفعية

المشكلة: ينفد الـ JVM من الذاكرة عند معالجة عشرات ملفات PDF.

الحل: تخلص من كل Annotator بعد الانتهاء من المستند، وعالج الملفات على دفعات صغيرة للحفاظ على استهلاك الذاكرة متوقعًا:

for (String documentPath : documentPaths) {
    Annotator annotator = null;
    try {
        annotator = new Annotator(documentPath);
        // Process document
    } finally {
        if (annotator != null) {
            annotator.dispose();
        }
    }
    
    // Force garbage collection every 10 documents
    if (processedCount % 10 == 0) {
        System.gc();
    }
}

تقنيات تخصيص متقدمة

تموضع السهم الديناميكي

عند الحاجة إلى أن تتبع الأسهم نقرات المستخدم في واجهة ويب، احسب المستطيل على جانب العميل وأرسل الإحداثيات إلى الخادم. يمكن للخادم بعد ذلك إنشاء ArrowAnnotation بهذه القيم.

public ArrowAnnotation createArrowAt(int x, int y, String message) {
    ArrowAnnotation arrow = new ArrowAnnotation();
    
    // Create arrow pointing to specific coordinates
    int arrowLength = 50;
    arrow.setBox(new Rectangle(x - arrowLength, y - arrowLength, arrowLength, arrowLength));
    arrow.setMessage(message);
    arrow.setOpacity(0.8);
    arrow.setPenColor(0xFF0000); // Red color
    arrow.setPenStyle(PenStyle.SOLID);
    arrow.setPenWidth((byte) 2);
    
    return arrow;
}

تنسيق السهام لحالات الاستخدام المختلفة

يمكنك تغيير PenColor و PenStyle لتوصيل معنى—مثلاً، أسهم حمراء متقطعة للمشكلات الحرجة، وأسهم خضراء صلبة للأقسام المعتمدة.

// Error highlighting (red, thick, solid)
public ArrowAnnotation createErrorArrow() {
    ArrowAnnotation arrow = new ArrowAnnotation();
    arrow.setPenColor(0xFF0000); // Red
    arrow.setPenWidth((byte) 4);
    arrow.setPenStyle(PenStyle.SOLID);
    arrow.setOpacity(0.9);
    return arrow;
}

// Suggestion arrows (blue, thin, dashed)
public ArrowAnnotation createSuggestionArrow() {
    ArrowAnnotation arrow = new ArrowAnnotation();
    arrow.setPenColor(0x0000FF); // Blue
    arrow.setPenWidth((byte) 2);
    arrow.setPenStyle(PenStyle.DASH);
    arrow.setOpacity(0.6);
    return arrow;
}

سيناريوهات تنفيذ واقعية

السيناريو 1: نظام مراجعة المستندات

في بوابة مراجعة متعددة المستخدمين، ينشئ كل مراجع ArrowAnnotation ويضيف Reply. يخزن النظام الردود في قاعدة بيانات علائقية، مما يتيح مناقشة متسلسلة على كل تعليق.

public class DocumentReviewSystem {
    public void addReviewArrow(String documentPath, int x, int y, 
                              String reviewComment, String reviewerName) {
        Annotator annotator = new Annotator(documentPath);
        
        ArrowAnnotation arrow = new ArrowAnnotation();
        arrow.setBox(new Rectangle(x, y, 50, 50));
        arrow.setMessage("Review by " + reviewerName);
        
        // Add reviewer's comment as reply
        Reply review = new Reply();
        review.setComment(reviewComment);
        review.setUser(new User(reviewerName));
        review.setRepliedOn(new Date());
        
        arrow.setReplies(Arrays.asList(review));
        
        annotator.add(arrow);
        annotator.save(documentPath.replace(".pdf", "_reviewed.pdf"));
        annotator.dispose();
    }
}

السيناريو 2: اكتشاف المشكلات تلقائيًا

محرك تحليل يفحص ملفات PDF للانتهاكات ويُدرج أسهم حمراء تلقائيًا تشير إلى البنود الإشكالية.

public void highlightDetectedIssues(String documentPath, List<Issue> issues) {
    Annotator annotator = new Annotator(documentPath);
    
    for (Issue issue : issues) {
        ArrowAnnotation arrow = createArrowForIssue(issue);
        annotator.add(arrow);
    }
    
    annotator.save(documentPath.replace(".pdf", "_issues_highlighted.pdf"));
    annotator.dispose();
}

private ArrowAnnotation createArrowForIssue(Issue issue) {
    ArrowAnnotation arrow = new ArrowAnnotation();
    arrow.setBox(new Rectangle(issue.getX(), issue.getY(), 40, 40));
    arrow.setMessage("Issue detected: " + issue.getType());
    
    // Color‑code by severity
    switch (issue.getSeverity()) {
        case HIGH:
            arrow.setPenColor(0xFF0000); // Red
            break;
        case MEDIUM:
            arrow.setPenColor(0xFFA500); // Orange
            break;
        case LOW:
            arrow.setPenColor(0xFFFF00); // Yellow
            break;
    }
    
    return arrow;
}

نصائح تحسين الأداء

أفضل ممارسات إدارة الذاكرة

  1. استخدم try‑with‑resources (Java 7+) لإغلاق كائنات Annotator تلقائيًا:

try (Annotator annotator = new Annotator(“document.pdf”)) { // Your annotation code } // Automatically disposed


2. **عالج الصفحات بشكل فردي** بدلاً من تحميل المستند بالكامل في الذاكرة.  

3. **راقب استهلاك الذاكرة** باستخدام أدوات مثل VisualVM أو JConsole أثناء تشغيل دفعات كبيرة.

### اعتبارات أداء وحدة المعالجة المركزية

- أعد استخدام كائن `Color` واحد لجميع الأسهم لتجنب إنشاء كائنات غير ضرورية.  
- تجنب الحلقات المتداخلة التي تنشئ كائنات `PenStyle` متماثلة باستمرار.  
- إذا كان لديك العديد من ملفات PDF المستقلة، فكر في استخدام مجموعة خيوط، لكن حدّ عدد مثيلات `Annotator` المتزامنة للحفاظ على استهلاك الذاكرة.

## دليل استكشاف الأخطاء – حلول للمشكلات الحقيقية

### المشكلة: التعليقات غير مرئية في Adobe Reader

**الأعراض**: تظهر الأسهم في عارضك المخصص ولكن ليس في Adobe Acrobat.

**الحلول**:

1. احفظ PDF بتوافق PDF/A‑1b لضمان أقصى توافق مع العارضين:  

   ```java
// Try different save options if available
SaveOptions saveOptions = new SaveOptions();
saveOptions.setAnnotationType(AnnotationType.All);
annotator.save(outputPath, saveOptions);
  1. تأكد من أن نسخة PDF لا تقل عن 1.7؛ الإصدارات الأقدم قد تتجاهل أنواع التعليقات الحديثة.

المشكلة: أداء ضعيف مع ملفات PDF الكبيرة

الأعراض: يتوقف التطبيق أو يصبح غير مستجيب عند معالجة ملفات PDF تزيد عن 200 صفحة.

الحلول:

  1. عالج الصفحات بشكل فردي بدلاً من تحميل الملف بالكامل:

// Process specific pages LoadOptions loadOptions = new LoadOptions(); loadOptions.setLoadCharts(false); // Skip charts if not needed Annotator annotator = new Annotator(documentPath, loadOptions);


2. **فعّل البث** في مُنشئ `Annotator` إذا كان إصدارك يدعم ذلك.  

3. زد حجم الذاكرة المؤقتة للـ JVM (`-Xmx4g`) للوثائق الضخمة جدًا.

### المشكلة: مشاكل في عرض الألوان

**الأعراض**: يظهر السهم باللون الرمادي أو شفاف تمامًا.

**الحل**: عرّف اللون باستخدام صيغة ARGB وتأكد من أن مساحة ألوان PDF مضبوطة على **DeviceRGB**:

```java
// Use hex values for consistent colors
int red = 0xFFFF0000;    // ARGB format
int blue = 0xFF0000FF;
int green = 0xFF00FF00;

// Or convert from RGB
public int rgbToArgb(int r, int g, int b) {
    return (0xFF << 24) | (r << 16) | (g << 8) | b;
}

اختبار تنفيذك

اختبار وحدة لتعليقات السهم

اختبار وحدة قوي يحمل ملف PDF تجريبي، يضيف ArrowAnnotation، يحفظ الملف، ثم يعيد فتحه للتحقق من عدد التعليقات وخصائصها:

@Test
public void testArrowAnnotationCreation() {
    // Arrange
    String inputPath = "test-documents/sample.pdf";
    String outputPath = "test-output/annotated.pdf";
    
    // Act
    Annotator annotator = new Annotator(inputPath);
    ArrowAnnotation arrow = new ArrowAnnotation();
    arrow.setBox(new Rectangle(100, 100, 50, 50));
    arrow.setMessage("Test annotation");
    
    annotator.add(arrow);
    annotator.save(outputPath);
    annotator.dispose();
    
    // Assert
    assertTrue("Output file should exist", new File(outputPath).exists());
    
    // Verify annotation was added
    Annotator verifyAnnotator = new Annotator(outputPath);
    List<AnnotationInfo> annotations = verifyAnnotator.get();
    assertEquals("Should have one annotation", 1, annotations.size());
    verifyAnnotator.dispose();
}

اختبار التكامل

شغّل مجموعة الاختبارات نفسها على ملفات PDF بأحجام مختلفة (10 صفحات، 100 صفحة، 500 صفحة) وعلى عارضات مختلفة (Adobe Reader، Foxit، Chrome) لضمان عرض ثابت.

الخلاصة

الآن لديك مجموعة أدوات كاملة لتنفيذ تعليقات السهم في PDF باستخدام Java وGroupDocs.Annotation. تذكر أن:

  • تتخلص من كائنات Annotator فور الانتهاء.
  • تختبر مع إصدارات PDF وأحجام متنوعة.
  • تطبق نصائح الأداء عند التوسع إلى وظائف دفعية.
  • تنسق الأسهم لتطابق المعنى الدلالي لكل تعليق.

الخطوات التالية: استكشف أنواع تعليقات أخرى مثل TextAnnotation، AreaAnnotation، وWatermarkAnnotation. أنماط التهيئة والتخلص نفسها تنطبق، مما يتيح لك بناء منصة تعاون مستندات متكاملة.

الأسئلة المتكررة

س: هل يمكنني إضافة تعليقات سهم إلى ملفات PDF محمية بكلمة مرور؟
ج: نعم، قدم كلمة المرور عند إنشاء مثيل Annotator:

LoadOptions loadOptions = new LoadOptions();
loadOptions.setPassword("your-password");
Annotator annotator = new Annotator("protected.pdf", loadOptions);

س: كيف يمكنني معالجة عدة مستندات دفعيًا بكفاءة؟
ج: عالج المستندات على دفعات صغيرة، أعد استخدام Annotator واحد لكل ملف، واستدعِ dispose() بعد كل حفظ:

for (String doc : documents) {
    try (Annotator annotator = new Annotator(doc)) {
        // Add annotations
        annotator.save(doc.replace(".pdf", "_annotated.pdf"));
    }
    if (processedCount % 10 == 0) {
        System.gc(); // Encourage garbage collection
    }
}

س: ما هو الحد الأقصى لعدد التعليقات في مستند واحد؟
ج: لا تفرض GroupDocs حدًا ثابتًا، لكن الأداء العملي يتدهور بعد حوالي 1,000 تعليق في PDF من 500 صفحة إذا لم تطبق تقنيات إدارة الذاكرة المذكورة سابقًا.

س: هل يمكنني تخصيص أشكال السهم بخلاف الخيارات القياسية؟
ج: توفر المكتبة رؤوس أسهم قياسية. للحصول على أشكال مخصصة بالكامل يمكنك دمج عدة كائنات AreaAnnotation أو الانتقال إلى مكتبة تركّز على الرسومات وتدعم مسارات المتجهات.

س: كيف أتعامل مع أنظمة إحداثيات PDF المختلفة؟
ج: تقوم GroupDocs تلقائيًا بتحويل إحداثيات UI العليا اليسرى إلى إحداثيات PDF السفلية اليسرى. إذا واجهت اختلافًا، تأكد من أنك لا تطبق طبقة تحويل إضافية على جانب العميل.

// Get page info for coordinate calculations
PageInfo pageInfo = annotator.getDocument().getPages().get(pageNumber);
int pageHeight = pageInfo.getHeight();

// Adjust Y coordinate if needed
int adjustedY = pageHeight - originalY;

س: ما تكلفة الترخيص للإنتاج؟
ج: تقدم GroupDocs تراخيص للمطورين، المواقع، وOEM. تبدأ الأسعار من 699 دولار لكل مقعد مطور سنويًا. زر صفحة أسعار GroupDocs للحصول على أحدث الأرقام.

س: كيف أدمج هذا مع تطبيقات Spring Boot؟
ج: أنشئ Bean @Service ي encapsulates منطق التعليقات، حقّنه في الـ Controllers، ووفّر نقطة نهاية REST تستقبل تدفق PDF وتعيد PDF معلقًا.

@Service
public class AnnotationService {
    public void addArrowAnnotation(String inputPath, String outputPath, 
                                 int x, int y, String message) {
        try (Annotator annotator = new Annotator(inputPath)) {
            ArrowAnnotation arrow = new ArrowAnnotation();
            arrow.setBox(new Rectangle(x, y, 50, 50));
            arrow.setMessage(message);
            
            annotator.add(arrow);
            annotator.save(outputPath);
        }
    }
}

س: هل يمكنني استخراج تعليقات السهم الموجودة من ملفات PDF؟
ج: نعم، استدعِ طريقة getAnnotations() على مثيل Annotator وصّف النتائج حسب AnnotationType.Arrow.

Annotator annotator = new Annotator("document.pdf");
List<AnnotationInfo> annotations = annotator.get();

for (AnnotationInfo annotation : annotations) {
    if (annotation instanceof ArrowAnnotation) {
        ArrowAnnotation arrow = (ArrowAnnotation) annotation;
        System.out.println("Arrow message: " + arrow.getMessage());
    }
}

موارد إضافية

آخر تحديث: 2026-08-14
تم الاختبار مع: GroupDocs.Annotation 25.2 for Java
المؤلف: GroupDocs

public void processBatch(List<String> documents, int batchSize) {
    for (int i = 0; i < documents.size(); i += batchSize) {
        List<String> batch = documents.subList(i, 
            Math.min(i + batchSize, documents.size()));
        
        processBatchInternal(batch);
        
        // Allow GC between batches
        System.gc();
        Thread.sleep(100);
    }
}
Runtime runtime = Runtime.getRuntime();
long memoryBefore = runtime.totalMemory() - runtime.freeMemory();

// Your annotation processing

long memoryAfter = runtime.totalMemory() - runtime.freeMemory();
System.out.println("Memory used: " + (memoryAfter - memoryBefore) + " bytes");
java -Xmx4g -jar your-application.jar

دروس ذات صلة