كيفية إنشاء مستندات باستخدام وحدة التوافق المولدة في Python
Aspose.PDF FOSS لـ Python يُصدر حزمة فرعية للتوافق generated (aspose_pdf.generated) التي تعكس مجموعة فرعية مستقرة من السطح الرئيسي لـ API — فئة Document مع عمليات دورة الحياة الأساسية، بالإضافة إلى UnsignedContent/UnsignedContentAbsorber و PdfAValidateOptions/PdfAValidationResult. توجد هذه الحزمة للمتصلين الذين يرغبون في هذا السطح الضيق صراحةً بدلاً من الفئات العليا ذات الميزات الكاملة، ولا يتم استيراد فئاتها تلقائيًا بواسطة import aspose_pdf — بل تستوردها مباشرةً من aspose_pdf.generated.*. الحزمة نقية Python ويتم تثبيتها بالأمر التالي.
دليل خطوة بخطوة
الخطوة 1: تثبيت الحزمة
قم بتثبيت حزمة Aspose.PDF FOSS:
git clone https://github.com/aspose-pdf-foss/Aspose-PDF-FOSS-for-Python.git
cd Aspose-PDF-FOSS-for-Python
pip install -e .تحقق من التثبيت عن طريق استيراد Document المُولَّد وطباعة رسالة تأكيد:
import aspose_pdf
from aspose_pdf.generated.document import Document
print("aspose-pdf-foss-for-python is ready.")الخطوة 2: استيراد الفئات المطلوبة
فئات التوافق generated موجودة في aspose_pdf.generated.document، aspose_pdf.generated.forms، وaspose_pdf.generated.pdfa — استوردها صراحةً عبر الوحدة الفرعية:
import aspose_pdf
from aspose_pdf.generated.document import Document
from aspose_pdf.generated.forms import UnsignedContent, UnsignedContentAbsorber
from aspose_pdf.generated.pdfa import PdfAValidateOptions, PdfAValidationResultالخطوة 3: إنشاء وتحميل مستند
Document(source) يتم تحميله فورًا عند توفير مصدر؛ استدعاء Document() بدون أي وسيط ينشئ نسخة فارغة يمكنك تحميلها لاحقًا باستخدام load_from. كلاهما يقبل مسار ملف، bytes، أو تدفق ثنائي:
from aspose_pdf.generated.document import Document
document = Document("report.pdf")
print(f"Loaded {len(document.pages)} page(s)")
empty_doc = Document()
empty_doc.load_from("report.pdf")الخطوة 7: استخراج محتوى النموذج غير الموقّع
UnsignedContentAbsorber يستخرج الصفحات وحقول النماذج والتعليقات التوضيحية التي لم تكن جزءًا من توقيع رقمي. استدعِ extract() لتشغيل الاستخراج، has_extracted() للتحقق مما إذا كان قد تم تشغيله، وget_extracted() لاسترجاع النتيجة مرة أخرى دون إعادة الاستخراج:
from aspose_pdf.generated.forms import UnsignedContentAbsorber
absorber = UnsignedContentAbsorber()
unsigned = absorber.extract()
print(f"Unsigned pages: {len(unsigned.pages)}")
print(f"Unsigned form fields: {len(unsigned.form_fields)}")
if absorber.has_extracted():
same_result = absorber.get_extracted()الخطوة 8: بناء حاوية UnsignedContent يدويًا
UnsignedContent هي أيضًا حاوية بسيطة يمكنك تعبئتها بنفسك باستخدام add_page، add_form_field، وadd_annotation — لكل منها طريقة remove_* المطابقة، وreset() يمسح جميع المجموعات الثلاث مرة واحدة:
from aspose_pdf.generated.forms import UnsignedContent
content = UnsignedContent()
content.add_page("page-1")
content.add_annotation("signature-placeholder")
print(content) # UnsignedContent(pages=1, form_fields=0, annotations=1)
content.remove_annotation("signature-placeholder")
content.reset()الخطوة 9: تهيئة وتشغيل PDF/A Validation
PdfAValidateOptions يجمع المدخلات والإعدادات لتشغيل التحقق. add_input(source) يسجل مدخلاً، set_option(key, value) يخزن خيارًا مسمى، وget_options() يُعيد نسخة من الخيارات المخزنة. PdfAValidationResult يحتوي على النتيجة — add_error(message) يعلِّم النتيجة بأنها غير صالحة ويضيف إلى errors، وto_dict() يُظهر is_valid وerrors كقاموس عادي:
from aspose_pdf.generated.pdfa import PdfAValidateOptions, PdfAValidationResult
options = PdfAValidateOptions()
options.add_input("report.pdf")
options.set_option("pdfa_version", "1b")
print(options.get_options())
result = PdfAValidationResult()
result.add_error("Font 'Arial' is not embedded")
print(result.is_valid) # False
print(result.to_dict())المشكلات الشائعة والحلول
ImportError or AttributeError عند الوصول aspose_pdf.generated
الحزمة الفرعية generated غير مُعاد تصديرها بواسطة import aspose_pdf — استورد كل فئة من الوحدة الفرعية المحددة لها، على سبيل المثال from aspose_pdf.generated.document import Document، بدلاً من توقع أن يعمل aspose_pdf.generated.Document بعد import aspose_pdf بسيط.
خلط المُنشأ Document مع الرئيسي aspose_pdf.Document
aspose_pdf.Document (الفئة العليا التي يُعاد تصديرها بواسطة import aspose_pdf) لديها واجهة أوسع — فهي تضيف أساليب مثل validate_pdfa، iter_pages، وredact_text التي لا يُنفّذها aspose_pdf.generated.document.Document. إذا كان أسلوب ما مفقودًا في Document المُنشأ، تحقق مما إذا كان ينتمي إلى الفئة العليا Document بدلاً من ذلك.
save() raises AsposePdfException: Cannot save a disposed document
close()/dispose() يطلق الحالة الداخلية للمستند بشكل دائم — لا يمكن حفظ Document المُهمل أو تحسينه أو إصلاحه لاحقًا. نفّذ جميع العمليات المتبقية قبل استدعاء close()، أو أعد التحميل من المصدر باستدعاء Document(...) جديد.
change_passwords raises PdfSecurityException: Document is not encrypted
change_passwords يدير كلمة المرور فقط في مستند مُشفّر بالفعل. استدعِ encrypt(password) أولاً، أو تحقق من document.is_encrypted قبل محاولة تغيير كلمة المرور.
PdfAValidationResult.add_error raises TypeError
add_error يتطلب معامل str. حوِّل كائنات الاستثناء أو تفاصيل الأخطاء الأخرى إلى سلسلة (str(error)) قبل تمريرها إلى add_error.
الأسئلة المتكررة
لماذا يوجد aspose_pdf.generated إلى جانب aspose_pdf.Document الرئيسي؟
إنه يعكس مجموعة فرعية أضيق ومستقرة من Aspose.PDF API للكود المكتوب ضد تلك السطحية المخفضة. يجب على الكود الجديد الذي لا يحتاج تحديدًا إلى مجموعة التوافق هذه أن يستخدم عادةً aspose_pdf.Document المستوى العلوي، الذي يدعم عمليات أكثر (PDF/A conversion, page iteration, text redaction, and others).
هل يقبل UnsignedContentAbsorber.extract() Document للمسح؟
يقبل extract() وسائط موقعية وكلمات مفتاحية تُستخدم لملء مجموعات pages وform_fields وannotations الخاصة بالـ UnsignedContent المُرجَع — مرِّر المجموعات التي تريد تمثيلها كوسائط كلمات مفتاحية (pages=، form_fields=، annotations=).
ماذا يحدث إذا استدعيت reset() على UnsignedContentAbsorber قبل استخراج أي شيء؟
إنه يمسح أي نتيجة مستخرجة مسبقًا. ثم يُعيد get_extracted() None وتُعيد has_extracted() False حتى يتم استدعاء extract() مرة أخرى.
هل يمكن استدعاء PdfAValidateOptions.add_input أكثر من مرة؟
نعم — كل استدعاء يضيف إدخالًا آخر إلى قائمة inputs، ويُعيد self، لذا يمكن ربط الاستدعاءات: options.add_input("a.pdf").add_input("b.pdf").
هل close() مختلف عن dispose() في الـ Document المُولَّد؟
لا — close() هو اسم مستعار مباشر يستدعي dispose() بنفس المعلمات؛ أي من الاسمين يحرّر موارد المستند.