كيف تبني إخراج تقارير Excel - COM وOpen XML والقوالب

· آخر تحديث: · · Excel, تقارير, تطوير Windows, Office, COM, Open XML

سجل التعديلات (3 تحديثات، آخر تحديث 3 Sep، 2026)

سجل بالتغييرات التي أُجريت على هذا المقال. وحيثما حُفظت نسخة سابقة، تبقى متاحة للقراءة عبر رابط دائم يحمل معرّف DOI.

أُضيفت روابط الاستشارة الموجودة في الأصل الياباني (consultation_services). ولم يتغيّر نصّ المقالة نفسه. قراءة النسخة السابقة لهذا التحديث (DOI: 10.5281/zenodo.22240855)
أُعيدَت الترجمة العربية كترجمة كاملة عن النص الياباني الأصلي، وأُضيفَت خريطة المعرفة.
أعيدت الترجمة كترجمة كاملة عن النص الياباني الأصلي. كانت النسخة العربية السابقة مختصراً يسقط أبواباً وجداول ورسوم Mermaid وتعليقات الأشكال وFAQ. أُعيدت هذه العناصر وفق الأصل الياباني، والادّعاءات التقنية مطابقة للنسخة اليابانية.
النشر الأول
الاستشهاد بهذا المقال(DOI: 10.5281/zenodo.21621400)

هذا المقال محفوظ على Zenodo. يرد أدناه معرّف DOI الذي يشير دائمًا إلى أحدث نسخة، ومعرّف DOI المثبَّت على النسخة التي تقرؤها.

小村 豪 (2026). كيف تبني إخراج تقارير Excel - COM وOpen XML والقوالب. شركة كومورا سوفت ذ.م.م.. https://doi.org/10.5281/zenodo.21621400 https://comcomponent.com/ar/blog/2026/03/16/010-excel-report-output-how-to-build/

DOI (أحدث نسخة)
10.5281/zenodo.21621400
DOI (هذه النسخة)
10.5281/zenodo.22279820

في استشارات إخراج تقارير Excel كثيراً ما تختلط داخل عبارة «نريد الإخراج إلى Excel» عدّة متطلّبات مختلفة.

  • يريد المستخدم أن يعدّل الناتج يدوياً لاحقاً
  • نريد الإبقاء على .xlsm الموجود
  • نريد الإبقاء على الجداول المحورية والرسوم وإعدادات الطباعة كما هي
  • نريد إخراجاً كبيراً في دفعة ليلية
  • نريد تشغيلاً بلا مشغّل على الخادم
  • نريد PDF أيضاً

لا يحلّ أسلوب واحد كل ذلك بنظافة. ما ينبغي النظر إليه أولاً ليس اسم المكتبة، بل هل ستشغّل تطبيق Excel أم ستنشئ ملف Excel.

إن تجاوزت هذا السؤال فقد يعمل الإصدار الأوّل، لكن الصيانة تصبح مؤلمة لاحقاً. نفترض هنا إخراج تقارير Excel من تطبيقات Windows وأنظمة الأعمال، ونرتّب كيف تختار بين أتمتة COM / Open XML / الإدراج في قالب / الإبقاء على VBA القائمة.

نقطة الفصل التي ينبغي النظر إليها أولاًفي إخراج تقارير Excel ينبغي النظر قبل اسم المكتبة إلى نقطة الفصل بين تشغيل تطبيق Excel وإنشاء ملف Excel، ويبين المخطّط أن تجاوز هذا السؤال يجعل الصيانة مؤلمة لاحقاً حتى إن عمل الإصدار الأوّل.تشغيل التطبيقإنشاء الملفتشغيل تطبيق Excel أم إنشاء ملف؟أسلوب التشغيل التلقائي لـ Excelأسلوب تركيب xlsx مباشرةتجاوزه يجعل الصيانة مؤلمة لاحقاً

الشكل 1: قبل اختيار المكتبة، قرّر إن كنت ستشغّل Excel أم ستركّب الملف.

الجمهور المستهدف والافتراضات

المقالة موجّهة إلى المطوّر الذي سيقرّر الآن أسلوب إخراج تقارير Excel من نظام أعمال.

الافتراض هو الإخراج من تطبيق أو دفعة C# / .NET تعمل على Windows. نفترض أيضاً حالات تحمل أصول VBA قائمة، لكن حتى عندئذ لا نكتب على أساس «إكمال كل شيء بـ VBA وحدها»، بل على أساس تقسيم الأدوار مع جانب .NET. أمثلة الشيفرة بـ C# / .NET 8.

مصطلحات ينبغي تثبيتها مسبقاً

المصطلح المعنى
Open XML صيغة الملفات منذ Office 2007. كيان .xlsx أرشيف ZIP يجمع ملفات XML، ويمكن تركيبه برمجياً دون تشغيل Excel
أتمتة COM (Office Automation) أسلوب يشغّل تطبيق Office مثل Excel فعلاً ويتحكّم فيه من برنامج خارجي. COM آليّة استدعاء بين مكوّنات Windows، وExcel يعرض واجهة لذلك
bitness هل البناء والتشغيل 32-bit أم 64-bit. في أتمتة COM يفشل الاتصال إن لم يتطابق bitness جانب الاستدعاء مع Excel نفسه
النطاق المسمّى اسم يمكن إعطاؤه لخلية أو نطاق في Excel. بدل عنوان مثل Cells[12, 7] تحدّد مدخل حقن البيانات عبر هذا الاسم
الجدول (ListObject) بنية تُنشأ بـ «التنسيق كجدول» في Excel. إضافة صف تمدّ التنسيق والصيغ تلقائياً، لذا تناسب مدخل صفوف التفاصيل

1. الخلاصة أولاً

نضع الخلاصة أولاً.

  • إن كان المستخدم سيفتح التقرير في Excel ويحرّره لاحقاً، فالمرشّح الأوّل هو قالب مع توليد مباشر لـ .xlsx / .xlsm.
  • إن كان التوليد التلقائي على خادم / خدمة / جدولة، فالأسلم ألّا تفترض أتمتة Office.
  • إن أردت الإبقاء على .xlsm القائم وVBA والرسوم والجداول المحورية وإعدادات الطباعة، فضع التخطيط وميزات Excel الخاصة في جانب القالب، واجعل الشيفرة تقتصر على حقن البيانات؛ هكذا يقلّ الكسر.
  • لا تستخدم أتمتة COM إلا عندما تحتاج فعلاً إلى سلوك تطبيق Excel نفسه، واحصرها عندئذ في تشغيل بحضور مستخدم على سطح المكتب.
  • إن كان المطلوب مجرّد قائمة، فقد يناسب CSV / PDF / شاشة ويب المتطلّب من البداية أكثر مما تظن.

باختصار، في كثير من تقارير الأعمال يكون الطبيعي «تركيب ملف Excel» لا «تشغيل Excel».

المرشّح الأوّل بحسب المتطلّبيبين المخطّط أن التقرير الذي سيحرّره المستخدم لاحقاً مرشّحه الأوّل قالب وتوليد مباشر، وأن التوليد التلقائي على خادم أو خدمة لا يفترض أتمتة Office، وأن أتمتة COM تُحصر في تشغيل بحضور مستخدم عندما تحتاج فعلاً إلى سلوك تطبيق Excel.تقرير يُحرَّر لاحقاًقالب وتوليد مباشرتوليد تلقائي بلا مشغّللا تفترض أتمتة Officeالحاجة إلى سلوك Excel نفسهاحصر أتمتة COM في تشغيل بحضور مستخدم

الشكل 2: انظر من يشغّل وأين يشغّل، فيكاد المرشّح الأوّل يتحدّد.

في المخطّط، يشير الخطّ المتّصل إلى علاقة قائمة دائماً، ويشير الخطّ المتقطّع إلى علاقة مشروطة (شروط قيامها مذكورة في شرح كلّ علاقة في الصفحة التفصيليّة). القائمة الكاملة للعلاقات (المجموع 29، مع الأدلّة ودرجة اليقين) وتعريفات المفاهيم الرئيسة مجمّعة في صفحة تفاصيل خريطة المعرفة (باليابانية). البيانات: JSON-LD / Turtle

2. ما ينبغي تقريره أولاً

نجمع في جدول ما يستحق التقرير مسبقاً في إخراج تقارير Excel.

بند التحقق لماذا يُقرَّر أولاً
هل الناتج النهائي .xlsx / .xlsm / PDF / CSV هنا يضيق الأسلوب كثيراً
هل سيحرّر المستخدم الناتج في Excel بعد الإخراج إن كان التحرير مفترضاً صارت ميزات Excel والحفاظ على التخطيط مهمّين
هل مكان التشغيل جهاز المستخدم أم خادم / خدمة / دفعة نطاق استخدام أتمتة COM يتغيّر كثيراً
هل نبقي VBA / وحدات الماكرو / الإضافات القائمة يلزم تصميم قالب .xlsm أو ترحيل مرحلي
هل نريد تثبيت الرسوم والجداول المحورية ونطاق الطباعة والترويسة / التذييل أمتن أن تميل إلى القالب لا إلى الشيفرة
كم عدد الصفوف والملفات والتنفيذ المتزامن في المرّة الواحدة في الإخراج الكبير يناسب التوليد المباشر أكثر من COM
من يغيّر مظهر التقرير إن لم يكن المطوّر وحده، بل الميدان أيضاً، ناسب أسلوب القالب

3. أساليب التنفيذ الرئيسة

3.1 أتمتة Excel عبر COM

تشغّل Excel وتتعامل مع Workbook وWorksheet وRange عبر COM. أسهل تصوّر هو أنك تقود Excel الحقيقي.

القوة أنك تستخدم سلوك Excel نفسه كما هو. يناسب المصنّفات القائمة والرسوم والجداول المحورية وإعدادات الطباعة والماكرو وإخراج PDF، وتتعامل مباشرة مع «كيف يعرض Excel الناتج في النهاية».

غير أن نقاط الضعف واضحة أيضاً.

  • يلزم تثبيت Excel
  • تحمل عمر العملية وقفل الملفات ومربّعات الحوار وbitness والاعتماد على ملف تعريف المستخدم
  • أتمتة Office من خادم بلا مشغّل أو من خدمة لا توصي بها Microsoft نفسها ولا تدعمها

النقطة الثالثة أقوى ادّعاء في هذه المقالة، لذا نذكر المصدر صراحة. مقالة دعم Microsoft «Considerations for server-side Automation of Office» تنصّ على أنها لا توصي بأتمتة Office على جانب الخادم ولا تدعمها. الأسباب المذكورة خمسة:

السبب المضمون
معرّف المستخدم يفترض Office وجود مستخدم، ويقرأ إعدادات السجل لكل مستخدم. تفشل الخدمة التي تعمل بحساب بلا ملف تعريف مستخدم عند هذه النقطة
تفاعل سطح المكتب يفترض Office سطح مكتب تفاعلياً، وقد يعرض مربّعات حوار نمطية. في بيئة لا يستطيع أحد إغلاقها يتوقف الخيط هناك ويستمر
إعادة الدخول وقابلية التوسّع تطبيقات Office خوادم COM أحادية الخيط وغير قابلة لإعادة الدخول. التصميم لعميل واحد، فلا تحتمل التنفيذ المتعدّد الذي تحتاجه أغراض الخادم
المتانة والاستقرار قد تُظهر ميزات التثبيت عند أوّل استخدام مربّعات حوار غير متوقّعة، ولم يُختبر النشر على جانب الخادم أصلاً
أمن جانب الخادم لا تملك تحكّماً أمنياً موجّهاً إلى المكوّنات الموزّعة، ولا تصادق على الطلبات. ثمّة خطر مشاركة معلومات مصادقة مخزّنة بين عملاء متعدّدين

لبيئة RPA في Microsoft 365 ترتيب منفصل في «Considerations for unattended automation of Office». إن صار هذا البند موضع خلاف عند اختيار الأسلوب، فاجعل هاتين المقالتين المصدر.

موقع أتمتة جانب الخادميبين المخطّط أن أتمتة Office من خادم بلا مشغّل أو من خدمة لا توصي بها Microsoft نفسها ولا تدعمها، وأن مقالتين رسميتين تصلحان مصدراً عندما يصير اختيار الأسلوب موضع خلاف.أتمتة Office من خادم بلا مشغّلMicrosoft لا توصي ولا تدعممقالة الدعم تصبح مستنداًبيئة RPA في M365 مرتّبة في مقالة أخرى

الشكل 3: جواز هذا الأسلوب ليس ذوقاً؛ يُحسم بمصدر رسمي.

3.2 التوليد المباشر لـ .xlsx

.xlsx صيغة Open XML، لذا يمكن تركيب الملف مباشرة دون تشغيل Excel. بوسائل مثل Open XML SDK تتعامل برمجياً مع المصنّف والورقة والخلية والنمط والجدول.

قوة هذا الأسلوب أنه يسهل تشغيله حتى في بيئة بلا Excel، ويناسب الدفعات والخوادم.

في المقابل يصعب قليلاً إن أردت إعادة سلوك Excel ذي الطابع البصري كما هو. المحاذاة التلقائية لعرض الأعمدة وتقسيم الصفحات والمظهر المعقّد والتحرير العميق لمصنّف قائم تجعل عدد الأسطر يتزايد إن حاولت إنجاز كل ذلك بالشيفرة وحدها.

طابع أسلوب التوليد المباشريبين المخطّط أن xlsx صيغة Open XML يمكن تركيبها دون تشغيل Excel وأنها تناسب البيئات بلا Excel والدفعات والخوادم، بينما تتزايد الشيفرة إن أردت إعادة سلوك Excel ذي الطابع البصري.xlsx صيغة Open XMLالتركيب دون تشغيل Excelيناسب الدفعات والخوادمإعادة الجانب البصري تزيد الشيفرة

الشكل 4: قوة الاستغناء عن Excel وضعف إعادة المظهر وجهان لعملة واحدة.

مكتبات التعامل مع .xlsx من .NET عدّة، وشروط الترخيص تؤثّر عملياً. المرشّحون الشائعون هم تقريباً هؤلاء.

المكتبة الترخيص الموقع
Open XML SDK (DocumentFormat.OpenXml) MIT من Microsoft. تلمس بنية Open XML كما هي تقريباً. أوسع قدرة، لكن كتابة خلية واحدة تتطلّب حجماً من الوصف
ClosedXML MIT غلاف فوق Open XML SDK. تتعامل مع الورقة والخلية والنطاق المسمّى والجدول بواجهة مباشرة. تدعم .xlsx و.xlsm ولا تحتاج تثبيت Excel
NPOI Apache License 2.0 نقل Apache POI من Java إلى .NET. ميزته التعامل مع الصيغة القديمة .xls أيضاً
EPPlus من الإصدار 5 Polyform Noncommercial أو ترخيص تجاري عالية القدرة، لكن الاستخدام التجاري يتطلّب ترخيصاً مدفوعاً. اختيارها بذاكرة عصر LGPL في الإصدار 4 يوقع حادث ترخيص

في أسلوب الإدراج في قالب يحمل القالب المظهر، فلا يُطلب من الشيفرة سوى «وضع القيمة في المدخل المتّفق عليه». لذلك يسهل التعامل مع أغلفة أقل حجماً في الكتابة.

3.3 الإدراج في قالب

الأسلوب الأسهل توصيته عملياً هو صنع قالب Excel أولاً، وجعل الشيفرة تقتصر على حقن البيانات.

ضع مظهر التقرير والصيغ والتنسيق الشرطي ونطاق الطباعة والترويسة / التذييل والشعار والرسوم في جانب القالب. جانب الشيفرة ينسخ القالب ويكتب البيانات في «المداخل المتّفق عليها» مثل النطاقات المسمّاة والجداول ونطاقات الخلايا.

بهذا ينفصل تعديل التخطيط عن تعديل منطق الأعمال. ويصير تجنّب جحيم Cells[37, 9] = ... الشائع في تقارير Excel أسهل كثيراً.

تقسيم الأدوار في الإدراج في قالبيبين المخطّط أن المظهر والصيغ وإعدادات الطباعة تُوضع في جانب القالب، وأن جانب الشيفرة ينسخ القالب ويكتب البيانات في مداخل متّفق عليها مثل النطاقات المسمّاة والجداول، فينفصل تعديل التخطيط عن تعديل منطق الأعمال.جانب القالبيحمل المظهر والصيغ وإعدادات الطباعةجانب الشيفرةيكتب القيم في المداخل المتّفق عليها فقطينفصل تعديل التخطيط عن تعديل الأعمال

الشكل 5: جوهر هذا الأسلوب فصل موضع المظهر عن موضع المنطق.

3.4 أسلوب الإبقاء على أصول VBA القائمة

إن كانت .xlsm وVBA القائمة لا تزال حيّة، فالأكثر طبيعية غالباً ألا تعيد بناء كل شيء دفعة واحدة. تقسيم من نوع: واجهة التقرير والتشطيب الأخير يبقيان في VBA، والحساب الثقيل وDB / HTTP ومنطق الأعمال ينتقلان إلى جانب C# / .NET، تقسيم واقعي جداً.

المهم هنا ألّا تبقى المسؤوليات غامضة.

  • جانب VBA: السلوك داخل المصنّف
  • جانب .NET: جلب البيانات ومعالجة الأعمال
  • الحدود بينهما تُثبَّت بنطاقات مسمّاة وجداول وواجهات معلنة
تقسيم المسؤوليات بين VBA القائمة و.NETيبين المخطّط أنه عند الإبقاء على xlsm وVBA القائمة يتولّى جانب VBA السلوك داخل المصنّف ويتولّى جانب .NET جلب البيانات ومعالجة الأعمال، وأن الحدود بينهما تُثبَّت بنطاقات مسمّاة وجداول وواجهات معلنة.جانب VBAالسلوك داخل المصنّفجانب .NETجلب البيانات ومعالجة الأعمالتُثبَّت الحدود بنطاقات مسمّاة ونحوها

الشكل 6: سرّ الإبقاء على الأصل تثبيت الحدود وألا تبقى المسؤوليات غامضة.

3.5 حالة استخدام Microsoft 365 / Graph

إن كان ملف Excel على OneDrive / SharePoint من البداية، وأردت استخداماً مشتركاً من تطبيق ويب أو جوّال، دخل Excel API في Microsoft Graph ضمن الخيارات.

غير أنه ليس حلاً عاماً لإنتاج ملفات عشوائية بكميات على جهاز محلّي. الصلاحيات ومكان الحفظ والجلسة والتشغيل تفترض M365 من البداية.

3.6 هل يلزم أن يكون Excel أصلاً؟

إن كان متطلّب التقرير «جدولاً يلمسه إنسان لاحقاً»، فاختيار Excel طبيعي. غير أن متطلّبات كهذه كثيراً ما تكون صيغة أخرى أصدق.

  • طباعة وحفظ -> PDF
  • إدخال إلى نظام آخر -> CSV / TSV / JSON
  • يكفي العرض في المتصفّح -> HTML / شاشة ويب
  • الغرض الرئيس تجميع وتصور -> BI أو لوحة معلومات
التحقق مما إذا كان Excel لازماًيبين المخطّط أن اختيار Excel طبيعي إن كان المتطلّب جدولاً يلمسه إنسان لاحقاً، أما الطباعة والحفظ أو الإدخال إلى نظام آخر أو العرض في المتصفّح أو التجميع والتتصور كغرض رئيس فكثيراً ما تكون صيغة أخرى أصدق.يلمسهلا يلمسههل هو جدول يلمسه إنسان لاحقاً؟اختيار Excel طبيعيادرس صيغة أخرىPDF / CSV / شاشة ويب / BI وغيرها

الشكل 7: استنتج صيغة الإخراج من الغرض، ولا تجعل Excel القيمة الافتراضية.

4. مقارنة الأساليب

إن صففنا الفروق في جدول واحد صارت كالتالي.

الأسلوب تثبيت Excel التوافق مع التشغيل بلا مشغّل إعادة استخدام التخطيط القائم التوافق مع ميزات Excel الخاصة المشهد المناسب
أتمتة COM لازم ضعيف قوي قوي جداً الإخراج على جهاز المستخدم، .xlsm القائم، التحويل النهائي إلى PDF
التوليد المباشر لـ .xlsx غير لازم قوي متوسط متوسط الدفعات، الخوادم، الإخراج بكميات كبيرة
الإدراج في قالب غير لازم (عند الإخراج) قوي قوي متوسط إلى قوي المرشّح الأوّل لكثير من تقارير الأعمال
الإبقاء على VBA القائمة بحسب شكل الاستخدام ضعيف إلى متوسط قوي جداً قوي الترحيل المرحلي، استثمار الأصول القائمة
Graph Excel API يفترض M365 متوسط متوسط متوسط الاستخدام المشترك على OneDrive / SharePoint

5. الاختيار بحسب المتطلّبات الشائعة

5.1 الإخراج على جهاز المستخدم ثم التحرير مباشرة

هنا قالب مع توليد مباشر خيار قوي جداً. المستخدم يفتح الناتج في Excel بعد الإخراج، فيجوز ترك التحرير النهائي لـ Excel.

5.2 التوليد بكميات كبيرة في دفعة ليلية أو خدمة

إن دخلت دفعة ليلية، فالأسلم أن تبدأ بإخراج أتمتة COM من المرشّحين. اجعل التوليد يميل إلى التوليد المباشر لـ .xlsx، ودع المستخدم يفتح الملف في Excel لاحقاً إن لزم.

مسار العمل في الدفعة الليليةيبين المخطّط أنه في التوليد بكميات كبيرة في دفعة ليلية أو خدمة يكون الأسلم إخراج أتمتة COM من المرشّحين أولاً، والميل بالتوليد إلى التوليد المباشر لـ xlsx، وترك المستخدم يفتح الملف لاحقاً إن لزم.نريد توليداً كبيراً في دفعة ليليةأخرج أتمتة COM أولاًمل نحو التوليد المباشر لـ xlsxيفتحه المستخدم لاحقاً إن لزم

الشكل 8: تصميم التشغيل بلا مشغّل يبدأ بالطرح.

5.3 الإبقاء على .xlsm / VBA القائمة

إن كانت الأصول القائمة حيّة، فالأوقع الإبقاء على .xlsm قالباً والاكتفاء بحقن البيانات من الخارج.

5.4 صفوف التفاصيل كبيرة

حدّ ورقة Excel الواحدة 1,048,576 صفّاً × 16,384 عموداً. إن كانت التفاصيل كبيرة فقرّر هذا أولاً.

  • بعد كم صفّاً نقسم الورقة
  • بعد كم عنصراً نقسم الملف
  • أليس CSV أصدق أصلاً
ما يُقرَّر مسبقاً عندما تكون التفاصيل كبيرةيبين المخطّط أن لورقة Excel الواحدة حدّاً لعدد الصفوف والأعمدة، لذا عندما تكون التفاصيل كبيرة يُقرَّر أولاً معيار تقسيم الورقة ومعيار تقسيم الملف وما إذا كان CSV أصدق أصلاً.التفاصيل كبيرةللورقة الواحدة حدّقرّر معيار تقسيم الورقةقرّر معيار تقسيم الملفأعد النظر: هل CSV أصدق

الشكل 9: لا تنتظر الاصطدام بالحد؛ قرّر سياسة التقسيم مسبقاً.

6. بنية يسهل توصيتها عملياً

ما يصعب كسره عملياً بنية من أربع طبقات.

الطبقة الدور ما لا تفعله هنا
ReportModel تشكيل القيم اللازمة للتقرير لا تعرف عناوين الخلايا
Template تحمل المظهر والصيغ وإعدادات الطباعة والرسوم لا تعرف قاعدة البيانات ولا منطق الأعمال
Binder تكتب البيانات في نطاقات مسمّاة / جداول لا تُدخل أحكام أعمال
Finisher تستدعي VBA / COM / التحويل إلى PDF عند الحاجة لا تجلب البيانات الأصلية

حسن هذا التقسيم أن الشيفرة تقلّ تبعيتها لمظهر Excel.

6.1 ماذا يسري بين الطبقات

المهم ما يعبر حدود الطبقة. إن تحدّد ذلك أمكن المضي في تغيير التخطيط وتغيير منطق الأعمال كلٍّ على حدة.

بيانات خاممصنّف منسوخأزواج اسم وقيمةمصنّف فيه القيمناتجإن لم تلزم Finisherيكتمل هناDB / API / ملفReportModelيشكّل القيم اللازمةللتقرير ويحفظهاTemplatexlsx أو xlsmالمظهر والصيغ وإعدادات الطباعةBinderتكتب القيم في النطاقات المسمّاةوالجداولFinisherتحويل إلى PDF أو استدعاء VBAعند الحاجة فقطxlsx / xlsm / PDF

الشكل 10: ما يسري بين الطبقات الأربع أزواج اسم وقيمة فقط، وعناوين الخلايا لا تخرج من Binder.

ما يعبر الحدود أزواج اسم وقيمة فقط، ولا تُخرج عناوين الخلايا خارج Binder. إن وصلت اعتبارات القالب حتى ReportModel، فالتصميم بدأ ينهار عند تلك النقطة.

6.2 أصغر مثال تنفيذ

كتابة الإدراج في قالب بـ ClosedXML تكون كالتالي. عرّف مسبقاً في قالب Invoice.xlsx النطاقات المسمّاة Rpt_Title وRpt_IssuedOn وRpt_CustomerName وRpt_DetailRows.

// C# / .NET 8 + ClosedXML(MIT ライセンス)
//   dotnet add package ClosedXML
using ClosedXML.Excel;

// ReportModel 相当。セル番地は一切持たない
var rows = new (string Code, string Name, int Qty, decimal UnitPrice)[]
{
    ("A-100", "محمل كروي", 12, 480m),
    ("A-205", "عمود", 3, 12800m),
    ("B-010", "حامل تثبيت", 30, 260m),
};

const string TemplatePath = @"templates\Invoice.xlsx";
string outputDir = "output";
Directory.CreateDirectory(outputDir);

// ファイル名は「秒までの時刻」で作らないこと。1件ずつ回すバッチでは、
// 2件が同じ秒に入った瞬間に同じ名前になり、後から保存したほうが
// 先の帳票を上書きします。消えたことに誰も気づかないのが厄介なところです。
// 帳票を一意に決める業務上の識別子(ここでは請求書番号)を必ず入れます。
string invoiceNo = "INV-2026-000123";     // 呼び出し側から受け取る
string outputPath = Path.Combine(outputDir, $"Invoice_{invoiceNo}.xlsx");

// 1. テンプレートを開く。保存は別名にするので、テンプレート自体は書き換わらない
using var workbook = new XLWorkbook(TemplatePath);

// 2. ヘッダーは名前付きセルへ。コードにセル番地が出てこないのが要点
workbook.Cell("Rpt_Title").Value = "فاتورة";
workbook.Cell("Rpt_IssuedOn").Value = DateTime.Today;   // 値として入れる。表示形式はテンプレート側
workbook.Cell("Rpt_CustomerName").Value = "شركة العينة";

// 3. 明細は名前付き範囲を入口にし、範囲内の相対位置で書く
var detail = workbook.Range("Rpt_DetailRows");
if (rows.Length > detail.RowCount())
{
    // 用意した行数を超えた。黙って切り捨てず、ここで止める
    throw new InvalidOperationException(
        $"عدد بنود التفاصيل {rows.Length} لكن Rpt_DetailRows في القالب {detail.RowCount()} صفّاً." +
        " زِد صفوف القالب أو قسّم الورقة.");
}

for (int i = 0; i < rows.Length; i++)
{
    var row = rows[i];
    detail.Cell(i + 1, 1).Value = row.Code;        // 範囲内の 1 始まりの相対位置
    detail.Cell(i + 1, 2).Value = row.Name;
    detail.Cell(i + 1, 3).Value = row.Qty;
    detail.Cell(i + 1, 4).Value = row.UnitPrice;
}

// 4. 別名で保存する。テンプレートは読み取り専用の資産として残す。
//    書き込みは同じフォルダーの一時ファイルへ行い、書き切ってから本来の名前へ
//    付け替えます。outputPath へ直接書くと、途中で失敗したとき(ディスク満杯、
//    ブックの不整合など)に「途中まで書けた .xlsx」が業務上のファイル名で残ります
string tempPath = Path.Combine(
    Path.GetDirectoryName(outputPath) ?? string.Empty,   // 付け替えを同一ボリューム内に収める
    $".{Path.GetFileName(outputPath)}.{Guid.NewGuid():N}.tmp");

try
{
    using (var stream = new FileStream(tempPath, FileMode.CreateNew, FileAccess.Write, FileShare.None))
    {
        workbook.SaveAs(stream);
    }

    // 既に同名があれば IOException。同名が来たときに黙って上書きせず、
    // その場で気づけます(FileMode.CreateNew と同じ方針)
    File.Move(tempPath, outputPath);
}
catch
{
    // 失敗したら痕跡を残さない。残すと、次の実行が同じ名前で再試行できなくなる
    try { File.Delete(tempPath); } catch (IOException) { }
    throw;
}
Console.WriteLine($"تمّ الإخراج: {outputPath}");

ما تنتبه إليه هذه الشيفرة خمس نقاط.

  • عناوين الخلايا لا تظهر في الشيفرة. مدخل الحقن نطاقات مسمّاة فقط. حتى إن أضفت صفّاً في القالب لا تتغيّر هذه الشيفرة
  • لا تُكتب فوق القالب. المصنّف المفتوح يُحفظ دائماً باسم آخر
  • التاريخ والرقم يُدخلان قيماً. إن أدخلتهما نصّاً منسّقاً تعطّل الترتيب والتجميع في Excel
  • فيض التفاصيل يوقف التنفيذ باستثناء. أسوأ كسر في تقرير هو الاقتطاع دون تنبيه. هنا تُسقط سياسة 5.4 في التنفيذ
  • الاسم الأصلي يُعطى بعد اكتمال الكتابة. قد يفشل SaveAs بعد أن يبدأ الكتابة. امتلاء القرص، وانقطاع المشاركة، وعدم اتساق محتوى المصنّف، كلها تقع. إن كتبت مباشرة إلى outputPath بقي عندئذ ملف مقطوع باسم مثالي مثل Invoice_INV-2026-000123.xlsx. يحكم الناس بالاسم فلا يميّزونه عن تقرير مكتمل. وفوق ذلك يرفض FileMode.CreateNew الملف الموجود، فيتوقف إعادة التشغيل أيضاً لأن «الملف موجود سلفاً». إن كتبت إلى ملف مؤقّت ثم بدّلت بـ File.Move لم يظهر ذلك الاسم إلا بعد اكتمال المحتوى. جعل وجهة التبديل المجلد نفسه لأن Move عبر الأقراص يصبح نسخاً وقد ينقطع في المنتصف

حتى إن حملت المبلغ بـ decimal، فإنه يصير عند دخول صيغة ملف Excel عدداً عشرياً مزدوج الدقة. إن كان معيار التقريب مهمّاً للأعمال، فالأسلم صنع قيمة مقرّبة مسبقاً في جانب ReportModel لا ترك الأمر لصيغ Excel.

إن جعلت .xlsm قالباً فالمسار نفسه، لكن اجعل امتداد الحفظ .xlsm. البنية التي تبقي الماكرو مع الحقن كما في 3.4.

مسار الحفظ عبر ملف مؤقّتيبين المخطّط مسار الكتابة كاملة إلى ملف مؤقّت في المجلد نفسه ثم التبديل إلى الاسم الأصلي بـ File.Move، وحذف الملف المؤقّت عند الإخفاق، حتى لا يبقى ملف مقطوع باسم الملف التشغيلي.نجاحإخفاقاكتب إلى ملف مؤقّت في المجلد نفسههل اكتملت الكتابة؟بدّل إلى الاسم الأصلي بـ File.Moveاحذف الملف المؤقّت وأبلغ بالاستثناءلا يظهر الاسم إلا بعد اكتمال المحتوى

الشكل 11: اسم الملف التشغيلي لا يُعطى إلا لملف مكتمل.

7. المطبات

7.1 لا تجعل عنوان الخلية مواصفة أعمال

إن بدأ Cells[12, 7] يمثّل قاعدة أعمال، صار تغيير التخطيط تغييراً في المواصفة كما هو. الشيفرة التي تلمس التقرير عبر نطاقات مسمّاة أو أسماء جداول تعيش أطول.

لا تجعل عنوان الخلية مواصفة أعماليبين المخطّط أنه إن بدأ عنوان الخلية يمثّل قاعدة أعمال صار تغيير التخطيط تغييراً في المواصفة، لذا تعيش الشيفرة أطول إن لمست التقرير عبر نطاقات مسمّاة أو أسماء جداول.عنوان الخلية يمثّل قاعدة أعمالتغيير التخطيط يصير تغييراً في المواصفةالمرور عبر نطاق مسمّى أو اسم جدولالشيفرة تصمد حتى مع تغيير التخطيط

الشكل 12: اللمس بالاسم لا بالعنوان هو ما يحدّد عمر شيفرة التقرير.

7.2 لا تجعل الخلايا المدمجة مدخل بيانات

الخلايا المدمجة وظيفة للعرض. استخدامها مدخل حقن يسهل الحوادث عند إضافة صفوف أو حساب النطاقات.

7.3 لا تملأ الأرقام والتواريخ «نصّاً بمظهر جاهز»

أدخل القيمة قيمة، ومل بالمظهر إلى تنسيق الخلية؛ هذا أصدق.

7.4 لا تترك تغيير القالب تشغيلاً بلا ضوابط

القالب ليس شيفرة، لكنه في الجوهر المواصفة نفسها. الأسلم معاملته هدفاً لإدارة الإصدارات ومراجعة الفروقات والمراجعة.

7.5 إن استخدمت COM فلا تتهاون في bitness وإدارة العمر

في أتمتة COM والربط مع VBA تؤثّر بهدوء فروق 32-bit / 64-bit وتنظيف عملية Excel وقفل الملفات وفروق بيئة المستخدم.

8. الخلاصة

يبدو إخراج تقارير Excel سطراً واحداً هو «الإخراج إلى Excel»، بينما ينبغي في الواقع تقرير عدّة تفرّعات مسبقاً.

  • هل تشغّل تطبيق Excel
  • أم تنشئ ملف Excel
  • جهاز المستخدم أم تشغيل بلا مشغّل
  • هل تبقي VBA القائمة أو .xlsm
  • هل الناتج النهائي Excel أم PDF أو CSV

عملياً المرشّح الأوّل قالب مع توليد مباشر قوي جداً. ثم تضيف عند الحاجة إعادة استخدام VBA القائمة أو معالجة Excel النهائية على جهاز المستخدم؛ هذا الشكل يسهل تماسكه.

كيف تُبنى بنية يسهل تماسكهايبين المخطّط أن الوضع العملي يضع قالباً وتوليداً مباشراً محوراً، ثم يضيف عند الحاجة إعادة استخدام VBA القائمة أو المعالجة النهائية لـ Excel على جهاز المستخدم.ضع القالب والتوليد المباشر محوراًأضف إعادة استخدام VBA القائمة إن لزمأضف المعالجة النهائية على جهاز المستخدم إن لزم

الشكل 13: حدّد محوراً واحداً ثم أضف الاستثناءات فقط فيسهل التماسك.

9. روابط مرجعية

مرتّبة بترتيب القراءة.

9.1 ما يُقرأ قبل تقرير الأسلوب

9.2 ما يُستخدم في التوليد المباشر

  • About the Open XML SDK for Office — أساس تركيب .xlsx دون Excel
  • ClosedXML — الغلاف المستخدم في مثال 6.2. ترخيص MIT
  • NPOI — خيار عندما يلزم التعامل مع .xls القديم. Apache License 2.0
  • EPPlus — راجع شروط ترخيص الإصدار 5 وما بعده حتماً قبل الاعتماد

9.3 عند التعامل على M365 / SharePoint

9.4 ما يُتعمّق فيه عند التعامل مع مصنّفات كبيرة

أحدث المقالات التي تشترك في نفس الوسوم. عمّق فهمك بمواضيع مرتبطة.

ترتبط هذه المقالة بشكل طبيعي بصفحات الخدمات التالية.

الأسئلة الشائعة

أسئلة شائعة حول موضوع هذه المقالة.

أيّهما أختار لإخراج تقارير Excel: أتمتة COM أم توليد الملف مباشرة؟
ما ينبغي النظر إليه أولاً ليس اسم المكتبة، بل هل ستشغّل تطبيق Excel أم ستنشئ ملف Excel. في كثير من تقارير الأعمال يكون الطبيعي «تركيب ملف Excel» لا «تشغيل Excel»، وإذا كان المستخدم سيحرّر التقرير لاحقاً فإن المرشّح الأوّل هو قالب مع توليد مباشر لـ .xlsx/.xlsm. لا تستخدم أتمتة COM إلا عندما تحتاج فعلاً إلى سلوك تطبيق Excel نفسه، واحصرها عندئذ في تشغيل بحضور مستخدم على سطح المكتب.
هل يجوز استخدام أتمتة COM لـ Excel على خادم أو في دفعة ليلية؟
الأسلم تجنّبها. Microsoft نفسها لا توصي بأتمتة Office من خادم بلا مشغّل أو من خدمة، ولا تدعمها. تتطلّب أتمتة COM تثبيت Excel، وتحمل مشكلات عمر العملية وقفل الملفات ومربّعات الحوار وbitness والاعتماد على ملف تعريف المستخدم. في الدفعات الليلية والإخراج بكميات كبيرة انحَ نحو التوليد المباشر لـ .xlsx، ودع المستخدم يفتح الملف في Excel لاحقاً إن لزم.
هل يمكن بناء إخراج التقارير مع الإبقاء على أصول .xlsm وVBA القائمة؟
نعم. إذا كانت الأصول القائمة لا تزال حيّة، فلا تعد بناء كل شيء دفعة واحدة؛ الأوقع الإبقاء على .xlsm قالباً والاكتفاء بحقن البيانات من الخارج. أبقِ واجهة التقرير والتشطيب الأخير في VBA، وانقل الحساب الثقيل وDB وHTTP ومنطق الأعمال إلى جانب C#/.NET. المهم ألا تبقى المسؤوليات غامضة، وثبّت الحدود بين الجانبين بنطاقات مسمّاة وجداول وواجهات معلنة.
ما المطبات التي ينبغي تجنّبها عند تنفيذ تقارير Excel؟
الأهم أولاً ألا تجعل عنوان الخلية مواصفة أعمال؛ المس التقرير عبر نطاقات مسمّاة أو أسماء جداول بدل Cells[12, 7]. الخلايا المدمجة للعرض فقط فلا تجعلها مدخل حقن، وأدخل الأرقام والتواريخ قيماً واترك المظهر لتنسيق الخلية، وعامل القالب مواصفة فعلية تخضع لإدارة الإصدارات والمراجعة. وحدّ ورقة Excel الواحدة 1,048,576 صفّاً × 16,384 عموداً، فإن كانت التفاصيل كبيرة فقرّر مسبقاً سياسة تقسيم الأوراق أو الملفات.

الملف الشخصي للمؤلف

صفحة الملف الشخصي لمؤلف المقالة.

غو كومورا

مؤسّس شركة كومورا سوفت ذ.م.م.

يركّز على تطوير برامج ويندوز، والاستشارات التقنية، والتحقيق في الأخطاء، ويتميّز في المشاريع التي تبقى فيها الأصول القديمة ناشطة، وفي تشخيص الأعطال التي يصعب تحديد سببها.

العودة إلى المدونة