Плагін Конвертера
Перетворення документів у 45 цільових форматів
Плагін Converter перетворює Doconut у сервіс конвертації документів. Він забезпечує движок, що стоїть за публічним фасадом DocumentConverter, і — за бажанням — готовий віджет зі своїм HTTP‑контрактом, що дозволяє конвертувати документи з C#, з віджета або з власного фронтенду.
Встановлення пакету
Встановіть останню стабільну версію плагіна Converter:
dotnet add package Doconut.NETStandard.ConverterЩоб зафіксувати плагін на поточному випуску 26.8.0, передайте версію окремо:
dotnet add package Doconut.NETStandard.Converter --version 26.8.0Тримайте пакет Converter тієї ж версії, що й Doconut.NETStandard. Ідентифікатор пакету — Doconut.NETStandard.Converter; .26.8.0 з’являється лише у назві завантаженого файлу .nupkg.
Реєстрація плагіна
Методу AddConverter() не існує — модель плагінів Doconut уніфікована. Кожен плагін, включаючи Converter, реєструється однаково: викликайте AddPlugin<TPlugin>() всередині AddDoconut(). ConverterPlugin постачається у власному пакеті NuGet Doconut.NETStandard.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 там, де це потрібно — він безстановий за задумом, тому одну інстанцію безпечно використовувати повторно в різних запитах.
viewer.Converter.GetConverter() тут не існує. Конвертація більше не здійснюється через екземпляр переглядача: інжектуйте Doconut.DocumentConverter замість цього.
// Inject DocumentConverter; its constructor is internal, so never `new` it.
Stream pdf = await converter.ConvertAsync("contract.docx", ConversionTarget.Pdf, ct: ct);// 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);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) у вигляді потоку, так само, як і будь‑який інший результат конвертації.
Цільові формати
ConversionTarget (простір імен Doconut.Configs.Conversion) має 45 членів:
Pdf, Docx, Doc, Html, Xlsx, Pptx, Png, Jpeg, Csv, Tiff, Bmp, Gif, Svg, Xml,
Txt, Xls, Jp2, Rtf, Odt, Ods, Odp, Epub, Xps, Webp, Msg, Eml, Emlx, Mhtml,
Xlsm, Xlsb, Ppt, Docm, Dot, Dotx, Dotm, Vsdx, Vssx, Vstx, Vsdm, Vssm, Vstm,
Vdx, Vsx, Vtx, IcoЦей один enum охоплює всі сімейства джерел. У попередній бібліотеці був окремий тип *ConfigConverter для кожного сімейства — WordConfigConverter, ExcelConfigConverter тощо — кожен зі своїм вкладеним enum EnTargetFormat, плюс enum SourceFormatConverter для вхідних даних. Усі вони прибрані; дивіться посібник з міграції.
Не кожне джерело конвертується у кожну ціль — плагін зіставляє сімейство формату джерела (Word, Excel, PowerPoint, PDF, CAD, Image, Email, Diagram, Project/Task, PSD, веб‑документ) зі своїм фіксованим набором дозволених цілей. Не кодуйте цей enum жорстко у вашому UI: ?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 успішно виконано | ті ж поля, що й у відповіді run, плюс запитаний target |
onDownload({ downloadName, downloadToken }) | Користувач натискає посилання Завантажити | викликається разом з вбудованим завантаженням браузера — не перехоплює і не замінює його |
onError({ phase, message }) | Запит open або run завершується помилкою | phase — 'open' або 'run'; message — очищене повідомлення сервера (або повідомлення на боці клієнта для попередньої перевірки розміру завантаження) |
Doconut.convert() повертає сам екземпляр віджету — збережіть його, щоб керувати віджетом програмно:
const conv = Doconut.convert('#doconut-convert', { basePath: '/doconut' });
conv.reset(); // back to the idle/drop screen; does not re-fire onReady
conv.loadFile(file); // starts the flow with a File object; no-op unless currently idle
conv.destroy(); // removes listeners, empties the mount; the instance is unusable after thisСтворіть власний інтерфейс
Віджет — лише клієнт для цього HTTP‑контракту — створіть власний інтерфейс безпосередньо проти нього для іншого UX. Усі три маршрути розташовані під гілкою ASP.NET, де змонтовано UseDoconut() (зазвичай /doconut):
| Маршрут | Призначення | Відповідь при успіху |
|---|---|---|
POST ?convert=open (multipart, поле 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" ) — протилежна конвенція параметру sourceExtension у DocumentConverter.ConvertAsync, який вимагає крапку.
Режими помилок, згруповані за маршрутом:
| Маршрут | Статус | Коли | Тіло |
|---|---|---|---|
| будь‑який | 404 | Віджет не ввімкнено (AddConverterWidget() ніколи не викликався) — перевіряється до обробки будь‑якого з трьох маршрутів | лише статус |
| будь‑який | 405 | Неправильний HTTP‑метод (open/run вимагають POST; download вимагає GET) | лише статус |
open | 413 | Завантажений файл перевищує MaxUploadMb | { "error": "File is too large." } → { "error": "Файл занадто великий." } |
open | 400 | Відсутнє multipart‑тіло, файл або розширення, яке не можна конвертувати | { "error": "..." } |
run | 400 | Некоректний токен (не GUID) або target, який не розпізнається як ConversionTarget | { "error": "Invalid token." } → { "error": "Недійсний токен." } / { "error": "Unknown target format." } → { "error": "Невідомий формат цілі." } |
run | 400 | target відсутній у allowedTargets джерела | { "error": "That target format is not available for this file." } → { "error": "Цей формат цілі недоступний для цього файлу." } |
run | 404 | Термін дії збереженого завантаження закінчився (TTL 30 хв) або токен ніколи не був відкритий | { "error": "Upload expired — please re-open the file." } → { "error": "Термін дії завантаження закінчився — будь ласка, знову відкрийте файл." } |
open, run | 500 | Внутрішня помилка обробки | { "error": "<sanitized message>" } — очищено так само, як у будь‑якому іншому шляху помилок Doconut; ніколи не розкриває внутрішні назви движка |
download | 400 | Некоректний токен (не GUID) | лише статус |
download | 404 | Невідомий або прострочений токен завантаження | лише статус |
Власність ресурсів
Конвертер повертає пошуковий MemoryStream, позиціонований на нуль. Викликальник володіє цим потоком і повинен його звільнити після копіювання або повернення його вмісту. Сервіс DocumentConverter сам по собі без стану і отримується через впровадження залежностей; не створюйте і не звільняйте сервіс вручну.
Для веб‑віджета, сховища завантаження та скачування мають незалежні TTL у 30 хвилин. Токен resultToken переглядача слідує життєвому циклу сесії переглядача. Закриття результату переглядача не видаляє ще дійсне сховище скачування, і скидання браузерного віджета не продовжує жоден з TTL.
Вирішення проблем
| Симптом | Перевірка |
|---|---|
Не вдається розв’язати DocumentConverter | Реєстрація ConverterPlugin відбулася всередині AddDoconut() |
| Застосунок не запускається під час старту | Завантажена ліцензія надає Converter |
| Перетворення потоку повідомляє, що формат не підтримується | sourceExtension містить початкову крапку |
| JavaScript віджета завантажується, але запити повертають 404 | AddConverterWidget() не був викликаний |
| Запити віджета використовують неправильний URL | basePath відповідає гілці, де відображено UseDoconut() |
| Ціль відсутня | Використайте allowedTargets, повернуті convert=open; не кожне джерело підтримує кожну ціль enum |
| Термін завантаження закінчився | Повторіть convert=open/convert=run; токени сховища навмисно тимчасові |
Додання водяного знаку
| Стан ліцензії | Перевірка запуску | Результат перетворення |
|---|---|---|
Платна ліцензія переглядача, що надає Converter, протягом терміну дії | Проходить | Чистий — watermarked: false |
| Активна оцінювальна (демо/NFR) ліцензія | Проходить | Успішно перетворює, позначений оцінювальним водяним знаком — watermarked: true |
Без ліцензії, застарілий файл TRIAL або нелімітована ліцензія, що не надає Converter | Застосунок ніколи не запускається — перевірка запуску, описана вище, викликає виключення | — |
| Термін дії тимчасової/демо ліцензії закінчився | Реєстрація зберігається після закінчення терміну | Перетворює з оцінювальним водяним знаком — watermarked: true |
Обидва шляхи виклику обчислюють прапорець за тим же правилом: фасад DocumentConverter на C# визначає його внутрішньо на основі стану ліцензії IsViewerLicensed та IsTemporary, а обробник віджета ?convert=run виконує еквівалентну перевірку (IsViewerLicensed && !IsTrial && !IsTemporary), щоб заповнити поле watermarked, яке він повертає. Інтеграцію можна створити та протестувати повністю на оцінювальній ліцензії перед покупкою — змінюються лише байти вихідних даних.
Чи була ця сторінка корисною?