Плагин Конвертера

Преобразуйте документы в 45 целевых форматов

Плагин Converter превращает Doconut в сервис конвертации документов. Он предоставляет движок, лежащий в основе публичного фасада DocumentConverter, и — при желании — готовый к использованию виджет со своим HTTP‑контрактом, так что вы можете конвертировать документы из C#, из виджета или из собственного фронтенда.

Установить пакет

Установите последнюю стабильную версию плагина Converter:

bash
dotnet add package Doconut.NETStandard.Converter

Чтобы зафиксировать плагин на текущем выпуске 26.8.0, укажите версию отдельно:

bash
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, установленном рядом с базовым пакетом просмотрщика.

csharp
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.

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 в перегрузке для потока должен включать ведущую точку (".xlsx", а не "xlsx" ) — конвертер сопоставляет её с каталогом форматов, и без точки расширение не будет распознано. И, несмотря на название, WordToHtmlAsync возвращает Task<Stream>, а не Task<string> — вы получаете HTML‑документ (изображения встроены как Base64) в виде потока, как и любой другой результат конвертации.

Целевые форматы

ConversionTarget (пространство имён Doconut.Configs.Conversion) содержит 45 членов:

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, 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 виджета являются опциональными и по умолчанию отключены — это обеспечивает безопасность из коробки. Включите их на стороне сервера вместе с регистрацией плагина:

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 — но сам файл JavaScript всё равно отдается (это простой встроенный статический ресурс; защищены только те конечные точки, к которым он обращается). 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, сообщения об ошибках).

Обратные вызовы:

Обратный вызовСрабатывает, когдаДанные
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() возвращает сам экземпляр виджета — сохраняйте его, чтобы управлять виджетом программно:

javascript
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>Конвертировать сохранённый источник в указанный target200 — { 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)только статус
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 30 минут) или токен никогда не открывался{ "error": "Upload expired — please re-open the file." }
open, run500Внутренняя ошибка обработки{ "error": "<sanitized message>" } — очищено так же, как во всех остальных путях ошибок Doconut; внутренние названия движков не раскрываются
download400Некорректный токен (не GUID)только статус
download404Неизвестный или истёкший токен загрузкитолько статус

Владение ресурсом

Конвертер возвращает перемещаемый MemoryStream, позиционированный в нуле. Вызывающая сторона владеет этим потоком и должна освободить его после копирования или возврата его содержимого. Сервис DocumentConverter сам по себе без состояния и получается через внедрение зависимостей; не создавайте и не освобождайте сервис вручную.

Для веб‑виджета загрузочные и скачиваемые хранилища имеют независимые TTL в 30 минут. Токен resultToken просмотрщика следует сроку жизни сессии просмотрщика. Закрытие результата просмотрщика не удаляет всё ещё действительное хранилище загрузки, и сброс виджета в браузере не продлевает ни один из TTL.

Устранение неполадок

СимптомПроверка
Не удалось разрешить DocumentConverterConverterPlugin регистрация произошла внутри AddDoconut()
Приложение не запускаетсяЗагруженная лицензия предоставляет Converter
Преобразование потока сообщает, что формат не поддерживаетсяsourceExtension включает ведущую точку
JavaScript виджета загружается, но запросы возвращают 404AddConverterWidget() не был вызван
Запросы виджета используют неправильный URLbasePath соответствует ветке, где сопоставлен 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. Интеграцию можно собрать и протестировать сквозным образом на оценочной лицензии до покупки — меняются только байты вывода.

Была ли эта страница полезной?