پلاگین مبدل

سندها را به ۲۴ فرمت هدف تبدیل کنید

پلاگین Converter Doconut را به یک سرویس تبدیل سند تبدیل می‌کند. این پلاگین موتور پشت رابط عمومی DocumentConverter را فراهم می‌کند و — به صورت اختیاری — یک ویجت آماده با قرارداد HTTP خود دارد، به طوری که می‌توانید اسناد را از C#، از ویجت یا از یک فرانت‌اند که خودتان می‌نویسید، تبدیل کنید.

نصب بسته

پلاگین Converter آخرین نسخه پایدار را نصب کنید:

bash
dotnet add package Doconut.NET8.Converter

برای قفل کردن پلاگین به نسخه فعلی ۲۶.۷.۰، نسخه را به‌صورت جداگانه پاس دهید:

bash
dotnet add package Doconut.NET8.Converter --version 26.7.0

پکیج Converter را هم‌نسخه با Doconut.NET8 نگه دارید. شناسه پکیج Doconut.NET8.Converter است؛ .26.7.0 فقط در نام فایل .nupkg دانلود شده ظاهر می‌شود.

ثبت پلاگین

متد AddConverter() وجود ندارد — مدل پلاگین Doconut یکسان است. هر پلاگین، از جمله Converter، به همان روش ثبت می‌شود: داخل AddDoconut()، AddPlugin<TPlugin>() را فراخوانی کنید. ConverterPlugin در بسته NuGet خود، Doconut.NET8.Converter، همراه با بسته پایهٔ ویور نصب می‌شود.

csharp
builder.Services.AddDoconut(options =>
{
    options.LicensePath = "Doconut.Viewer.lic";
    options.AddPlugin<Doconut.Plugins.Converter.ConverterPlugin>();
});

این فراخوانی در زمان راه‌اندازی به دلیل عدم وجود لایسنس، فایل قدیمی TRIAL یا لایسنس غیر موقت که قابلیت Converter را اعطا نمی‌کند، استثنای InvalidOperationException را از داخل AddDoconut() پرتاب می‌کند، پیش از این که برنامه درخواست‌ها را سرو کند. ثبت‌نام‌های موقت Demo/NFR پذیرفته می‌شوند؛ پس از انقضای تقویمی آن‌ها، تبدیل همچنان با خروجی دارای واترمارک در دسترس است. هیچ لایه رایگان ساکتی وجود ندارد. برای نحوه بارگذاری لایسنس‌ها به راه‌اندازی لایسنس مراجعه کنید.

تبدیل از C#

هر تبدیل یک MemoryStream قابل جستجو که در موقعیت ۰ قرار دارد برمی‌گرداند، آماده برای خواندن یا کپی فوری. DocumentConverter را از DI در هر جایی که به آن نیاز دارید دریافت کنید — این سرویس به‌صورت بی‌حالت (stateless) طراحی شده، بنابراین یک نمونهٔ واحد می‌تواند به‌صورت ایمن در میان درخواست‌ها مجدداً استفاده شود.

csharp
// Inject DocumentConverter; its constructor is internal, so never `new` it.
Stream pdf = await converter.ConvertAsync("contract.docx", ConversionTarget.Pdf, ct: ct);
csharp
// 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);
csharp
Stream html = await converter.WordToHtmlAsync("report.docx", ct);
csharp
Stream docx = await converter.HtmlToWordAsync(html, ConversionTarget.Docx, ct);

دو نکته‌ای که به‌راحتی می‌توان اشتباه کرد: sourceExtension در overload استریم باید نقطهٔ پیش‌رو را شامل شود (".xlsx" نه "xlsx" ) — مبدل آن را در کاتالوگ فرمت‌ها جستجو می‌کند و یک پسوند بدون نقطه حل نمی‌شود. و با وجود نامش، WordToHtmlAsync یک Task<Stream> برمی‌گرداند، نه Task<string> — شما سند HTML (تصاویر به‌صورت Base64 جاسازی شده) را به‌صورت استریم دریافت می‌کنید، همان‌طور که برای هر نتیجهٔ تبدیل دیگر نیز صادق است.

فرمت‌های هدف

text
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، web document) را به مجموعهٔ ثابت هدف‌های مجاز خود نگاشت می‌کند. این enum را به‌صورت ثابت در لیست هدف UI خود کد نکنید: ?convert=open لیست واقعی allowedTargets را برای فایلی که تازه بارگذاری شده است برمی‌گرداند و باید برای پر کردن انتخابگر استفاده شود.

ویجت آماده

نقطهٔ انتهایی ?convert=open|run|download ویجت به‌صورت اختیاری است و به‌طور پیش‌فرض غیرفعال است — به‌صورت پیش‌فرض امن. آنها را در سمت سرور، همراه با ثبت‌نام پلاگین، فعال کنید:

csharp
builder.Services.AddDoconut(options =>
{
    options.LicensePath = "Doconut.Viewer.lic";
    options.AddPlugin<Doconut.Plugins.Converter.ConverterPlugin>();
    options.AddConverterWidget(widget =>
    {
        widget.MaxUploadMb = 25;
    });
});
html
<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) پاس می‌شوند:

گزینهنوعپیش‌فرضتوضیحات
basePathstring/doconutمسیر پایه برای نقطهٔ انتهایی ?convert=؛ باید با شاخهٔ ASP.NET که UseDoconut() در آن سوار شده است مطابقت داشته باشد (معمولاً از طریق MiddlewarePath هماهنگ می‌شود)
resPathstring/doconut-resبرای سازگاری پیکربندی با سایر ویجت‌های Doconut پذیرفته می‌شود؛ ویجت مبدل در حال حاضر URL‌ای از این مقدار نمی‌سازد
maxUploadMbnumber25فقط پیش‌چک سمت کلاینت — قبل از بارگذاری فایل بزرگ‌تری را رد می‌کند. سرور به‌صورت مستقل سقف خود را اعمال می‌کند و در صورت تجاوز 413 برمی‌گرداند
licenseUrlstring | nullnullوقتی تنظیم شود، اعلان واترمارک روی صفحهٔ نتیجه را به یک لینک به این URL تبدیل می‌کند
labelsobject{}هر زیرمجموعه‌ای از رشته‌های پیش‌فرض انگلیسی ویجت (متن‌های جایگزین، دکمه‌ها، اعلان‌های aria‑live، پیام‌های خطا) را بازنویسی می‌کند

Callbacks:

Callbackزمان فراخوانیPayload
onReady()ویجت صفحهٔ بیکاری/دراپ خود را رندر کرده است
onSourceLoaded({ token, pages, sourceExt, allowedTargets })?convert=open موفق می‌شودتوکن جلسه منبع، تعداد صفحات، پسوند منبع (بدون نقطهٔ پیش‌رو)، لیست هدف‌های مجاز
onConverted({ downloadToken, resultToken, resultPages, downloadName, watermarked, target })?convert=run موفق می‌شودهمان فیلدهای پاسخ run، به‌علاوهٔ target درخواست‌شده
onDownload({ downloadName, downloadToken })کاربر روی لینک Download کلیک می‌کندهمراه با دانلود بومی مرورگر اجرا می‌شود — آن را بازنویسی یا جایگزین نمی‌کند
onError({ phase, message })درخواست open یا run با خطا مواجه می‌شودphase مقدار 'open' یا 'run' است؛ message پیام خطای سرور پاک‌سازی‌شده (یا پیام سمت کلاینت برای پیش‌چک حجم بارگذاری)

Doconut.convert() خود نمونهٔ ویجت را برمی‌گرداند — برای کنترل برنامه‌نویسی ویجت آن را نگه دارید:

javascript
const conv = Doconut.convert('#doconut-convert', { basePath: '/doconut' });
conv.reset();         // بازگشت به صفحهٔ بیکاری/دراپ؛ onReady دوباره فراخوانی نمی‌شود
conv.loadFile(file);  // جریان را با یک شیء File آغاز می‌کند؛ اگر در حالت بیکاری نباشد هیچ کاری نمی‌کند
conv.destroy();       // شنونده‌ها را حذف می‌کند، محل سوار شدن را خالی می‌کند؛ پس از این نمونه غیرقابل استفاده است

ساخت فرانت‌اند خودتان

ویجت فقط یک کلاینت برای این قرارداد HTTP است — به‌صورت مستقیم یک فرانت‌اند دیگر بر پایهٔ آن بسازید تا تجربه کاربری متفاوتی داشته باشید. هر سه مسیر زیر زیر شاخهٔ ASP.NET که UseDoconut() در آن سوار شده است (معمولاً /doconut) قرار دارند:

مسیرهدفپاسخ موفق
POST ?convert=open (multipart, field file)بارگذاری و باز کردن سند منبع برای پیش‌نمایش200{ token, pages, sourceExt, allowedTargets }
POST ?token=<token>&convert=run&target=<ext>تبدیل منبع ذخیره‌شده به target200{ downloadToken, resultToken, resultPages, downloadName, watermarked }
GET ?convert=download&token=<downloadToken>استریم فایل تبدیل‌شده200 — بایت‌های فایل، Content-Disposition: attachment، Cache-Control: no-store

بایت‌های منبع بارگذاری‌شده به‌صورت سروری با TTL ۳۰ دقیقه‌ای ذخیره می‌شوند؛ پس از پایان این بازه، run پاسخ 404 می‌دهد و فایل باید دوباره باز شود. نتیجهٔ تبدیل در همان مخزن باقی می‌ماند — downloadToken پس از تکمیل تبدیل پنجرهٔ تازهٔ ۳۰ دقیقه‌ای خود را دریافت می‌کند — در حالی که resultToken یک توکن جلسهٔ ویور معمولی است که طول عمر آن با کش جلسهٔ ویور مرتبط است، مستقل از مخزن.

sourceExt در پاسخ open نقطهٔ پیش‌رو ندارد (مثلاً "docx" ) — برعکس قرارداد sourceExtension در DocumentConverter.ConvertAsync که نیاز به نقطه دارد.

حالت‌های خطا، گروه‌بندی بر حسب مسیر

مسیروضعیتزمانبدنه
any404ویجت فعال نیست (AddConverterWidget() هرگز فراخوانی نشده) — قبل از هر یک از سه مسیر بررسی می‌شودفقط وضعیت
any405روش HTTP نادرست (open/run نیاز به POST دارند؛ download نیاز به GET دارد)فقط وضعیت
open413فایل بارگذاری‌شده بزرگ‌تر از MaxUploadMb است{ "error": "فایل بیش از حد بزرگ است." }
open400بدنه multipart وجود ندارد، فایل نیست، یا پسوند منبعی که قابل تبدیل نیست{ "error": "..." }
run400توکن خراب (نه GUID) یا target که به ConversionTarget تبدیل نمی‌شود{ "error": "توکن نامعتبر است." } / { "error": "فرمت هدف ناشناخته است." }
run400target در allowedTargets منبع وجود ندارد{ "error": "این فرمت هدف برای این فایل در دسترس نیست." }
run404بارگذاری ذخیره‌شده منقضی شده (TTL ۳۰ دقیقه) یا توکن هرگز باز نشده است{ "error": "بارگذاری منقضی شد — لطفاً فایل را دوباره باز کنید." }
open, run500پردازش به‌صورت داخلی با خطا مواجه شد{ "error": "<پیام پاک‌سازی‌شده>" } — همانند سایر مسیرهای خطای Doconut پاک‌سازی می‌شود؛ نام‌های داخلی موتور هرگز فاش نمی‌شوند
download400توکن خراب (نه GUID)فقط وضعیت
download404توکن دانلود نامشخص یا منقضی شدهفقط وضعیت

مالکیت منبع

مبدل یک MemoryStream قابل جستجو که در صفر موقعیت دارد برمی‌گرداند. فراخواننده مالک این استریم است و باید پس از کپی یا بازگرداندن محتوا آن را آزاد کند. سرویس DocumentConverter خود بی‌حالت است و از طریق تزریق وابستگی حل می‌شود؛ آن را به‌صورت دستی ساخت یا آزاد نکنید.

برای ویجت وب، مخازن بارگذاری و دانلود TTL مستقل ۳۰ دقیقه‌ای دارند. یک resultToken ویور طول عمر جلسهٔ ویور را دنبال می‌کند. بستن نتیجهٔ ویور مخزن دانلود هنوز معتبر را حذف نمی‌کند و بازنشانی ویجت مرورگر هیچ‌یک از TTLها را تمدید نمی‌کند.

عیب‌یابی

علامتبررسی
حل DocumentConverter شکست می‌خوردثبت‌نام ConverterPlugin داخل AddDoconut() انجام شده است
برنامه در زمان راه‌اندازی شکست می‌خوردلایسنس بارگذاری‌شده قابلیت Converter را اعطا می‌کند
تبدیل استریم می‌گوید فرمت پشتیبانی نمی‌شودsourceExtension شامل نقطهٔ پیش‌رو است
JavaScript ویجت بارگذاری می‌شود اما درخواست‌ها 404 می‌دهندAddConverterWidget() فراخوانی نشده است
درخواست‌های ویجت URL اشتباهی دارندbasePath با شاخه‌ای که UseDoconut() به آن نگاشت شده مطابقت داشته باشد
هدف موجود نیستاز allowedTargets برگردانده‌شده توسط convert=open استفاده کنید؛ همهٔ منابع هر هدف enum را پشتیبانی نمی‌کنند
دانلود منقضی شدهconvert=open/convert=run را دوباره انجام دهید؛ توکن‌های مخزن به‌صورت عمدی موقت هستند

واترمارک‌گذاری

با ثبت‌نام ConverterPlugin، لایسنس میزبان در یکی از سه وضعیت زیر است:

وضعیت لایسنسدروازهٔ راه‌اندازیخروجی تبدیل
لایسنس ویور پرداخت‌شده که Converter را اعطا می‌کند و در دوره اعتبار خود استعبور می‌کندپاک — watermarked: false
لایسنس ارزیابی فعال (demo/NFR)عبور می‌کندبه‌صورت موفقیت‌آمیز تبدیل می‌شود و با واترمارک ارزیابی مهر می‌شود — watermarked: true
بدون لایسنس، فایل TRIAL قدیمی، یا لایسنس غیر موقت که Converter را اعطا نمی‌کندبرنامه هرگز شروع نمی‌شود — دروازهٔ راه‌اندازی توضیح داده‌شده بالا استثنا می‌اندازد
لایسنس موقت/Demo منقضی‌شدهثبت‌نام پس از انقضا باقی می‌ماندبا واترمارک ارزیابی تبدیل می‌شود — watermarked: true

هر دو مسیر فراخوانی پرچم را بر پایهٔ همان قانون محاسبه می‌کنند: واسط C# DocumentConverter به‌صورت داخلی از وضعیت IsViewerLicensed و IsTemporary لایسنس استخراج می‌کند، و هندلر ?convert=run ویجت همان بررسی معادل (IsViewerLicensed && !IsTrial && !IsTemporary) را انجام می‌دهد تا فیلد watermarked را پر کند. یک یکپارچه‌سازی می‌تواند قبل از خرید بر روی لایسنس ارزیابی ساخته و به‌صورت سرتاسری تست شود — فقط بایت‌های خروجی تغییر می‌کنند.

آیا این صفحه مفید بود؟