ملحق التحويل
تحويل المستندات إلى 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 أينما احتجت إليه — فهو لا يحمل حالة حسب التصميم، لذا يمكن إعادة استخدام نسخة واحدة بأمان عبر الطلبات.
// قم بحقن 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) كمجرى، وهو نفس نتيجة كل تحويل آخر.
صيغ الهدف
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(); // العودة إلى شاشة الخمول/الإسقاط؛ لا يعيد تشغيل onReady
conv.loadFile(file); // يبدأ التدفق باستخدام كائن File؛ لا يفعل شيئًا إلا إذا كان في حالة الخمول
conv.destroy(); // يزيل المستمعين، يفرغ الـ mount؛ يصبح الكائن غير قابل للاستخدام بعد ذلكبناء واجهة أمامية خاصة بك
الأداة مجرد عميل لهذا العقد 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") — وهو عكس convention المعامل sourceExtension على DocumentConverter.ConvertAsync، الذي يتطلب واحدة.
أنماط الفشل، مجمعة حسب المسار:
| المسار | الحالة | متى | المحتوى |
|---|---|---|---|
| أي | 404 | الأداة غير مفعلة (لم يتم استدعاء AddConverterWidget() أبداً) — يتم التحقق قبل إرسال أي من المسارات الثلاثة | الحالة فقط |
| أي | 405 | طريقة HTTP غير صحيحة (يتطلب open/run POST؛ يتطلب download GET) | الحالة فقط |
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) | الحالة فقط |
download | 404 | رمز تنزيل غير معروف أو منتهي الصلاحية | الحالة فقط |
ملكية المورد
يعيد المحول كائن MemoryStream قابل للتمرير موضعه عند الصفر. يمتلك المستدعي ذلك التدفق ويجب أن يفرغه بعد النسخ أو إرجاع محتوياته. خدمة DocumentConverter نفسها لا تحتفظ بحالة ويتم حلها عبر حقن الاعتماديات؛ لا تقم بإنشاء الخدمة أو تحريرها يدويًا.
بالنسبة لأداة الويب، فإن مخازن الرفع والتحميل لديها أوقات بقاء (TTL) مستقلة مدتها 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 الذي يُرجعه. يمكن بناء واختبار تكامل من الطرف إلى الطرف على ترخيص تقييم قبل الشراء — فقط بايتات الناتج تتغير.
هل كانت هذه الصفحة مفيدة؟