ملحق المحول
تحويل المستندات إلى 24 تنسيقًا مستهدفًا
ملحق المحول يحول Doconut إلى خدمة تحويل المستندات. يساهم في المحرك وراء الواجهة العامة DocumentConverter، و— عند الاختيار— عنصر واجهة مستخدم جاهز مع عقد HTTP الخاص به، بحيث يمكنك تحويل المستندات من C#، أو من العنصر، أو من واجهة أمامية تقوم بكتابتها بنفسك.
تثبيت الحزمة
قم بتثبيت أحدث ملحق محول ثابت:
dotnet add package Doconut.NET8.Converterلتثبيت الملحق على الإصدار الحالي 26.7.0، مرّر الإصدار بشكل منفصل:
dotnet add package Doconut.NET8.Converter --version 26.7.0احتفظ بحزمة المحول بنفس نسخة Doconut.NET8. معرف الحزمة هو
Doconut.NET8.Converter؛ يظهر .26.7.0 فقط في اسم ملف .nupkg الذي تم تنزيله.
تسجيل الملحق
لا توجد طريقة AddConverter() — نموذج ملحقات Doconut موحد. كل ملحق، بما في ذلك المحول، يُسجل بنفس الطريقة: استدعِ AddPlugin<TPlugin>() داخل AddDoconut(). ConverterPlugin يأتي في حزمة NuGet الخاصة به، Doconut.NET8.Converter، مثبتًا جنبًا إلى جنب مع حزمة العارض الأساسية.
builder.Services.AddDoconut(options =>
{
options.LicensePath = "Doconut.Viewer.lic";
options.AddPlugin<Doconut.Plugins.Converter.ConverterPlugin>();
});هذا الاستدعاء يرمي استثناءً عند بدء التشغيل في حالة عدم وجود ترخيص، أو ملف
TRIALقديم، أو ترخيص غير مؤقت لا يمنح قدرةConverter— وهوInvalidOperationExceptionيُرفع من داخلAddDoconut()، قبل أن يبدأ التطبيق في خدمة الطلبات. تُقبل تسجيلات Demo/NFR المؤقتة؛ بعد انتهاء صلاحيتها، يظل التحويل متاحًا مع مخرجات مائية. لا توجد طبقة مجانية صامتة. راجع إعداد الترخيص لمعرفة كيفية تحميل التراخيص.
التحويل من C#
كل عملية تحويل تُعيد MemoryStream قابل للبحث ومُحدد على الموضع 0، جاهز للقراءة أو النسخ فورًا. احصل على DocumentConverter من DI أينما احتجت إليه — فهو بلا حالة حسب التصميم، لذا يمكن إعادة استخدام نسخة واحدة بأمان عبر الطلبات.
// Inject DocumentConverter; its constructor is internal, so never `new` it.
Stream pdf = await converter.ConvertAsync("contract.docx", ConversionTarget.Pdf, ct: ct);// sourceExtension includes the leading dot. password is null unless the document is protected.
Stream png = await converter.ConvertAsync(upload, ".xlsx", ConversionTarget.Png, password: null, ct: ct);Stream html = await converter.WordToHtmlAsync("report.docx", ct);Stream docx = await converter.HtmlToWordAsync(html, ConversionTarget.Docx, ct);تفصيلان سهلان الوقوع في الخطأ: يجب أن يتضمن sourceExtension في نسخة الدفق النقطة الأولية (".xlsx" وليس "xlsx" ) — حيث يطابق المحول ذلك مع كتالوج الصيغ ولن تُحل الامتداد بدون نقطة. وعلى الرغم من اسمه، فإن WordToHtmlAsync يُعيد Task<Stream> وليس Task<string> — تحصل على مستند HTML (الصور مدمجة كـ Base64) كدفق، كما هو الحال مع كل نتيجة تحويل أخرى.
صيغ الهدف
Pdf, Docx, Doc, Html, Xlsx, Pptx, Png, Jpeg, Csv, Tiff, Bmp, Gif, Svg, Xml,
Txt, Xls, Jp2, Rtf, Odt, Ods, Odp, Epub, Xps, Webpليس كل مصدر يُحوَّل إلى كل هدف — يقوم الملحق بربط عائلة صيغ كل مصدر (Word، Excel، PowerPoint، PDF، CAD، Image، Email، Diagram، Project/Task، PSD، مستند ويب) بمجموعة ثابتة من الأهداف المسموح بها. لا تُثبت هذا التعداد صلبًا كقائمة أهداف لواجهة المستخدم الخاصة بك: ?convert=open يُعيد allowedTargets الفعلية لأي ملف تم رفعه للتو، وهذا ما يجب أن يُدير أداة الاختيار.
عنصر واجهة المستخدم الجاهز
نقاط النهاية ?convert=open|run|download للعنصر هي اختيارية ومُعطَّلة بشكل افتراضي — آمنة بشكل افتراضي. فعّلها من جانب الخادم، جنبًا إلى جنب مع تسجيل الملحق:
builder.Services.AddDoconut(options =>
{
options.LicensePath = "Doconut.Viewer.lic";
options.AddPlugin<Doconut.Plugins.Converter.ConverterPlugin>();
options.AddConverterWidget(widget =>
{
widget.MaxUploadMb = 25;
});
});<div id="doconut-convert"></div>
<script src="/doconut-res/js/doconutConverter.js"></script>
<script>
Doconut.convert('#doconut-convert', { basePath: '/doconut', resPath: '/doconut-res', maxUploadMb: 25 });
</script>بدون AddConverterWidget()، تُجيب النقاط الثلاث ?convert= بـ 404 — لكن ملف الـ JS نفسه لا يزال يُقدم على أي حال (إنه مورد ثابت مضمّن بسيط؛ فقط نقاط النهاية التي يتواصل معها هي المحجوبة). لا يزال AddConverterWidget() يتطلب تسجيل ملحق المحول وترخيص يمنح Converter — فهو لا يمنح حقوق التحويل بمفرده.
تخصيص العنصر
خيارات التهيئة التي تُمرَّر إلى Doconut.convert(selector, options):
| الخيــار | الـنـوع | الافتراضي | ملاحظات |
|---|---|---|---|
basePath | string | /doconut | المسار الأساسي لنقاط النهاية ?convert=؛ يجب أن يتطابق مع فرع ASP.NET حيث يتم تثبيت UseDoconut() فعليًا (عادةً يتم تنسيق ذلك عبر MiddlewarePath). |
resPath | string | /doconut-res | مقبول لتوافق الإعداد مع عناصر Doconut الأخرى؛ عنصر المحول لا يُنشئ أي عنوان URL منه حاليًا. |
maxUploadMb | number | 25 | تحقق مسبق من جانب العميل فقط — يرفض ملفًا كبيرًا جدًا قبل الرفع. يفرض الخادم حدًا خاصًا به بشكل مستقل ويُجيب بـ 413 إذا تم تجاوز الحد. |
licenseUrl | string | null | null | عند التعيين، يحول إشعار العلامة المائية على شاشة النتيجة إلى رابط لهذا العنوان URL. |
labels | object | {} | يتجاوز أي جزء من سلاسل النص الإنجليزية الافتراضية للعنصر (نص السقوط، الأزرار، إعلانات aria-live، رسائل الخطأ). |
الاستدعاءات:
| الاستدعاء | يُطلق عندما | الحمولة |
|---|---|---|
onReady() | الواجهة قد عرضت شاشة الخمول/السقوط | — |
onSourceLoaded({ token, pages, sourceExt, allowedTargets }) | نجاح ?convert=open | رمز جلسة المصدر، عدد الصفحات، امتداد المصدر (بدون نقطة أولية)، قائمة الأهداف المسموح بها |
onConverted({ downloadToken, resultToken, resultPages, downloadName, watermarked, target }) | نجاح ?convert=run | نفس الحقول كما في استجابة التشغيل، بالإضافة إلى target المطلوب |
onDownload({ downloadName, downloadToken }) | النقر من قبل المستخدم على رابط التحميل | يُطلق جنبًا إلى جنب مع تحميل المتصفح الأصلي — لا يعترض أو يستبدله |
onError({ phase, message }) | فشل طلب فتح أو تشغيل | phase إما 'open' أو 'run'؛ message هي رسالة الخطأ المُنقاة من الخادم (أو رسالة من جانب العميل للتحقق المسبق من حجم الرفع). |
Doconut.convert() يُعيد نسخة العنصر نفسها — احتفظ بها لتوجيه العنصر برمجيًا:
const conv = Doconut.convert('#doconut-convert', { basePath: '/doconut' });
conv.reset(); // back to the idle/drop screen; does not re-fire onReady
conv.loadFile(file); // starts the flow with a File object; no-op unless currently idle
conv.destroy(); // removes listeners, empties the mount; the instance is unusable after thisبناء الواجهة الأمامية الخاصة بك
العنصر هو مجرد عميل لهذا العقد HTTP — ابنِ واجهتك الأمامية الخاصة مباشرةً ضده لتجربة مستخدم مختلفة. جميع المسارات الثلاثة تقع تحت فرع ASP.NET حيث يتم تثبيت UseDoconut() (عادةً /doconut):
| المسار | الغرض | استجابة النجاح |
|---|---|---|
POST ?convert=open (multipart, الحقل file) | رفع وفتح مستند مصدر للمعاينة | 200 — { token, pages, sourceExt, allowedTargets } |
POST ?token=<token>&convert=run&target=<ext> | تحويل المصدر المخزن إلى target | 200 — { downloadToken, resultToken, resultPages, downloadName, watermarked } |
GET ?convert=download&token=<downloadToken> | تدفق الملف المحول | 200 — file bytes, Content-Disposition: attachment, Cache-Control: no-store |
يتم تخزين بايتات المصدر المرفوعة على الخادم مع TTL قدره 30 دقيقة؛ بمجرد انتهاء هذه الفترة، تُجيب run بـ 404 ويجب إعادة فتح الملف. النتيجة المحولة تُحفظ في نفس التخزين — يحصل downloadToken على نافذة جديدة مدتها 30 دقيقة عند اكتمال التحويل — بينما resultToken هو رمز جلسة عارض عادي يتبع عمر جلسة العارض، مستقلًا عن التخزين.
sourceExt في استجابة open لا يحتوي على نقطة أولية (مثال: "docx") — وهو عكس الاتفاقية في معامل sourceExtension على DocumentConverter.ConvertAsync الذي يتطلب وجود نقطة.
أوضاع الفشل، مُجمَّعة حسب المسار
| المسار | الحالة | متى | المحتوى |
|---|---|---|---|
| any | 404 | العنصر غير مفعَّل (AddConverterWidget() لم يُستدعَ أبداً) — يتم التحقق قبل توجيه أي من المسارات الثلاثة | الحالة فقط |
| any | 405 | طريقة HTTP غير صحيحة (open/run تتطلب POST؛ download تتطلب GET) | الحالة فقط |
open | 413 | الملف المرفوع يتجاوز MaxUploadMb | { "error": "الملف كبير جدًا." } |
open | 400 | لا يوجد جسم multipart، أو لا ملف، أو امتداد مصدر لا يمكن تحويله | { "error": "..." } |
run | 400 | رمز غير صالح (ليس GUID)، أو target لا يمكن تحليله إلى ConversionTarget | { "error": "الرمز غير صالح." } / { "error": "صيغة الهدف غير معروفة." } |
run | 400 | target غير موجود في allowedTargets للمصدر | { "error": "صيغة الهدف هذه غير متاحة لهذا الملف." } |
run | 404 | انتهاء صلاحية الرفع المخزن (TTL 30 دقيقة) أو لم يتم فتح الرمز أبداً | { "error": "انتهت صلاحية الرفع — يرجى إعادة فتح الملف." } |
open, run | 500 | فشل المعالجة داخليًا | { "error": "<sanitized message>" } — تم تنقيحه بنفس طريقة كل مسار خطأ آخر في Doconut؛ لا يُسرب أسماء المحرك الداخلية |
download | 400 | رمز غير صالح (ليس GUID) | الحالة فقط |
download | 404 | رمز تحميل غير معروف أو منتهي الصلاحية | الحالة فقط |
ملكية الموارد
المحول يُعيد MemoryStream قابل للبحث ومُحدد على الصفر. المتصل يملك هذا الدفق ويجب أن يُفرغ (dispose) بعد النسخ أو إرجاع محتوياته. خدمة DocumentConverter نفسها بلا حالة وتُستخرج من حقن الاعتماديات؛ لا تقم بإنشاء الخدمة أو إفراغها يدويًا.
بالنسبة لعنصر الويب، فإن مخازن الرفع والتحميل لها TTL مستقل مدته 30 دقيقة. resultToken للعارض يتبع عمر جلسة العارض بدلاً من ذلك. إغلاق نتيجة العارض لا يحذف مخزن التحميل الذي لا يزال صالحًا، وإعادة ضبط عنصر المتصفح لا يمدد أيًا من TTL.
استكشاف الأخطاء وإصلاحها
| العَرَض | التحقق |
|---|---|
فشل في حل DocumentConverter | تم تسجيل ConverterPlugin داخل AddDoconut() |
| فشل التطبيق أثناء بدء التشغيل | الترخيص المحمَّل يمنح Converter |
| تحويل الدفق يُظهر أن الصيغة غير مدعومة | sourceExtension يتضمن النقطة الأولية |
| جافاسكريبت العنصر يُحمَّل لكن الطلبات تُعيد 404 | AddConverterWidget() لم يُستدعَ |
| طلبات العنصر تستخدم عنوان URL خاطئ | basePath يتطابق مع الفرع حيث تم تعيين UseDoconut() |
| الهدف مفقود | استخدم allowedTargets التي تُعيدها convert=open؛ ليس كل مصدر يدعم كل هدف من تعداد الـ enum |
| انتهاء صلاحية التحميل | أعد تنفيذ convert=open/convert=run؛ رموز التخزين مؤقتة عن قصد |
العلامة المائية
مع تسجيل ConverterPlugin، يكون ترخيص المضيف في إحدى ثلاث حالات:
| حالة الترخيص | بوابة بدء التشغيل | مخرجات التحويل |
|---|---|---|
ترخيص عارض مدفوع يمنح Converter، ضمن فترة صلاحيته | ينجح | نظيف — watermarked: false |
| ترخيص تقييم نشط (demo/NFR) | ينجح | يتم التحويل بنجاح، مع علامة مائية للتقييم — watermarked: true |
بدون ترخيص، أو ملف TRIAL قديم، أو ترخيص غير مؤقت لا يمنح Converter | التطبيق لا يبدأ أبداً — بوابة بدء التشغيل الموصوفة أعلاه تُرمى استثناء | — |
| ترخيص مؤقت/تجريبي منتهي الصلاحية | التسجيل يبقى بعد الانتهاء | يتم التحويل مع علامة مائية للتقييم — watermarked: true |
كلا مساري الاستدعاء يحسبان العلامة وفقًا للقاعدة نفسها: الواجهة C# لـ DocumentConverter تستخلصها داخليًا من حالة الترخيص IsViewerLicensed و IsTemporary، ومُعالج العنصر ?convert=run يجري الفحص المكافئ (IsViewerLicensed && !IsTrial && !IsTemporary) لملء حقل watermarked الذي يُعيده. يمكن بناء تكامل واختباره من الطرف إلى الطرف باستخدام ترخيص تقييم قبل الشراء — فقط بايتات المخرجات تتغير.
هل كانت هذه الصفحة مفيدة؟