افزونه مبدل
سندها را به ۲۴ فرمت هدف تبدیل کنید
افزونه مبدل Doconut را به یک سرویس تبدیل سند تبدیل میکند. این افزونه موتور پشت رابط عمومی DocumentConverter را فراهم میکند و — به صورت اختیاری — یک ویجت قابل گنجاندن که توسط DocImage.axd سرویس میشود، بنابراین میتوانید اسناد را از C#، از ویجت، یا از یک رابط کاربری که خودتان مینویسید، تبدیل کنید.
نصب بسته
Install-Package Doconut.NETFramework.Converterبسته مبدل را با همان نسخهای که Doconut.NETFramework دارد، نگه دارید.
ثبت افزونه
هر افزونه به همان روش ثبت میشود: AddPlugin<TPlugin>() در DoconutHost.Initialize.
Doconut.DoconutHost.Initialize(options =>
{
options.LicensePath = HostingEnvironment.MapPath("~/wwwroot/Doconut.Viewer.lic");
options.AddPlugin<Doconut.Plugins.Converter.ConverterPlugin>();
});اگر هیچ لایسنس فعال قابلیت
Converterرا ندهد — بدون لایسنس، فایل قدیمیTRIAL، یا لایسنس بدون این قابلیت —DoconutHost.InitializeازApplication_Startپرتاب میشود. در System.Web این به این معنی است که هر درخواست پاسخی خالی از نوع500میدهد، و دلیل آن فقط در لاگ رویدادهای ویندوز (منبع ASP.NET) موجود است. لایسنسهای موقت Demo/NFR پذیرفته میشوند. ببینید تنظیم لایسنس.
تبدیل از C#
هر تبدیل یک MemoryStream قابل جستجو که در موقعیت ۰ قرار دارد، برمیگرداند. DocumentConverter بیحالت است: آن را از DoconutHost.Services هر جایی که نیاز دارید دریافت کنید و آزادانه دوباره استفاده کنید.
// DocumentConverter را از DoconutHost.Services حل کنید؛ سازندهٔ آن داخلی است، بنابراین هرگز آن را `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 در overload استریم باید نقطه پیشوندی را شامل شود (".xlsx"، نه "xlsx")، در غیر این صورت حل نمیشود. و با وجود نامش، WordToHtmlAsync مقدار Task<Stream> را برمیگرداند، نه Task<string> — سند HTML (تصاویر به صورت Base64 جاسازی شده) به شکل یک استریم میآید، همانند هر نتیجهٔ دیگر.
در یک کنترلر MVC 5
عملکرد را به صورت ناهمزمان کنید و await تبدیل را:
[HttpPost]
public async Task<ActionResult> ToPdf(HttpPostedFileBase file)
{
var converter = Doconut.DoconutHost.Services.GetRequiredService<DocumentConverter>();
Stream pdf = await converter.ConvertAsync(
file.InputStream, Path.GetExtension(file.FileName), ConversionTarget.Pdf,
password: null, ct: Response.ClientDisconnectedToken);
return File(pdf, "application/pdf", Path.GetFileNameWithoutExtension(file.FileName) + ".pdf");
}در Web Forms: هرگز بر روی یک تبدیل مسدود نشوید
یک صفحه Web Forms در یک زمینهٔ درخواست تکنخی اجرا میشود. ConvertAsync پس از تکمیل بر روی همان زمینه ادامه مییابد، بنابراین صفحهای که به صورت همزمان منتظر آن باشد — .Result، .Wait()، .GetAwaiter().GetResult() — همان نخ مورد نیاز تبدیل را مسدود میکند. درخواست هرگز باز نمیگردد. مرورگر میچرخد، IIS هیچ لاگی ثبت نمیکند و بقیهٔ سایت به کار خود ادامه میدهد، بنابراین بهنظر میرسد که تبدیل بهصورت کند انجام میشود نه قفلگذاری.
صفحه را با Async="true" علامتگذاری کنید و تبدیل را بهعنوان یک کار ناهمزمان صفحه اجرا کنید:
<%@ Page Language="C#" Async="true" CodeBehind="Convert.aspx.cs" Inherits="MyApp.Convert" %>// Web Forms: دستور @Page نیاز به Async="true" دارد و تبدیل به عنوان یک کار ناهمزمان صفحه اجرا میشود.
// مسدود کردن آن به جای اینکه (.Result, .Wait(), .GetAwaiter().GetResult()) باعث قفلکردن درخواست میشود:
// هرگز برنمیگردد و هیچچیزی ثبت نمیشود.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack) return;
RegisterAsyncTask(new PageAsyncTask(async ct =>
{
var converter = Doconut.DoconutHost.Services.GetRequiredService<DocumentConverter>();
using (var pdf = await converter.ConvertAsync(
Server.MapPath("~/App_Data/contract.docx"), ConversionTarget.Pdf, ct: ct))
using (var ms = new MemoryStream())
{
if (pdf.CanSeek) pdf.Position = 0;
await pdf.CopyToAsync(ms);
Response.ContentType = "application/pdf";
Response.AddHeader("Content-Disposition", "attachment; filename=contract.pdf");
Response.BinaryWrite(ms.ToArray());
// Context، نه HttpContext.Current: پس از await ممکن است مورد دوم null باشد.
Context.ApplicationInstance.CompleteRequest();
}
}));
}بدون Async="true" در دستور @Page، RegisterAsyncTask بهصورت خاموش نادیده گرفته میشود. پس از یک await، از Context صفحه استفاده کنید؛ HttpContext.Current میتواند آنجا null باشد.
قالبهای هدف
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, PSD, web document) مجموعهای از اهداف مجاز خود را دارد. این enum را بهصورت ثابت در لیست هدف UI خود کد نکنید: ?convert=open مقدار allowedTargets را برای فایل بارگذاریشده برمیگرداند و این باید انتخابکننده را هدایت کند.
ویجت Drop‑in
نقطههای انتهایی ?convert=open|run|download ویجت توسط DocImage.axd ارائه میشوند و بهصورت پیشفرض غیرفعال هستند. آنها را در کنار ثبتنام افزونه فعال کنید:
Doconut.DoconutHost.Initialize(options =>
{
options.LicensePath = HostingEnvironment.MapPath("~/wwwroot/Doconut.Viewer.lic");
options.AddPlugin<Doconut.Plugins.Converter.ConverterPlugin>();
options.AddConverterWidget(widget =>
{
widget.MaxUploadMb = 25;
});
});
// System.Web کل بارگذاری را قبل از اینکه Doconut آن را ببیند میخواند: maxRequestLength (KB) را نگه دارید و
// maxAllowedContentLength (bytes) در Web.config بالای MaxUploadMb ویجت<div id="doconut-convert"></div>
<script src="/doconut-res/js/doconutConverter.js"></script>
<script>
Doconut.convert('#doconut-convert', { basePath: '/DocImage.axd', maxUploadMb: 25 });
</script>دو مورد برای بررسی وقتی ویجت بهدرستی کار نمیکند:
basePath: '/DocImage.axd'. پیشفرض ویجت،/doconut، نقطه انتهایی ASP.NET Core است. در این بسته، نقطههای انتهایی، هندلرDocImage.axdازWeb.configهستند.- اسکریپت و نقطههای انتهایی مستقل هستند. ماژول منبع
doconutConverter.jsرا سرو میکند صرفنظر از اینکه ویجت فعال باشد یا نه. بدونAddConverterWidget()، ویجت بارگذاری میشود، ناحیهی رهاسازی خود را میکشد و کاملاً صحیح به نظر میرسد — و اولین اقدام آن پاسخ میدهد404.
حدود بارگذاری
ASP.NET تمام بدنهٔ درخواست را پیش از اجرای DocImage.axd میخواند. بارگذاریای که بالای MaxUploadMb اما زیر محدودیتهای میزبان باشد، JSON 413 مخصوص ویجت را دریافت میکند («File is too large.»). بارگذاریای که بالای محدودیتهای میزبان باشد ابتدا توسط IIS رد میشود، با صفحهٔ خطایی که ویجت نمیتواند بخواند. هر دو محدودیت میزبان را در Web.config بالاتر از سقف ویجت نگه دارید:
<system.web>
<httpRuntime maxRequestLength="30720" /> <!-- کیلوبایت: 30 MB -->
</system.web>
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="31457280" /> <!-- بایت: 30 MB -->
</requestFiltering>
</security>
</system.webServer>سفارشیسازی ویجت
گزینههای ارسالشده به Doconut.convert(selector, options):
| گزینه | نوع | پیشفرض | یادداشتها |
|---|---|---|---|
basePath | string | /doconut | آدرس نقطه انتهایی. '/DocImage.axd' را در این بسته تنظیم کنید |
resPath | string | /doconut-res | برای سازگاری با سایر ویجتهای Doconut پذیرفته شده است؛ ویجت مبدل هیچ URLای از آن نمیسازد |
maxUploadMb | number | 25 | فقط پیشبررسی سمت کلاینت؛ سرور سقف خود را اعمال میکند |
licenseUrl | string | null | null | اعلان واترمارک در صفحهٔ نتیجه را به یک لینک تبدیل میکند |
labels | object | {} | هر زیرمجموعهای از رشتههای انگلیسی ویجت را بازنویسی میکند |
بازگشتخوانها:
| بازگشتخوان | زمانی که رخ میدهد | داده |
|---|---|---|
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() نمونهٔ ویجت را برمیگرداند: reset() به صفحهٔ رهاسازی باز میگردد، loadFile(file) جریان را با یک File آغاز میکند، و destroy() آن را حذف میکند.
ساخت فرانتاند خود
ویجت یک کلاینت برای این قرارداد HTTP در DocImage.axd است:
| مسیر | هدف | پاسخ موفق |
|---|---|---|
POST /DocImage.axd?convert=open (multipart, field file) | بارگذاری و باز کردن یک سند منبع | 200 — { token, pages, sourceExt, allowedTargets } |
POST /DocImage.axd?token=<token>&convert=run&target=<ext> | تبدیل منبع بارگذاریشده به target | 200 — { downloadToken, resultToken, resultPages, downloadName, watermarked } |
GET /DocImage.axd?convert=download&token=<downloadToken> | پخش فایل تبدیلشده | 200 — فایل، Content-Disposition: attachment |
منابع بارگذاریشده به مدت 30 دقیقه نگهداری میشوند؛ پس از آن، run به 404 پاسخ میدهد و فایل باید دوباره باز شود. downloadToken پس از تکمیل تبدیل، پنجره 30 دقیقهای خود را دریافت میکند. resultToken یک توکن نمایشگر عادی است که طول عمر جلسه نمایشگر را دنبال میکند.
sourceExt در پاسخ open نقطهٔ پیشساز (leading dot) ندارد ("docx") — برعکس پارامتر sourceExtension از ConvertAsync.
| مسیر | وضعیت | چهوقت | بدنه |
|---|---|---|---|
| any | 404 | ویجت فعال نیست (AddConverterWidget() هرگز فراخوانی نشده است) | فقط وضعیت |
| any | 405 | فعل نادرست (open/run نیاز به POST دارند، download نیاز به GET دارد) | فقط وضعیت |
open | 413 | بارگذاری از MaxUploadMb فراتر میرود (اما محدودیتهای IIS نیست) | { "error": "File is too large." } |
open | 400 | بدنهٔ چندبخشی وجود ندارد، فایل نیست، یا نوعی که قابل تبدیل نیست | { "error": "..." } |
open | 403 | نوع فایل به قابلیتای نیاز دارد که مجوز آن را اعطا نمیکند | { "error": "..." } |
run | 400 | توکن خراب، target ناشناخته، یا هدفی که در allowedTargets نیست | { "error": "..." } |
run | 404 | بارگذاری منقضی شد یا هرگز باز نشد | { "error": "Upload expired — please re-open the file." } |
open, run | 500 | پردازش ناموفق بود | { "error": "<sanitized message>" } |
download | 400 / 404 | توکن دانلود خراب، ناشناخته یا منقضیشده | فقط وضعیت |
مالکیت منبع
صدا کننده مالک MemoryStream است که یک تبدیل برمیگرداند و باید پس از کپی یا بازگرداندن آن، آن را آزاد کند (MVC's File(stream, …) برای شما آن را آزاد میکند). DocumentConverter را خودتان ساخت یا آزاد نکنید — سازندهٔ آن داخلی است.
افزودن واترمارک
| وضعیت مجوز | راهاندازی | خروجی تبدیل |
|---|---|---|
مجوز نمایشگر پرداختشده که Converter را اعطا میکند | شروع میشود | تمیز — watermarked: false |
| مجوز موقت/دموی فعال | شروع میشود | تبدیل میکند، با واترمارک ارزیابی — watermarked: true |
بدون مجوز، فایل قدیمی TRIAL یا مجوزی بدون Converter | Application_Start خطا میاندازد؛ هر درخواست پاسخ یک 500 خالی میدهد | — |
| مجوز موقت/دموی منقضیشده | شروع میشود | تبدیل میکند، با واترمارک ارزیابی — watermarked: true |
یک ادغام میتواند بهصورت انتها به انتها بر روی یک مجوز ارزیابی ساخته و تست شود قبل از خرید — فقط بایتهای خروجی تغییر میکنند.
عیبیابی
| علامت | بررسی |
|---|---|
هر درخواست پس از افزودن افزونه، یک 500 خالی پاسخ میدهد | مجوز Converter را اعطا میکند — لاگ رویداد ویندوز، منبع ASP.NET |
حل کردن DocumentConverter خطا میاندازد | AddPlugin<ConverterPlugin>() در DoconutHost.Initialize است |
| یک تبدیل Web Forms هرگز باز نمیگردد | صفحه در ConvertAsync مسدود میشود — از Async="true" و RegisterAsyncTask استفاده کنید |
| تبدیل جریان میگوید قالب پشتیبانی نمیشود | sourceExtension نقطهٔ پیشساز را شامل میشود |
ویجت بارگذاری میشود اما درخواستهای آن 404 را برمیگردانند | AddConverterWidget() فراخوانی نشده است، یا basePath '/DocImage.axd' نیست |
| یک بارگذاری بزرگ صفحه خطای IIS را نشان میدهد به جای پیام ویجت | maxRequestLength / maxAllowedContentLength کمتر از MaxUploadMb هستند |
| یک هدف گم شده است | از allowedTargets در convert=open استفاده کنید |
| دانلود منقضی شد | convert=open / convert=run را تکرار کنید؛ توکنها عمداً موقت هستند |
آیا این صفحه مفید بود؟