ملحق التحويل
تحويل المستندات إلى 24 تنسيقًا مستهدفًا
يقوم ملحق Converter بتحويل Doconut إلى خدمة تحويل المستندات. يساهم في المحرك وراء الواجهة العامة DocumentConverter، و— عند الاختيار— واجهة قابلة للإضافة مع عقد HTTP خاص بها، بحيث يمكنك تحويل المستندات من C#، أو من الواجهة، أو من واجهة أمامية تقوم بكتابتها بنفسك.
تثبيت الحزمة
قم بتثبيت أحدث نسخة مستقرة من ملحق Converter:
dotnet add package Doconut.NET6.Converterلتثبيت الملحق على الإصدار الحالي 26.7.0، مرّر الإصدار بشكل منفصل:
dotnet add package Doconut.NET6.Converter --version 26.7.0احتفظ بحزمة Converter بنفس نسخة Doconut.NET6. معرف الحزمة هو Doconut.NET6.Converter؛ يظهر .26.7.0 فقط في اسم ملف .nupkg الذي تم تنزيله.
تسجيل الملحق
لا توجد طريقة AddConverter() — نموذج ملحقات Doconut موحد. كل ملحق، بما في ذلك Converter، يُسجَّل بنفس الطريقة: استدعِ AddPlugin<TPlugin>() داخل AddDoconut().
ConverterPlugin يأتي في حزمة NuGet خاصة به، Doconut.NET6.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 وترخيص يمنح صلاحية 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, field 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() لم يُستدعَ أبدًا) — يتم التحقق قبل أي من المسارات الثلاثة | status only |
| any | 405 | طريقة HTTP غير صحيحة (open/run تتطلب POST؛ download يتطلب GET) | status only |
open | 413 | الملف المرفوع يتجاوز MaxUploadMb | { "error": "File is too large." } |
open | 400 | لا يوجد جسم multipart، أو لا ملف، أو امتداد مصدر لا يمكن تحويله | { "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) | status only |
download | 404 | رمز تحميل غير معروف أو منتهي الصلاحية | status only |
ملكية المورد
المحول يُعيد MemoryStream قابل للبحث ومُحدد على الموضع صفر. المتصل يملك ذلك الدفق ويجب أن يُفرغّه بعد النسخ أو إرجاع محتوياته. خدمة DocumentConverter نفسها لا تحمل حالة وتُستخرج من حقن الاعتماديات؛ لا تُنشئ أو تُفرغ الخدمة يدويًا.
بالنسبة لواجهة الويب، فإن مخازن الرفع والتحميل لها TTL مستقل مدته 30 دقيقة. رمز عارض resultToken يتبع عمر جلسة العارض بدلاً من ذلك. إغلاق نتيجة عارض لا يحذف مخزن تحميل لا يزال صالحًا، وإعادة ضبط واجهة المتصفح لا تُطيل أيًا من الـ TTLs.
استكشاف الأخطاء وإصلاحها
| العَرَض | التحقق |
|---|---|
فشل حل DocumentConverter | تم تسجيل ConverterPlugin داخل AddDoconut() |
| فشل التطبيق أثناء بدء التشغيل | الترخيص المحمَّل يمنح صلاحية Converter |
| تحويل الدفق يقول إن الصيغة غير مدعومة | sourceExtension يتضمن النقطة الأولية |
| تحميل JavaScript للواجهة لكن الطلبات تُعيد 404 | لم يتم استدعاء AddConverterWidget() |
| طلبات الواجهة تستخدم عنوان URL خاطئ | basePath يتطابق مع الفرع حيث يتم تعيين UseDoconut() |
| الهدف مفقود | استخدم allowedTargets التي تُعيدها convert=open؛ ليس كل مصدر يدعم كل هدف من تعداد الصيغ |
| انتهت صلاحية التحميل | كرر 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 الذي يُعيده. يمكن بناء واختبار تكامل من الطرف إلى الطرف على ترخيص تقييم قبل الشراء — فقط بايتات المخرجات هي التي تتغير.
هل كانت هذه الصفحة مفيدة؟