كيفية العمل مع المستندات في .NET
يوضح هذا الدليل كيفية العمل مع نموذج الكائن Document في Aspose.Words FOSS لـ .NET: إنشاء مستند فارغ، تحميل مستند موجود بأمان، استعراض هيكل القسم/المحتوى، دمج المستندات، وتطبيق قيد تحرير. Aspose.Words FOSS لـ .NET متاح عبر NuGet أو عن طريق البناء من المصدر.
دليل خطوة بخطوة
الخطوة 1: الحصول على المكتبة
استنسخ المستودع وابنِ Aspose.Words.sln في تكوين Release، ثم أضف إشارة مشروع إلى Aspose.Words.csproj من مشروع .NET الخاص بك. أوامر الاستنساخ والبناء الكاملة موجودة في دليل التثبيت. بمجرد الإشارة إليه، أضف using Aspose.Words; في أعلى أي ملف يعمل مع المستندات.
الخطوة 2: إنشاء أو تحميل مستند
استدعِ new Document() لإنشاء مستند فارغ، أو مرّر مسار ملف أو Stream إلى مُنشئ Document(fileName) / Document(stream) لفتح مستند موجود. يُتيح لك تحميل زائد يقبل معامل LoadOptions توفير كلمة مرور لملف مُشفّر. قبل تحميل ملف لا تثق بصيغته بعد، استدعِ FileFormatUtil.DetectFileFormat(fileName) — فإنه يُرجع FileFormatInfo يُبلغ عن LoadFormat المكتشف وما إذا كان الملف IsEncrypted، HasDigitalSignature أو HasMacros، حتى تتمكن من رفض الإدخال غير المتوقع قبل أن يحاول Document تحليله.
الخطوة 3: كتابة المحتوى باستخدام DocumentBuilder
DocumentBuilder يغلف Document مع مؤشر يمكنك تحريكه عبر الشجرة أثناء إدخال المحتوى. Write(text) وWriteln(text) يُدخلان نصًا عند المؤشر، وInsertParagraph() يبدأ فقرة جديدة. التنسيق المحدد على خصائص Font وParagraphFormat وListFormat وPageSetup الخاصة بالباني يُطبق على ما تكتبه لاحقًا. أعد وضع المؤشر باستخدام MoveToDocumentStart() أو MoveToDocumentEnd() أو MoveToSection(sectionIndex) أو MoveToBookmark(bookmarkName) أو MoveToParagraph(paragraphIndex, characterIndex)، واقرأ CurrentNode / CurrentParagraph / CurrentSection لتأكيد موقع الباني.
الخطوة 4: فحص بنية القسم والجسم
Document يكشف عن SectionCollection عبر Document.Sections (بالإضافة إلى FirstSection / LastSection). كل Section يحتوي على Body واحد بالضبط، يُمكن الوصول إلى المحتوى الرئيسي له من خلال Body.Paragraphs (وهو ParagraphCollection) وBody.Tables. لقراءة النص أو البحث فيه دون التنقل بين العقد يدويًا، استخدم Range المتاح على Document وSection وParagraph وغيرها من العقد — Range.Text يُعيد النص العادي، وRange.Replace(pattern, replacement) يُجري عملية بحث-استبدال محصورة في ذلك النطاق فقط.
الخطوة 5: دمج مستندين
لنسخ مستند كامل، استدعِ Document.Clone(). لجلب محتوى محدد من نسخة Document إلى أخرى، استدعِ ImportNode(srcNode, isImportChildren) على المستند الوجهة، أو استدعِ Document.AppendDocument(srcDoc, importFormatMode) لإلحاق كل قسم من مستند المصدر بنهاية المستند الحالي. DocumentBuilder.InsertDocument(srcDoc, importFormatMode) يفعل نفس الأمر لكنه يدرج عند مؤشر الباني بدلاً من النهاية. في جميع الحالات الثلاث، اختر قيمة ImportFormatMode — KeepSourceFormatting أو UseDestinationStyles أو KeepDifferentStyles — بعناية، لأنها تقرر أي أنماط المستند تفوز عندما يتصادم الاثنان.
الخطوة 6: تطبيق قيود التحرير
استدعِ Document.Protect(type, password) بقيمة ProtectionType — ReadOnly أو AllowOnlyComments أو AllowOnlyRevisions أو AllowOnlyFormFields — لتقييد التعديلات التي يقبلها Word للمستند. Unprotect() (مع أو بدون كلمة المرور المطابقة) يزيل القيد. هذا يؤثر فقط على التحرير داخل Word؛ ولا يشفر الملف المحفوظ. لفرض كلمة مرور لفتح الملف فقط، عيّن OoxmlSaveOptions.Password عند الحفظ.
المشكلات الشائعة والحلول
Document(fileName) يرمي استثناءً لملف يفتح بشكل صحيح في Word. صيغة الملف ليست واحدة من الصيغ التي يدعمها محملات هذا الإصدار. Call FileFormatUtil.DetectFileFormat(fileName) أولاً وتحقق من ما تم إرجاعه LoadFormat قبل محاولة التحميل.
المحتوى المنسوخ بين المستندات يلتقط الخطوط أو الأنماط الخاطئة. ال ImportFormatMode تم تمريره إلى AppendDocument or InsertDocument لا يتطابق مع ما توقعت. مرّر KeepSourceFormatting or UseDestinationStyles بصورة صريحة بدلاً من الاعتماد على الإعداد الافتراضي.
Unprotect() يبدو أنه لا يُحدث أي تأثير. إما أن المستند لم يُحمى بكلمة مرور (استدعاء Unprotect() بدون أي معاملات)، أو كلمة المرور المقدمة لا تتطابق مع Protect() التي تم استدعاؤها بـ.
تم تطبيق التنسيق عبر DocumentBuilder لا يظهر في المكان المتوقع. تنسيق على مستوى المُنشئ (Font, ParagraphFormat) يطبق فقط على المحتوى المكتوب after تم تعيينه. حرك المؤشر واضبط التنسيق قبل الاستدعاء Write/Writeln، ليس بعد.
الأسئلة المتكررة
كيف يمكنني إنشاء مستند Word جديد وفارغ؟
استدعِ new Document(). غلفه بـ DocumentBuilder لبدء إدراج المحتوى فورًا.
ما الفرق بين Document.Clone() وImportNode؟
Clone() ينسخ مستندًا كاملاً إلى نسخة جديدة من Document. ImportNode(srcNode, isImportChildren) يجلب عقدة واحدة — وربما أطفالها — من شجرة مستند إلى آخر، وهو ما تستخدمه لدمج محتوى محدد بدلاً من مستندات كاملة.
كيف يمكنني التحقق بأمان من تنسيق الملف قبل تحميله؟
استدعِ FileFormatUtil.DetectFileFormat(fileName) (أو النسخة Stream) وتفقد خصائص FileFormatInfo المعادة: LoadFormat، IsEncrypted، HasDigitalSignature، وHasMacros قبل تمرير الملف إلى Document.
كيف أقرأ الفقرات فقط داخل جسم المستند؟
استخدم مجموعة Body.Paragraphs على Body الخاص بالقسم، أو Body.GetChildNodes(nodeType, isDeep) لأنواع العقد الأخرى.
هل يقوم Document.Protect بتشفير الملف المحفوظ؟
لا — إنها قيود تحرير يفرضها Word عند فتح الملف. لتطلب كلمة مرور لفتح الملف نفسه، اضبط OoxmlSaveOptions.Password عند استدعاء Document.Save.