پلاگین مبدل

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

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

نصب بسته

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

bash
dotnet add package Doconut.NET6.Converter

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

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

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

ثبت پلاگین

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

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

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

تبدیل از 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، وب‌سند) را به مجموعهٔ ثابت هدف‌های مجاز خود نگاشت می‌کند. این 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)

فراخوانیزمان اجرابار
onReady()ویجت صفحهٔ بیکار/رها را رندر کرده است
onSourceLoaded({ token, pages, sourceExt, allowedTargets })موفقیت ?convert=openتوکن جلسه منبع، تعداد صفحات، پسوند منبع (بدون نقطه)، لیست هدف‌های مجاز
onConverted({ downloadToken, resultToken, resultPages, downloadName, watermarked, target })موفقیت ?convert=runهمان فیلدهای پاسخ اجرا، به‌علاوهٔ target درخواست‌شده
onDownload({ downloadName, downloadToken })کاربر روی لینک دانلود کلیک می‌کندهمراه با دانلود بومی مرورگر اجرا می‌شود — جایگزین یا مداخله‌ای در آن ندارد
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();       // لیسنرها را حذف می‌کند، mount را خالی می‌کند؛ پس از این نمونه غیرقابل استفاده است

ساخت رابط کاربری خود

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

مسیرهدفپاسخ موفقیت
POST ?convert=open (multipart, فیلد 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 که نیاز به نقطه دارد.

حالت‌های خطا (Failure modes) بر حسب مسیر

مسیروضعیتزمانبدنه
هرکدام404ویجت فعال نیست (AddConverterWidget() صدا زده نشده) — قبل از پردازش هر یک از مسیرها بررسی می‌شودفقط وضعیت
هرکدام405روش HTTP نادرست (open/run نیاز به POST دارند؛ download نیاز به GET دارد)فقط وضعیت
open413فایل بارگذاری‌شده بزرگ‌تر از MaxUploadMb است{ "error": "File is too large." }
open400بدنهٔ multipart موجود نیست، فایلی وجود ندارد، یا پسوند منبعی که قابل تبدیل نیست{ "error": "..." }
run400توکن نامعتبر (نه GUID) یا target که به ConversionTarget تبدیل نمی‌شود{ "error": "Invalid token." } / { "error": "Unknown target format." }
run400target در allowedTargets منبع وجود ندارد{ "error": "That target format is not available for this file." }
run404مخزن بارگذاری منقضی شده (TTL ۳۰ دقیقه) یا توکن هرگز باز نشده{ "error": "Upload expired — please re-open the file." }
open, run500پردازش داخلی با خطا مواجه شد{ "error": "<sanitized message>" } — همانند سایر مسیرهای خطای Doconut پاک‌سازی می‌شود؛ نام‌های داخلی موتور در معرض نمایش قرار نمی‌گیرد
download400توکن نامعتبر (نه GUID)فقط وضعیت
download404توکن دانلود ناشناخته یا منقضی شدهفقط وضعیت

مالکیت منابع

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

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

عیب‌یابی

علامتبررسی
دریافت 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 را اعطا نمی‌کندبرنامه هرگز شروع نمی‌شود — دروازهٔ راه‌اندازی بالا استثنا می‌اندازد
لایسنس موقت/Demo منقضی‌شدهثبت‌نام پس از انقضا باقی می‌ماندبا واترمارک ارزیابی تبدیل می‌شود — watermarked: true

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

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