كيفية العمل مع التعليقات التوضيحية في TypeScript
يوضح هذا الدليل كيفية إضافة، تسطيح، والبحث في تعليقات PDF باستخدام Aspose.PDF FOSS لـ TypeScript. تُظهر فئة Page طريقة Add* واحدة لكل نوع فرعي من التعليقات التوضيحية — العلامات (تمييز، تسطير، شطب، خط متموج)، الأشكال (مربع، دائرة، خط، مضلع، حبر)، النص (ملاحظة لاصقة، نص حر)، والروابط — كل منها يُعيد مقبض Annotation مُصنف يمكن قراءته لاحقًا أو تسطيحه. يتطلب Node.js 22 أو أحدث.
دليل خطوة بخطوة
الخطوة 1: تثبيت الحزمة
git clone https://github.com/aspose-pdf-foss/Aspose.PDF-FOSS-for-TypeScript.git
cd Aspose.PDF-FOSS-for-TypeScript
npm install
npm run buildتحقق من التثبيت عن طريق استيراد فئة Document في ملف TypeScript جديد — يجب أن يتم حل هذا السطر دون خطأ بمجرد تثبيت الحزمة:
import { Document } from '@asposefoss/pdf';الخطوة 2: استيراد الفئات المطلوبة
استورد Document لفتح الملف وPage لتوقيعات نوع التعليقات التوضيحية المستخدمة في الخطوات أدناه:
import { Document, Page } from '@asposefoss/pdf';الخطوة 3: إضافة تعليقات توضيحية للترميز
Page.AddHighlight()، Page.AddUnderline()، Page.AddSquiggly()، وPage.AddStrikeOut() جميعها تستقبل مصفوفة quads — رباعية مكوّنة من 8 أرقام (x1,y1,x2,y2,x3,y3,x4,y4) لكل منطقة نصية مميزة — بالإضافة إلى color وcontents اختياريين. تقوم المكتبة بإنشاء تدفق المظهر (/AP) لجميع الأنواع الفرعية الأربعة تلقائيًا:
import { Document } from '@asposefoss/pdf';
const doc = Document.OpenFile('input.pdf');
const page = doc.Pages[0];
page.AddHighlight({
quads: [72, 700, 300, 700, 72, 685, 300, 685],
color: [1, 1, 0],
contents: 'Yellow highlight',
});
page.AddUnderline({
quads: [72, 660, 300, 660, 72, 645, 300, 645],
color: [0, 0, 1],
});
page.AddStrikeOut({
quads: [72, 620, 300, 620, 72, 605, 300, 605],
color: [1, 0, 0],
});
doc.WriteTo('annotated.pdf');الخطوة 4: إضافة تعليقات توضيحية للأشكال والحبر
Page.AddSquare() وPage.AddCircle() تستقبلان rect محيطًا بالإضافة إلى color (الخط) وfill اختياري. Page.AddLine() تستقبل line مكوّن من 4 أرقام (x1,y1,x2,y2) ونهايات سهمية اختيارية. Page.AddInk() تستقبل paths — مصفوفة من مصفوفات أزواج نقاط مسطحة، واحدة لكل ضربة قلم:
page.AddSquare({ rect: [100, 500, 220, 560], color: [0.8, 0, 0], fill: [1, 1, 0.5], width: 2 });
page.AddCircle({ rect: [250, 500, 370, 560], color: [0, 0.5, 0], width: 2 });
page.AddLine({
line: [100, 470, 370, 470],
color: [0, 0, 0.7],
width: 2,
startEnding: 'OpenArrow',
endEnding: 'ClosedArrow',
});
page.AddInk({
paths: [[100, 400, 130, 430, 160, 390, 190, 420]],
color: [0.6, 0, 0.6],
width: 2,
});الخطوة 5: إضافة ملاحظة لاصقة ونص حر
Page.AddTextNote() يضع أيقونة قابلة للنقر تفتح نافذة منبثقة للتعليق. Page.AddFreeText() يرسم النص مباشرة على الصفحة داخل rect الخاصة به:
page.AddTextNote({
rect: [400, 700, 420, 720],
icon: 'Note',
author: 'Reviewer',
contents: 'This is a sticky-note annotation.',
});
page.AddFreeText({
rect: [400, 600, 550, 660],
contents: 'FreeText sample',
fontSize: 10,
align: 'center',
fill: [1, 1, 0.8],
width: 1,
});الخطوة 6: تسطيح تعليق توضيحي إلى محتوى ثابت
كل مقبض تعليقة يتم إرجاعه بواسطة استدعاء Add* يحتوي على طريقة Flatten() التي تُدمج مظهر التعليقة في تدفق محتوى الصفحة وتزيله من /Annots. بعد التسطيح لا يبقى شيء يمكن النقر عليه أو تحريره في العارض:
const note = page.AddFreeText({
rect: [210, 535, 470, 590],
contents: 'Sticky note — flattened into the page.',
fontSize: 11,
align: 'left',
});
note.Flatten(); // -> boolean; bakes the annotation, unwires itself from /Annots
الخطوة 7: البحث عن نص التعليقة
Page.SearchAnnotationText() and Page.SearchAnnotations() متباعدة في كلا الاتجاهين: SearchAnnotationText() يطابق بيانات تعريف التعليق الحرفية (/Contents, /T, /Subj), بينما SearchAnnotations() يطابق الـ rendered نص تعليقات التنسيق مثل FreeText:
const metadataHits = page.SearchAnnotationText('confidential');
for (const hit of metadataHits) {
console.log(hit.key, hit.value); // e.g. 'Contents', 'confidential'
}
const renderedHits = page.SearchAnnotations('confidential');
console.log(renderedHits.length);المشكلات الشائعة والحلول
Page.AddHighlight() (أو طريقة تنسيق أخرى) يُرسم في المكان الخطأ. quads هو مصفوفة مسطحة مكوّنة من 8 أرقام (x1,y1,x2,y2,x3,y3,x4,y4), ليس a rect — تمرير مستطيل مكوّن من 4 أرقام ينتج رباعية متدهورة أو مفقودة. أنشئ رباعية واحدة لكل سطر من النص المميز.
التعليق المسطح لا يزال قابلًا للنقر. Flatten() يجب استدعاؤه على الكائن الذي تم إرجاعه من قبل Add* الاستدعاء، ويجب حفظ المستند (doc.WriteTo() / doc.Save()) بعد التسطيح — التغيير موجود فقط في الذاكرة حتى يُكتب الملف مرة أخرى.
SearchAnnotationText() لا يُرجع أي نتائج رغم أن النص مرئي على الصفحة. إنه يبحث فقط في حقول annotation metadata (/Contents, /T, /Subj) — النص المرئي للـ markup text المُنتج من مظهر annotation نفسه (على سبيل المثال FreeText body) يتم العثور عليه بواسطة SearchAnnotations() بدلاً من ذلك، ولا يبحث محتوى الصفحة العادي (استخدم Page.GetText() or Page.Search() من أجل ذلك).
علامات الإزالة لا تظهر عند البحث في التعليقات التوضيحية. Page.AddRedact() ينشئ RedactAnnotation, نوع فرعي مميز عن تعليقات العلامات/الأشكال/النص التي تم تغطيتها هنا — انظر ال Redaction الدليل.
الأسئلة المتكررة
كم عدد الأنواع الفرعية للتعليقات التوضيحية التي يدعمها Page؟
المكتبة تُنشئ مظهرًا للعلامات (highlight, underline, strikeout, squiggly)، الأشكال (square, circle, line, polygon, ink)، النص (sticky note, free text)، الروابط، والطوابع — بالإضافة إلى تعليقات مرفق الملف والحجب، التي يتم تغطيتها في أدلة “كيف تفعل” الخاصة بها.
هل يمكنني قراءة التعليقات التوضيحية الموجودة بالفعل على صفحة؟
نعم — Page.Annotations تُعيد التعليقات التوضيحية الموجودة كمصفوفة من المقابض ذات النوع التي يمكنك فحصها أو تعديلها أو تسويتها، وPage.RemoveAnnotation(a) يزيل واحدة.
ما الفرق بين تسوية تعليق توضيحي وتطبيق حجب؟
Flatten() يدمج تعليقًا appearance في الصفحة ويزيل كائن التعليق، لكن أي نص أو محتوى صورة تحته يظل دون تغيير. ApplyRedactions() يعيد كتابة تدفق المحتوى بشكل مدمر بحيث يختفي المحتوى المغطى نفسه — انظر دليل الإزالة للحصول على التفاصيل.
هل يتم الحفاظ على التعليقات التوضيحية عبر عملية حفظ/فتح متتابعة؟
نعم — يتم كتابة التعليقات التوضيحية المضافة قبل doc.WriteTo() / doc.Save() في ملف PDF وتُقرأ بشكل صحيح في الـ Document.Open() / Document.OpenFile() التالي.