مدیریت اسناد
مدیریت اسناد
کلاس Document نقطه ورودی تقریباً تمام عملیاتها در Aspose.PDF FOSS برای Python است: ایجاد یک PDF جدید، بارگذاری یک PDF موجود، ویرایش صفحات آن و نوشتن نتیجه به فایل. این راهنما چرخه حیات سند، عملیاتهای مجموعه صفحات، بهینهسازی، جریانهای کاری چندفایلی، رمزنگاری و استثناهایی که باید انتظار پردازش آنها را داشته باشید را مرور میکند.
چرخه حیات سند: ایجاد، باز کردن، و ذخیره
Document() بدون آرگومان یک سند خالی در حافظه ایجاد میکند. به عنوان اولین آرگومان مسیر فایل، bytes خام، یا هر جریان باینری قابل خواندن را پاس کنید (یا بهطور صریح load_from() را فراخوانی کنید) تا بهجای آن یک PDF موجود را بارگذاری کنید. save() یک مسیر یا یک جریان باینری قابل نوشتن مانند io.BytesIO را میپذیرد.
from aspose_pdf import Document
# Create a new, empty document and add a blank page
doc = Document()
doc.pages.add()
doc.save("hello.pdf")
# Re-open it — a path, bytes, or a binary stream all work
reopened = Document("hello.pdf")
print(reopened.page_count) # 1
# ...or load explicitly onto an existing instance
another = Document()
another.load_from("hello.pdf")
reopened.close()
another.dispose()
doc.dispose()save() اگر مسیر مقصد از پیش وجود داشته باشد، FileExistsError را ایجاد میکند، مگر اینکه overwrite=True را پاس کنید. close() یک نام مستعار برای dispose() است؛ هر دو ایدمپوتنت هستند، بنابراین فراخوانی آنها بیش از یکبار ایمن است.
فقط PDF بهعنوان هدف ذخیره پیادهسازی شده است — این بخش اصلی کتابخانه و یک عملکرد کاملاً کارا است. ارسال یک مقدار خروجی مانند SaveFormat.PPTX یا DocFormat.HTML به save() باعث ایجاد UnsupportedFeatureException میشود بهجای نوشتن فایلی با نام نادرست، بنابراین یک خروجی ناموفق همیشه بهصورت واضح (خطا) اعلام میشود نه بهصورت ساکت.
مدیریت مجموعه صفحات
doc.pages یک PageCollection است. از len()، تکرار و ایندکسگذاری صفر-پایه (doc.pages[0]) پشتیبانی میکند، به علاوه add()، insert(index, page) و delete(index) برای ویرایشهای ساختاری. هر Page، index، rect (یعنی MediaBox) و rotation را نمایش میدهد.
from aspose_pdf import Document
doc = Document()
doc.pages.add() # page 0
doc.pages.add() # page 1
doc.pages.insert(1, None) # insert a blank page at index 1
print(doc.page_count) # 3
first_page = doc.pages[0]
print(first_page.rect) # (0, 0, 612, 792)
for page in doc.pages:
print(page.index, page.rotation)
doc.pages.delete(1) # remove the page we inserted
doc.save("pages_demo.pdf", overwrite=True)pages.add(page=None) یک صفحه خالی اضافه میکند وقتی بدون آرگومان فراخوانی شود. pages.insert() ایندکس خارج از بازه را به نزدیکترین موقعیت معتبر محدود میکند به جای اینکه خطا بدهد.
بهینهسازی و فشردهسازی اسناد
Document.optimize در یک فراخوانی حذف تکرار تصویر/جریان، جمعآوری زباله اشیاء استفادهنشده و فشردهسازی جریان را اجرا میکند. برای کنترل تکنیکهای اجرا شده یک نمونه OptimizationOptions پاس دهید؛ اگر آن را حذف کنید از پروفایل پاکسازی استاندارد استفاده میشود.
from aspose_pdf import Document, OptimizationOptions
doc = Document("large_report.pdf")
options = OptimizationOptions()
options.remove_unused_objects = True
options.link_duplicate_streams = True
options.image_compression_quality = 60
options.subset_fonts = True
doc.optimize(options)
doc.save("large_report_optimized.pdf", overwrite=True)optimize_resources() یک نام مستعار برای optimize() است. اگر فقط فشردهسازی جریان را بدون عبور پاکسازی ساختاری میخواهید، مستقیماً doc.compress_streams() را صدا بزنید.
ادغام، تقسیم و ویرایش فایلها
برای اسنادی که از قبل باز دارید، Document.merge() نمونههای دیگر Document را به نمونهٔ فعلی اضافه میکند:
from aspose_pdf import Document
base = Document("part1.pdf")
extra = Document("part2.pdf")
base.merge(extra)
base.save("combined.pdf", overwrite=True)برای جریانهای کاری فایل-به-فایل بدون اینکه خودتان یک Document باز کنید، افزونههای کمکد Merger و Splitter یک شیء MergeOptions/SplitOptions که از ورودیها و خروجیهای FileDataSource ساخته شده است، میگیرند:
from aspose_pdf import Merger, MergeOptions, Splitter, SplitOptions, FileDataSource
# Merge two files into one
merge_options = MergeOptions()
merge_options.add_input(FileDataSource("part1.pdf"))
merge_options.add_input(FileDataSource("part2.pdf"))
merge_options.add_output(FileDataSource("combined.pdf"))
Merger().process(merge_options)
# Split the result into one file per page
split_options = SplitOptions()
split_options.add_input(FileDataSource("combined.pdf"))
split_options.add_output(FileDataSource("combined_page1.pdf"))
split_options.add_output(FileDataSource("combined_page2.pdf"))
Splitter().process(split_options)PdfFileEditor همان مجموعهای از عملیات را به عنوان یک واسط ارائه میدهد که به جای پرتاب استثنا، True/False را برمیگرداند، که برای اسکریپتهای دستهای مناسب است:
from aspose_pdf import PdfFileEditor
with PdfFileEditor() as editor:
ok = editor.concatenate(["part1.pdf", "part2.pdf"], "combined.pdf")
if not ok:
print("concatenate failed:", editor.last_exception)
editor.extract("combined.pdf", "first_page_only.pdf", page_from=1, page_to=1)PdfFileEditor.extract() and .insert() take مبتنی بر ۱ شمارههای صفحه، برخلاف PageCollectionشاخص صفر پایه — ببینید مشکلات رایج در زیر.
رمزنگاری و امنیت سند
Document.encrypt(user_password, owner_password=None, permissions=-4) سند در-حافظه را رمزنگاری میکند؛ decrypt(password) و change_passwords(old, new_user, new_owner=None) رمزها را معکوس یا چرخش میدهند. is_encrypted و permissions وضعیت فعلی را گزارش میدهند.
from aspose_pdf import Document
from aspose_pdf.exceptions import PdfSecurityException
doc = Document()
doc.pages.add()
doc.encrypt("user-pass", "owner-pass", permissions=-4)
doc.save("secured.pdf", overwrite=True)
try:
Document("secured.pdf", password="wrong-pass")
except PdfSecurityException as exc:
print("could not open:", exc)
reopened = Document("secured.pdf", password="user-pass")
print(reopened.is_encrypted) # True
reopened.decrypt("user-pass")
reopened.save("unsecured.pdf", overwrite=True)باز کردن یک سند رمزنگاریشده بدون رمز عبور، یا با رمز نادرست، PdfSecurityException را پرتاب میکند — به جای فرض اینکه بارگذاری همیشه موفق باشد، این کلاس (از aspose_pdf.exceptions) را دریافت کنید.
متادیتا، اعتبارسنجی و مدیریت استثنا
متادیتای سند در doc.info قرار دارد (یک dict[str, str] ساده)، و doc.version / doc.id نسخهٔ سرآیند PDF و شناسهٔ فایل تریلر را نشان میدهند. validate() (که به عنوان check() شناخته میشود) یکپارچگی ساختاری را گزارش میکند؛ repair() سعی میکند مشکلات رایجی مانند فهرست صفحات گمشده یا MediaBox خارج از محدوده را برطرف کند.
from aspose_pdf import Document, PdfLoadLimits
from aspose_pdf.exceptions import AsposePdfException, PdfIOException
doc = Document()
doc.pages.add()
doc.info["Title"] = "Quarterly Report"
doc.info["Author"] = "Reporting Bot"
doc.save("report.pdf", overwrite=True)
# Load untrusted input under an explicit resource-limit policy
safe_limits = PdfLoadLimits(max_input_bytes=50 * 1024 * 1024, max_pages=1000)
try:
untrusted = Document("incoming.pdf", limits=safe_limits)
if not untrusted.validate():
untrusted.repair()
except (AsposePdfException, PdfIOException) as exc:
print("failed to process incoming.pdf:", exc)PdfLoadLimits حافظه و تعداد اشیا را برای فایلهای غیرقابل اعتماد محدود میکند؛ برای غیرفعالسازی تمام محدودیتها وقتی منبع را کاملاً اعتماد دارید، PdfLoadLimits.unlimited() را فراخوانی کنید. AsposePdfException کلاس پایه برای کل سلسلهمراتب استثناها است (از جمله PdfIOException و PdfSecurityException)، بنابراین یک except AsposePdfException واحد هر خطای ایجادشده توسط کتابخانه را میگیرد.
نکات و بهترین شیوهها
- همواره
dispose()(یاclose()) را بر رویDocumentفراخوانی کنید زمانی که کارتان با آن تمام شد، یا آن را بهعنوان یک متغیر محلی کوتاهمدت استفاده کنید — موتور محتوای صفحه و تصاویر رمزگشاییشده را تا زمان حذف در حافظه نگه میدارد. - هنگام بازنویسی مسیری که قبلاً در همان اجرا ایجاد کردهاید،
overwrite=Trueرا بهsave()بدهید؛ مقدار پیشفرضFalseاست وFileExistsErrorرا برمیانگیزد. - قبل از انتشار یک PDF تولیدشده، از
doc.optimize()استفاده کنید — این یک فراخوانی تکبار است که اشیای استفادهنشده را حذف میکند و جریانها را فشرده میسازد و معمولاً اندازه خروجی را بهطور قابلمشاهدهای کاهش میدهد. - همیشه بهصورت صریح یک سیاست
PdfLoadLimitsتنظیم کنید هر زمان که PDFها را از منبعی غیرقابل اعتماد (بارگذاریها، پیوستهای ایمیل، استخراجهای وب) بارگذاری میکنید؛ مقادیر پیشفرض بخشنده اما محدود هستند و مرز امنیتی نیستند که بهصورت کورکورانه به آن اعتماد کنید. - بهجای
Exceptionخالص،AsposePdfException(یا یک زیرکلاس خاص مانندPdfSecurityException) را در اطراف فراخوانیهای بارگذاری/ذخیرهسازی بگیرید — این پایهٔ مشترک برای تمام خطاهایی است که کتابخانه برمیانگیزد.
مشکلات رایج
| مشکل | دلیل | رفع |
|---|---|---|
FileExistsError روی save() | مسیر مقصد از پیش موجود است و overwrite در مقدار پیشفرض False باقی مانده است | ارسال save(path, overwrite=True) |
UnsupportedFeatureException روی save() | یک save_format غیر PDF (به عنوان مثال SaveFormat.PPTX، DocFormat.HTML) درخواست شد | ذخیره بهعنوان PDF — هر مقدار دیگر SaveFormat/DocFormat باعث ایجاد UnsupportedFeatureException میشود بهجای نوشتن خروجی |
PdfSecurityException: Password required for encrypted document | PDF رمزگذاریشده بدون آرگومان password باز شد | مقدار Document(path, password="...") را ارسال کنید یا load_from(path, password="...") را فراخوانی کنید |
اختلاف یک عدد صفحه بین PageCollection و PdfFileEditor | doc.pages[i] مبتنی بر صفر است؛ آرگومانهای صفحه PdfFileEditor.extract()/.insert() مبتنی بر یک هستند | هنگام تبدیل بین دو API، ۱ را اضافه یا کم کنید |
IndexError: Page index out of range. از pages.delete() | نمایه ارسالشده به delete() در مجموعه وجود ندارد | قبل از حذف، doc.page_count (یا len(doc.pages)) را بررسی کنید |
FAQ
آیا برای استفاده از Aspose.PDF FOSS برای Python به مجوز نیاز دارم؟
خیر. این نسخه متن باز (دارای مجوز MIT) است؛ هیچ فایل مجوز یا مرحلهٔ فعالسازی برای پیکربندی وجود ندارد.
آیا میتوانم یک Document را به فرمتهای دیگری غیر از PDF صادر کنم؟
در این نسخه امکانپذیر نیست. save() فقط خروجی PDF را پیادهسازی میکند — ارسال مقدار دیگری از نوع SaveFormat/DocFormat منجر به بروز UnsupportedFeatureException میشود و فایل اشتباهبرچسبگذاریشدهای تولید نمیکند.
تفاوت بین Document.merge() و افزونهٔ Merger چیست؟
Document.merge() نمونههای Document را که قبلاً در حافظه باز کردهاید ترکیب میکند. Merger (با MergeOptions و FileDataSource) یک بستهٔ راحتی فایل-به-فایل است که در یک فراخوانی برای شما باز میکند، ترکیب میکند و ذخیره میکند — برای اسکریپتهای سادهٔ دستهای که هرگز به شیء میانی Document نیاز ندارند، مفید است.
چرا pages.insert() هرگز برای اندیسی خارج از محدوده خطا نمیدهد؟
PageCollection.insert() اندیس را به محدودهٔ معتبر محدود میکند (مقدارهای منفی به 0 تبدیل میشوند، مقادیر بیش از انتها به len(doc.pages)) بهجای اینکه خطا بدهد، بنابراین درج بهخاطر مقدار اندیس بهتنهایی هرگز شکست نمیخورد.
چگونه میتوانم یک PDF را بهصورت ایمن از منبع غیرقابل اعتماد بارگذاری کنم؟
یک PdfLoadLimits را با محدودیتهای صریح (max_input_bytes، max_pages، max_objects و غیره) بسازید و آن را بهعنوان آرگومان limits= به Document(...) یا load_from() پاس دهید. هر فیلد بهطور پیشفرض مقدار محدودی دارد، اما محدود کردن آنها به اندازه ورودی مورد انتظار، منابع مصرفی یک فایل خرابشده را کاهش میدهد.
خلاصه API Reference
| کلاس / متد | توضیح |
|---|---|
Document() / Document.load_from | یک سند خالی ایجاد کنید یا آن را از مسیر، بایتها یا یک جریان باینری بارگذاری کنید |
Document.save | سند را در یک مسیر یا جریان قابل نوشتن بنویسید (فقط PDF) |
Document.dispose() / Document.close() | منابع موتور را آزاد کنید؛ بدون اثر تکراری |
Document.pages | PageCollection سند |
Document.info | متادیتای سند به عنوان یک dict[str, str] |
Document.optimize / Document.optimize_resources / Document.compress_streams() | حذف منابع استفادهنشده و فشردهسازی جریانها |
Document.merge() | نمونههای دیگر Document را به این مورد اضافه کنید |
Document.encrypt / Document.decrypt / Document.change_passwords | اعمال، حذف یا چرخاندن گذرواژههای سند |
Document.validate() / Document.check() / Document.repair() | بررسی و تلاش برای رفع یکپارچگی ساختاری |
PageCollection.add() / .insert() / .delete() / .item() | ویرایشهای ساختاری مجموعه صفحات (صفر مبنا) |
Page.rect / Page.rotation / Page.index | هندسه و موقعیت هر صفحه |
OptimizationOptions | پرچمهای دقیقالگویی که توسط Document.optimize مصرف میشوند |
MergeOptions / Merger | افزونهٔ ادغام فایل-به-فایل |
SplitOptions / Splitter | افزونهٔ تقسیم فایل-به-فایل یک-صفحه-در-هر-خروجی |
FileDataSource | ورودی/خروجی مبتنی بر فایل برای APIهای افزونه |
PdfFileEditor | رابط جلویی برای concatenate()، extract()، insert()، delete()، append() (صفحات با شمارهگذاری از ۱) |
PdfLoadLimits | سیاست محدودیت منابع غیرقابل تغییر برای ورودیهای نامطمئن |
AsposePdfException | کلاس پایه برای هر استثنایی که کتابخانه برمیانگیزد |
PdfSecurityException | در صورت عدم وجود یا نادرست بودن رمز عبور و خطاهای دسترسی برانگیخته میشود |
PdfIOException | در صورت بروز خطاهای ورودی/خروجی هنگام پردازش PDF برانگیخته میشود |
همچنین ببینید:
- API Reference: مستندات کامل کلاس و متد برای
aspose_pdf - پایگاه دانش: راهنمای گامبهگام مبتنی بر وظیفه
- نمای کلی محصول: خلاصه ویژگیها و قابلیتها
- شروع کار / نصب: نصب و راهاندازی
- Aspose.PDF for Python — Enterprise Documentation