ملحق المحول
تحويل المستندات إلى 45 تنسيقًا مستهدفًا
يحوِّل ملحق Converter Doconut إلى خدمة تحويل المستندات. يساهم بالمحرك وراء الواجهة العامة DocumentConverter، و— عند الاختيار — أداة قابلة للإدراج مع عقد HTTP الخاص بها، بحيث يمكنك تحويل المستندات من C#، أو من الأداة، أو من الواجهة الأمامية التي تكتبها بنفسك.
تثبيت الحزمة
قم بتثبيت أحدث ملحق Converter ثابت:
dotnet add package Doconut.NETStandard.Converterلتثبيت الملحق على إصدار 26.8.0 الحالي، مرّر الإصدار بشكل منفصل:
dotnet add package Doconut.NETStandard.Converter --version 26.8.0احفظ حزمة Converter بنفس الإصدار مثل Doconut.NETStandard. معرف الحزمة هو
Doconut.NETStandard.Converter؛ .26.8.0 يظهر فقط في اسم الملف .nupkg الذي تم تنزيله.
تسجيل الملحق
لا توجد طريقة AddConverter() — نموذج ملحقات Doconut موحد. كل ملحق، بما في ذلك Converter، يُسجَّل بنفس الطريقة: استدعِ AddPlugin<TPlugin>() داخل AddDoconut(). ConverterPlugin يُوزَّع في حزمة NuGet الخاصة به، Doconut.NETStandard.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 أينما احتجته — فهو بلا حالة حسب التصميم، لذا يمكن إعادة استخدام نسخة واحدة بأمان عبر الطلبات.
viewer.Converter.GetConverter() غير موجود هنا. لم يعد الوصول إلى التحويل عبر نسخة المشاهد: قم بحقن Doconut.DocumentConverter بدلاً من ذلك.
// حقن DocumentConverter؛ مُنشئه داخلي، لذا لا تقم أبداً بـ `new` له.
Stream pdf = await converter.ConvertAsync("contract.docx", ConversionTarget.Pdf, ct: ct);// sourceExtension يتضمن النقطة الأولية. password هو null ما لم يكن المستند محمياً.
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) كمجرى، وهو نفس نتيجة كل تحويل آخر.
صيغ الهدف
ConversionTarget (المساحة الاسمية Doconut.Configs.Conversion) تحتوي على 45 عضوًا:
Pdf, Docx, Doc, Html, Xlsx, Pptx, Png, Jpeg, Csv, Tiff, Bmp, Gif, Svg, Xml,
Txt, Xls, Jp2, Rtf, Odt, Ods, Odp, Epub, Xps, Webp, Msg, Eml, Emlx, Mhtml,
Xlsm, Xlsb, Ppt, Docm, Dot, Dotx, Dotm, Vsdx, Vssx, Vstx, Vsdm, Vssm, Vstm,
Vdx, Vsx, Vtx, Icoهذا التعداد يغطي كل عائلة مصدر. المكتبة السابقة كان لديها نوع *ConfigConverter لكل عائلة — WordConfigConverter، ExcelConfigConverter، وهكذا — كل منها يحتوي على تعداد EnTargetFormat المتداخل الخاص به، بالإضافة إلى تعداد SourceFormatConverter للمدخل. جميعها اختفت؛ راجع دليل الترحيل.
ليس كل مصدر يتحول إلى كل هدف — يقوم الملحق بربط كل عائلة صيغ المصدر (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 وإصدار رخصة يمنح 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 | عند التفعيل، يحول إشعار العلامة المائية على شاشة النتيجة إلى رابط لهذا العنوان |
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(); // العودة إلى شاشة الخمول/الإسقاط؛ لا يعيد تشغيل onReady
conv.loadFile(file); // يبدأ التدفق باستخدام كائن File؛ لا عملية إلا إذا كان النظام حاليًا في حالة idle
conv.destroy(); // يزيل المستمعين، يفرغ الـ mount؛ لا يمكن استخدام المثيل بعد ذلكبناء الواجهة الأمامية الخاصة بك
الأداة مجرد عميل لهذا العقد HTTP — قم ببناء واجهة أمامية خاصة بك مباشرةً للحصول على تجربة مستخدم مختلفة. جميع المسارات الثلاثة تقع تحت فرع ASP.NET حيث يتم تثبيت UseDoconut() (عادةً /doconut):
| المسار | الغرض | استجابة النجاح |
|---|---|---|
POST ?convert=open (متعدد الأجزاء، الحقل 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 — بايتات الملف، Content-Disposition: attachment، Cache-Control: no-store |
يتم تخزين بايتات المصدر المرفوعة على الخادم مع عمر افتراضي 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": "File is too large." } |
open | 400 | لا يوجد جسم متعدد الأجزاء، لا ملف، أو امتداد مصدر لا يمكن تحويله | { "error": "..." } |
run | 400 | رمز مكوَّن بشكل غير صحيح (ليس GUID)، أو target لا يمكن تحليله إلى ConversionTarget | { "error": "Invalid token." } / { "error": "Unknown target format." } |
run | 400 | target غير موجود في allowedTargets المصدر | { "error": "That target format is not available for this file." } |
run | 404 | انتهت صلاحية الرفع المخزن (TTL 30 دقيقة) أو لم يُفتح الرمز أبداً | { "error": "Upload expired — please re-open the file." } |
open, run | 500 | فشل المعالجة داخليًا | { "error": "<sanitized message>" } — منقح بنفس طريقة كل مسار خطأ آخر لـ Doconut؛ لا يكشف عن أسماء المحركات الداخلية |
download | 400 | رمز مكوَّن بشكل غير صحيح (ليس GUID) | الحالة فقط |
download | 404 | رمز تحميل غير معروف أو منتهي الصلاحية | الحالة فقط |
ملكية المورد
يعيد المحول كائن MemoryStream قابل للتمرير موضعه عند الصفر. يمتلك المتصل ذلك التدفق ويجب عليه تحريره بعد النسخ أو إرجاع محتوياته. خدمة DocumentConverter نفسها لا تحتفظ بحالة ويتم حلها عبر حقن الاعتماديات؛ لا تقم بإنشاء الخدمة أو تحريرها يدويًا.
بالنسبة لأداة الويب، فإن مخازن الرفع والتحميل لها فترات صلاحية مستقلة تبلغ 30 دقيقة. يتبع عارض resultToken بدلاً من ذلك عمر جلسة العارض. إغلاق نتيجة العارض لا يحذف مخزن التحميل الذي لا يزال صالحًا، وإعادة ضبط أداة المتصفح لا يمدد أيًا من فترات الصلاحية.
استكشاف الأخطاء وإصلاحها
| العَرْض | التحقق |
|---|---|
فشل حل DocumentConverter | تم تسجيل ConverterPlugin داخل AddDoconut() |
| فشل التطبيق أثناء بدء التشغيل | الرخصة المحملة تمنح Converter |
| تحويل التدفق يقول إن الصيغة غير مدعومة | يتضمن sourceExtension النقطة الأولية |
| يتم تحميل جافا سكريبت الواجهة لكن الطلبات تُعيد 404 | لم يتم استدعاء AddConverterWidget() |
| طلبات الواجهة تستخدم عنوان URL خاطئ | يتطابق basePath مع الفرع حيث يتم تعيين UseDoconut() |
| الهدف مفقود | استخدم allowedTargets الذي أرجعه convert=open؛ ليس كل مصدر يدعم كل هدف تعداد |
| انتهت صلاحية التحميل | كرر convert=open/convert=run؛ رموز المخزن مؤقتة عن قصد |
وضع العلامة المائية
مع تسجيل ConverterPlugin، تكون رخصة المضيف في واحدة من ثلاث حالات:
| حالة الرخصة | بوابة بدء التشغيل | ناتج التحويل |
|---|---|---|
رخصة عارض مدفوعة تمنح Converter، ضمن فترة صلاحيتها | تنجح | نظيفة — watermarked: false |
| رخصة تقييم نشطة (تجريبية/غير طلب دفع) | تنجح | تحول بنجاح، مختومة بعلامة التقييم المائية — watermarked: true |
بدون رخصة، ملف TRIAL قديم، أو رخصة غير مؤقتة لا تمنح Converter | التطبيق لا يبدأ أبدًا — بوابة بدء التشغيل المذكورة أعلاه تُطلق استثناء | — |
| رخصة مؤقتة/تجريبية منتهية | التسجيل يبقى بعد الانتهاء | تحول مع علامة التقييم المائية — watermarked: true |
كلا مساري الاستدعاء يحسبان العلامة وفقًا للقاعدة نفسها: الواجهة DocumentConverter بلغة C# تستخلصها داخليًا من حالة IsViewerLicensed وIsTemporary للرخصة، ومعالج ?convert=run للواجهة يقوم بالتحقق المكافئ (IsViewerLicensed && !IsTrial && !IsTemporary) لملء الحقل watermarked الذي يُرجعه. يمكن بناء واختبار تكامل من الطرف إلى الطرف على رخصة تقييم قبل الشراء — فقط بايتات الناتج تتغير.
هل كانت هذه الصفحة مفيدة؟