المقدمة

تحتاج المؤسسات التي تخزن العقود والبيانات المالية أو الملفات التنظيمية إلى حفظ ملفات PDF بصيغة أرشيفية – PDF/A. إذا تسرب ملف واحد دون الامتثال المطلوب، قد يُشير المدققون إلى الدفعة بأكملها، ويمكن أن يُفعل إعادة معالجة مكلفة بعد أشهر. الاعتماد على الفحوص اليدوية يصبح غير عملي عندما تصل مئات الملفات يوميًا.

تزيل GroupDocs.Metadata للـ .NET التخمين. من خلال إظهار علم IsPdfA الواضح وتعداد PdfFormat الدقيق، تخبرك المكتبة في سطر واحد ما إذا كان المستند يطابق أي مستوى من PDF/A، وإذا كان كذلك، أي نسخة محددة (مثل PDF/A‑1b، PDF/A‑2u) يتوافق معها. في هذا البرنامج التعليمي ستتعرف على كيفية دمج هذه المنطق في تطبيق كونسول، وتعريضه عبر واجهة برمجة تطبيقات ويب، وتوسيع نطاقه للمعالجة الدفعية.

بنهاية الدليل ستتمكن من:

  • تحميل ملف PDF باستخدام فئة Metadata.
  • تحديد امتثال PDF/A باستخدام خاصية منطقية.
  • استخراج نسخة PDF/A الدقيقة للملفات المتوافقة.
  • دمج الفحص في سير عمل أكبر (وظائف دفعية، واجهات API، وظائف بدون خادم).

لماذا يعتبر اكتشاف PDF/A الدقيق أمرًا حيويًا

يساعد الفحص الآلي والموثوق على:

  • الاستعداد للتدقيق: إظهار للجهات التنظيمية أن كل PDF مخزن يطابق معيار ISO 19005.
  • الحفاظ على الدقة البصرية: يضمن PDF/A بقاء الخطوط والألوان وتخطيط الصفحة في المشاهد المستقبلية.
  • أتمتة خطوط الإدخال: رفض الملفات غير المتوافقة قبل وصولها إلى نظام إدارة المستندات.
  • تجنب إعادة العمل المكلفة: الكشف المبكر يمنع الحاجة إلى إعادة التحقق الدفعي المكلفة لاحقًا في دورة الحياة.

المتطلبات المسبقة

  • .NET 6.0 أو أحدث.
  • حزمة GroupDocs.Metadata من NuGet (أحدث نسخة).
  • ملف أو أكثر من ملفات PDF تريد تقييمها.
  • (اختياري) ترخيص تقييم مؤقت – يمكنك الحصول عليه من بوابة GroupDocs.

التثبيت

أنشئ مشروع كونسول جديد وأضف الحزمة:

dotnet new console -n DetectPdfA
cd DetectPdfA

dotnet add package GroupDocs.Metadata

الخطوة 1 – تهيئة محرك Metadata

أولاً نفتح ملف PDF باستخدام فئة Metadata. يقوم المُنشئ تلقائيًا بالتعرف على صيغة الملف، لذا لا تحتاج إلى معلمات إضافية.

using GroupDocs.Metadata;

string pdfPath = "sample.pdf";

// افتح المستند – يضمن كتلة using تحرير مقبض الملف.
using (Metadata metadata = new Metadata(pdfPath))
{
    // الخطوات اللاحقة توضع هنا.
}

نقطة أساسية: يضمن بيان using تحرير الموارد الأصلية بسرعة، مما يمنع تسرب مقبض الملف في الخدمات طويلة التشغيل.

الخطوة 2 – الحصول على حزمة الجذر الخاصة بـ PDF

توفر GroupDocs.Metadata كائن جذر قوي النوع لكل صيغة. بالنسبة لملفات PDF نطلب PdfRootPackage، الذي يحتوي على معلومات FileType التي نحتاجها.

using GroupDocs.Metadata.Formats.Pdf;

// داخل كتلة using من الخطوة 1
var root = metadata.GetRootPackage<PdfRootPackage>();

root.FileType يحمل خاصيتين مهمتين:

  • IsPdfAtrue إذا كان المستند يطابق أي مستوى من PDF/A.
  • PdfFormat – تعداد مثل PdfA1b، PdfA2u، إلخ، يحدد النسخة الدقيقة.

الخطوة 3 – إجراء فحص الامتثال

الآن نقرأ العلم، وعند الحاجة نعرض نسخة PDF/A المحددة.

if (root.FileType.IsPdfA)
{
    // المستند متطابق – أبلغ عن النسخة الدقيقة.
    Console.WriteLine($"✅ PDF/A compliant – version: {root.FileType.PdfFormat}");
}
else
{
    // المستند لا يفي بمتطلبات PDF/A.
    Console.WriteLine("❌ The document is NOT PDF/A compliant.");
}

ما تراه:

  • قيمة منطقية واحدة (IsPdfA) تعطي إجابة فورية نعم/لا.
  • عندما تكون true، يوفر PdfFormat مستوى الامتثال الدقيق، والذي يمكنك تخزينه في السجلات أو قواعد البيانات أو تقارير التدقيق.

مثال عملي كامل

دمج الخطوات الثلاث ينتج برنامجًا مختصرًا يمكن نسخه ولصقه مباشرة:

using System;
using GroupDocs.Metadata;
using GroupDocs.Metadata.Formats.Pdf;

class Program
{
    static void Main(string[] args)
    {
        string pdfPath = "sample.pdf";

        using (Metadata metadata = new Metadata(pdfPath))
        {
            var root = metadata.GetRootPackage<PdfRootPackage>();

            if (root.FileType.IsPdfA)
            {
                Console.WriteLine($"✅ PDF/A compliant – version: {root.FileType.PdfFormat}");
            }
            else
            {
                Console.WriteLine("❌ The document is NOT PDF/A compliant.");
            }
        }
    }
}

شغّل البرنامج باستخدام dotnet run. قد يبدو الإخراج لملف متطابق كالتالي:

✅ PDF/A compliant – version: PdfA2u

ولملف غير متطابق:

❌ The document is NOT PDF/A compliant.

تطبيقات واقعية

1. خطوط الأرشفة الآلية – راقب مجلدًا للملفات الواردة، تحقق من كل PDF باستخدام المقتطف أعلاه، وانقل الملفات المتطابقة فقط إلى طبقة التخزين طويلة الأمد.

2. التحقق من التحميل في بوابة ويب – غلف نفس المنطق في متحكم ASP.NET Core (انظر المقتطف الاختياري أدناه) لرفض التحميلات غير المتوافقة مع PDF/A قبل حفظها.

3. فحوص الامتثال بدون خادم – انشر الطريقة كدالة Azure Function تُفعل عند إنشاء Blob، وتعيد حمولة JSON تحتوي على حالة الامتثال.

// مقتطف حمولة Azure Function (جزء)
var result = new
{
    file = file.FileName,
    isPdfA = root.FileType.IsPdfA,
    format = root.FileType.IsPdfA ? root.FileType.PdfFormat.ToString() : null
};

أفضل الممارسات والنصائح

  • تحقق من المسار أولًا – استخدم Path.GetFullPath وتأكد من وجود الملف قبل إنشاء Metadata لتجنب FileNotFoundException.
  • احرص على تحديث المكتبة – الإصدارات الأحدث تحسن من اكتشاف الصيغ وتصلح الأخطاء النادرة.
  • حرّر الموارد بسرعة – نمط using الموضح يضمن تحرير الموارد الأصلية.
  • عالج الاستثناءات – غلف المُنشئ بـ try/catch وسجّل MetadataException للملفات PDF التالفة.
  • التوازي للدفعات الكبيرة – أنشئ كائن Metadata منفصل لكل ملف داخل Parallel.ForEach؛ الـ API آمن للخطوط المتعددة طالما لا يتم مشاركة الكائنات.

استكشاف المشكلات الشائعة وإصلاحها

المشكلة: root.FileType.PdfFormat يُعيد null رغم أن IsPdfA يساوي true.

  • الحل: تأكد من أنك تستخدم GroupDocs.Metadata v23.6+ حيث يُملأ التعداد بالكامل. عادةً ما يحل تحديث حزمة NuGet المشكلة.

المشكلة: يتعطل التطبيق بـ FileFormatException على PDF تالف.

  • الحل: ضع استدعاء new Metadata(pdfPath) داخل try/catch، سجّل اسم الملف، وتخطى الملف في سيناريوهات الدفعات.

المشكلة: استهلاك عالي للذاكرة عند معالجة ملفات PDF متعددة الجيجابايت.

  • الحل: فعّل وضع البث بإنشاء Metadata باستخدام FileStream وتعيين علم enableStreaming إلى true (مثال: new Metadata(stream, true)).

موارد إضافية