Плагін Конвертера
Конвертуйте документи у 24 цільові формати
Плагін Converter перетворює Doconut у сервіс конвертації документів. Він надає движок, що стоїть за публічним фасадом DocumentConverter і — за бажанням — готовий віджет, що обслуговується DocImage.axd, тому ви можете конвертувати документи з C#, з віджета або з фронтенду, який створите самостійно.
Встановити пакет
Install-Package Doconut.NETFramework.ConverterТримайте пакет 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, а причина записана лише в журналі подій Windows (джерело ASP.NET). Тимчасові Demo/NFR ліцензії приймаються. Дивіться Налаштування ліцензії.
Конвертувати з C#
Кожна конвертація повертає придатний до пошуку MemoryStream, позиціонований на 0. DocumentConverter є безстанним: отримуйте його з DoconutHost.Services там, де потрібен, і вільно повторно використовуйте.
// Отримайте DocumentConverter з DoconutHost.Services; його конструктор є internal, тому ніколи не `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) надходить у вигляді потоку, як і будь‑який інший результат.
У контролері 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()) призводить до deadlock‑у запиту:
// він ніколи не повертається, і нічого не записується.
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, веб‑документ) має власний набір дозволених цілей. Не жорстко кодуйте цей перелік у вашому UI: ?convert=open повертає allowedTargets для завантаженого файлу, і саме це має керувати вибором.
Вбудований віджет
Кінцеві точки ?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 («Файл занадто великий.»). Завантаження, що перевищує обмеження хоста, спочатку відхиляється 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 | URL кінцевої точки. Встановіть '/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 не має початкової крапки ("docx") — навпаки до параметра sourceExtension у ConvertAsync.
| Маршрут | Статус | Коли | Тіло |
|---|---|---|---|
| any | 404 | Віджет не ввімкнено (AddConverterWidget() ніколи не викликався) | лише статус |
| any | 405 | Неправильний метод (open/run вимагає POST, download вимагає GET) | лише статус |
open | 413 | Завантаження перевищує MaxUploadMb (але не межі IIS) | { "error": "File is too large." } |
open | 400 | Відсутнє multipart‑тіло, файл або тип, який не можна конвертувати | { "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‑овий File(stream, …) звільняє його за вас). Не створюйте і не звільняйте DocumentConverter самостійно — його конструктор є внутрішнім.
Водяний знак
| Стан ліцензії | Запуск | Вихід конверсії |
|---|---|---|
Платна ліцензія переглядача, що надає Converter | Запускається | Чистий — watermarked: false |
| Активна тимчасова/демо‑ліцензія | Запускається | Конвертує, з водяним знаком оцінки — watermarked: true |
Відсутня ліцензія, застарілий файл TRIAL або ліцензія без Converter | Application_Start викидає виключення; кожен запит відповідає порожнім 500 | — |
| Прострочена тимчасова/демо‑ліцензія | Запускається | Конвертує, з водяним знаком оцінки — watermarked: true |
Інтеграцію можна створити та протестувати від початку до кінця на оцінній ліцензії перед покупкою — змінюються лише байти вихідних даних.
Усунення неполадок
| Симптом | Перевірка |
|---|---|
Кожен запит відповідає порожнім 500 після додавання плагіна | Ліцензія надає Converter — журнал подій Windows, джерело 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; токени навмисно тимчасові |
Чи була ця сторінка корисною?