چگونه با حاشیهنویسیهای PDF در Python کار کنیم
Aspose.PDF FOSS برای Python هر حاشیهنویسی را در صفحه به عنوان یک شیء Annotation زنده از طریق AnnotationCollection صفحه نمایان میکند، بنابراین میتوانید حاشیهنویسیهای علامتگذاری، پیوند و سهبعدی اضافه کنید، ویژگیهای نوع-خاصشان را بررسی کنید و جریانهای ظاهر را که نمایشگرهای PDF برای رندر کردن آنها نیاز دارند، تولید کنید — همه اینها فقط با Python خالص. این راهنما نشان میدهد چگونه کتابخانه را نصب کنید، حاشیهنویسیها را اضافه کنید، آنها را بخوانید و جریانهای ظاهرشان را تولید کنید.
راهنمای گام به گام
گام 1: نصب بسته
پکیج متنباز Aspose.PDF را نصب کنید:
git clone https://github.com/aspose-pdf-foss/Aspose-PDF-FOSS-for-Python.git
cd Aspose-PDF-FOSS-for-Python
pip install -e .نصب را با وارد کردن ماژول سطح بالای aspose_pdf تأیید کنید، که کلاس Document را که در گامهای زیر استفاده میشود، در دسترس قرار میدهد. این قطعه کد هنگام موفقیتآمیز بودن وارد کردن، aspose_pdf OK را چاپ میکند؛ یک ModuleNotFoundError معمولاً به این معنی است که بسته در محیط Python متفاوتی نسبت به محیطی که اسکریپت شما در آن اجرا میشود، نصب شده است.
import aspose_pdf
print("aspose_pdf OK")مرحله ۲: وارد کردن کلاسهای مورد نیاز
کلاس Document را برای نگهداری PDF وارد کنید، بهعلاوه کلاسهای حاشیهنویسی که برای ایجاد و بررسی حاشیهنویسیها استفاده خواهید کرد:
from aspose_pdf import Document
from aspose_pdf.annotations import (
Annotation,
AnnotationType,
AnnotationFlags,
MarkupAnnotation,
LinkAnnotation,
)مرحله ۳: افزودن یک حاشیهنویسی به یک صفحه
هر Page حاشیهنویسیهای خود را از طریق ویژگی annotations، که یک AnnotationCollection است، در دسترس میگذارد. با نام زیرنوع، یک مستطیل (left, bottom, right, top) و محتوای متنی حاشیهنویسی، add(subtype, rect, contents) را فراخوانی کنید. زیرنوعهای استاندارد نشانهگذاری مانند "Highlight" به عنوان یک نمونه MarkupAnnotation بازگردانده میشوند:
from aspose_pdf import Document
document = Document()
document.pages.add()
page = document.pages[0]
annotation = page.annotations.add(
"Highlight",
(100, 700, 300, 720),
"Key clause",
)
print(type(annotation).__name__) # MarkupAnnotation
print(annotation.contents) # Key clauseمرحله ۴: ایجاد حاشیهنویسیها از زیرنوعهای Enum
AnnotationType تمام زیرنوعهای استاندارد حاشیهنویسی PDF (PDF 32000-1:2008، جدول ۱۶۹) را فهرست میکند، بنابراین میتوانید بهجای یک رشته خام، یک عضو enum را پاس دهید. دادههای خاص نوع — مانند رئوس یک چندضلعی — در دیکشنری properties قرار میگیرند و با get_property خوانده میشوند:
from aspose_pdf import Document
from aspose_pdf.annotations import AnnotationType
document = Document()
document.pages.add()
page = document.pages[0]
annotation = page.annotations.add(
AnnotationType.POLYGON,
(0, 0, 10, 10),
"",
properties={"Vertices": [0, 0, 10, 0, 5, 10]},
)
print(annotation.subtype) # Polygon
print(annotation.get_property("Vertices")) # [0, 0, 10, 0, 5, 10]مرحله ۵: خواندن و مرور حاشیهنویسیهای موجود
AnnotationCollection قابل تکرار است، بنابراین میتوانید هر حاشیهنویسی که قبلاً بر روی یک صفحه وجود دارد — از جمله آنهایی که از یک PDF موجود بارگذاری شدهاند — را پیمایش کنید و ویژگیهای مشترکی که هر Annotation افشا میکند (subtype، contents، rect، title، author، color) را بخوانید:
from aspose_pdf import Document
document = Document()
document.pages.add()
page = document.pages[0]
page.annotations.add("Text", (50, 50, 70, 70), "First note")
page.annotations.add("Text", (80, 80, 100, 100), "Second note")
for annotation in page.annotations:
print(annotation.subtype, "-", annotation.contents)مرحله 6: تولید جریانهای ظاهر حاشیهنویس
یک حاشیهنویس که بدون appearance_normal صریح ایجاد شده باشد، رندر قابل مشاهدهای (/AP /N) ندارد تا زمانی که یکی تولید شود. با فراخوانی generate_appearance(force) روی یک Annotation واحد، یا generate_appearances(force) روی کل AnnotationCollection میتوانید تمام جریانهای ظاهر گمشده را بهصورت یکجا در صفحه ترکیب کنید:
from aspose_pdf import Document
from aspose_pdf.engine.cos import AnnotationName
document = Document()
document.pages.add()
page = document.pages[0]
stamp = page.annotations.add(
"Stamp",
(100, 100, 260, 150),
"",
properties={"Name": AnnotationName("Approved")},
)
if stamp.generate_appearance():
print(f"Appearance stream: {len(stamp.appearance_normal)} byte(s)")
# Regenerate every missing appearance stream on the page in one call:
count = page.annotations.generate_appearances(force=True)
print(f"Regenerated {count} appearance stream(s)")مرحله 7: تمایز زیرکلاسهای حاشیهنویس
AnnotationCollection.add() بر اساس زیرنوع به یک زیرکلاس خاص ارجاع میدهد: زیرنوعهای سبک علامتگذاری (Highlight, Square, Stamp و مشابه) به صورت MarkupAnnotation برمیگردند، و "Link" به صورت LinkAnnotation برمیگردد. هر دو تمام متدها و خصوصیات را از Annotation به ارث میبرند، بنابراین بررسیهای isinstance به شما امکان میدهند بر پایه نوع حاشیهنویس شاخهبندی کنید بدون اینکه رشتههای subtype را بهصورت مستقیم بررسی کنید:
from aspose_pdf import Document
from aspose_pdf.annotations import LinkAnnotation, MarkupAnnotation
document = Document()
document.pages.add()
page = document.pages[0]
link = page.annotations.add("Link", (50, 750, 200, 770), "")
highlight = page.annotations.add("Highlight", (50, 700, 200, 720), "")
print(isinstance(link, LinkAnnotation)) # True
print(isinstance(highlight, MarkupAnnotation)) # Trueمشکلات رایج و راهحلها
get_property returns None برای ویژگیای که تازه تنظیم کردهام
properties کلیدها دقیق هستند، نامهای فیلد PDF حساس به حروف بزرگ/کوچک ("Vertices", "Name" و مشابه) — یک اشتباه تایپی یا حروف نادرست بهصورت بیصدا نادیده گرفته میشود و خطایی تولید نمیکند. یک آرگومان default را به get_property(name, default) پاس بدهید و هنگام اشکالزدایی یک زیرنوع جدید بهصورت صریح بررسی کنید.
generate_appearance() returns False
نه هر ترکیب زیرنوع و ویژگی میتواند توسط ژنراتور داخلی به یک جریان ظاهر تبدیل شود. قبل از اینکه فرض کنید فراخوانی موفق بوده است، has_appearance را بررسی کنید، و برای زیرنوعهایی که ژنراتور پوشش نمیدهد، یک appearance_normal پیشرندر شده (bytes) را مستقیماً روی add() تأمین کنید.
زیرکلاس حاشیهنگاری غیرمنتظره پس از add()
رشتهٔ زیرنوع (یا عضو AnnotationType) که میفرستید، کلاس بازگشتی را تعیین میکند: زیرنوعهای نشانهگذاری به صورت MarkupAnnotation برمیگردند، "Link" به عنوان LinkAnnotation برمیگردد، و هر زیرنوع شناختهشدهٔ دیگر به صورت پایهٔ Annotation برمیگردد. بهجای فرض کردن رشتهٔ زیرنوع خاص، از isinstance() در مقابل MarkupAnnotation/LinkAnnotation استفاده کنید.
AnnotationFlags به نظر میرسد مقادیر رندرینگ را تغییر نمیدهند
AnnotationFlags (PRINT, HIDDEN, NO_ZOOM, READ_ONLY و مشابه) یک enum استاندارد Python IntFlag برای ترکیب و تفسیر بیتهای رفتار حاشیهنویسی با عملگر | است — این یک نوع مقداری است، نه ویژگیای که Annotation.add() بهصورت خودکار بنویسد. پرچمهای مورد نیاز خود را ترکیب کنید و از طریق همان مکانیزم properties مخصوص نوع که برای دادههای دیگر زیرنوع-خاص استفاده میشود، عبور دهید.
کار با صفحهای که هنوز حاشیهنویسی ندارد
page.annotations همیشه یک AnnotationCollection معتبر (احتمالاً خالی) است — شما هرگز نیازی ندارید قبل از فراخوانی add()، تکرار یا فراخوانی clear()، برای None بررسی کنید.
سوالات متداول
کدام زیرنوعهای حاشیهگذاری توسط Aspose.PDF FOSS برای Python پشتیبانی میشود؟
AnnotationType تمام ۲۵ زیرنوع استاندارد PDF 32000-1:2008 جدول 169 را فهرست میکند، از جمله TEXT، LINK، FREE_TEXT، LINE، SQUARE، CIRCLE، POLYGON، HIGHLIGHT، STAMP، INK، FILE_ATTACHMENT، REDACT و موارد دیگر.
آیا این کتابخانه از حاشیهگذاریهای سهبعدی پشتیبانی میکند؟
بله. PDF3DAnnotation, همراه با PDF3DArtwork, PDF3DContent, PDF3DView, PDF3DLightingScheme, و PDF3DRenderMode, یک سطح حاشیهنگاری PDF 3D حداقل (یک rectangle، embedded artwork، و named views) برای prerelease PDF 3D workflows مدل میکند. See the مرجع PDF3DAnnotation برای مجموعهٔ کامل ویژگیهای آن.
چگونه میتوان یک حاشیهگذاری را از صفحه حذف کرد؟
با فراخوانی page.annotations.delete(index) میتوانید یک حاشیهگذاری را بر اساس موقعیت حذف کنید، یا با page.annotations.clear() همه حاشیهگذاریهای صفحه را حذف کنید.
آیا میتوانم یک حاشیهگذاری را در موقعیت خاصی وارد کنم به جای افزودن به انتها؟
بله — AnnotationCollection.insert(index, subtype, rect, contents, title, appearance_normal, properties) همان آرگومانهای add() را میگیرد، بهعلاوه هدف index.
رنگ حاشیهنویسی چگونه نمایش داده میشود؟
ویژگی color در Annotation (و زیرکلاسهای آن) یک tuple[float, ...] است که تعداد مؤلفههای ورودی /C PDF را مطابقت میدهد (زمانی که رنگ تنظیم نشده باشد خالی است) — نه یک شیء رنگ اختصاصی.