Плагин Конвертера
Преобразуйте документы в 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 — но сам файл JavaScript всё равно отдается (это простой встроенный статический ресурс; защищены только те конечные точки, к которым он обращается). 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 }) | Пользователь нажимает ссылку Download | срабатывает одновременно с нативным скачиванием браузера — не перехватывает и не заменяет его |
onError({ phase, message }) | Запрос open или run завершился ошибкой | phase — 'open' или 'run'; message — очищенное сообщение сервера (или сообщение на клиенте для проверки размера загрузки) |
Doconut.convert() возвращает сам экземпляр виджета — сохраняйте его, чтобы управлять виджетом программно:
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, поле 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 — байты файла, Content-Disposition: attachment, Cache-Control: no-store |
Загруженные байты источника сохраняются на сервере со сроком жизни 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." } |
open | 400 | Отсутствует multipart‑тело, файл не передан, либо расширение источника нельзя конвертировать | { "error": "..." } |
run | 400 | Некорректный токен (не GUID) или target, который не распознаётся как ConversionTarget | { "error": "Invalid token." } / { "error": "Unknown target format." } |
run | 400 | target отсутствует в allowedTargets источника | { "error": "That target format is not available for this file." } |
run | 404 | Сохранённая загрузка истекла (TTL 30 минут) или токен никогда не открывался | { "error": "Upload expired — please re-open the file." } |
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 target |
| Срок загрузки истёк | Повторите convert=open/convert=run; токены хранилища намеренно временные |
Водяные знаки
С ConverterPlugin зарегистрированным, лицензия хоста находится в одном из трёх состояний:
| Состояние лицензии | Проверка при запуске | Результат преобразования |
|---|---|---|
Платная лицензия просмотра, предоставляющая Converter, в пределах срока действия | Проходит | Чистый — watermarked: false |
| Активная оценочная (демо/NFR) лицензия | Проходит | Успешно преобразует, помечено оценочным водяным знаком — watermarked: true |
Без лицензии, устаревший файл TRIAL или непостоянная лицензия, не предоставляющая Converter | Приложение никогда не запускается — проверка при запуске, описанная выше, бросает исключение | — |
| Истёкшая временная/демо лицензия | Регистрация сохраняется после истечения | Преобразует с оценочным водяным знаком — watermarked: true |
Оба пути вызова вычисляют флаг по одному и тому же правилу: фасад DocumentConverter на C# выводит его внутренне из состояний лицензии IsViewerLicensed и IsTemporary, а обработчик виджета ?convert=run выполняет эквивалентную проверку (IsViewerLicensed && !IsTrial && !IsTemporary), чтобы заполнить возвращаемое поле watermarked. Интеграцию можно собрать и протестировать сквозным образом на оценочной лицензии до покупки — меняются только байты вывода.
Была ли эта страница полезной?