Plugin Convertidor

Convierte documentos a 24 formatos de destino

El plugin Convertidor convierte Doconut en un servicio de conversión de documentos. Contribuye con el motor detrás de la fachada pública DocumentConverter, y — opcionalmente — un widget listo para usar con su propio contrato HTTP, de modo que puedes convertir documentos desde C#, desde el widget, o desde una interfaz que desarrolles tú mismo.

Instalar el paquete

Instala el plugin Convertidor estable más reciente:

bash
dotnet add package Doconut.NET8.Converter

Para fijar el plugin a la versión actual 26.7.0, pasa la versión por separado:

bash
dotnet add package Doconut.NET8.Converter --version 26.7.0

Mantén el paquete Convertidor en la misma versión que Doconut.NET8. El ID del paquete es Doconut.NET8.Converter; .26.7.0 aparece solo en el nombre del archivo .nupkg descargado.

Registrar el plugin

No existe el método AddConverter() — el modelo de plugins de Doconut es uniforme. Cada plugin, incluido Convertidor, se registra de la misma manera: llama a AddPlugin<TPlugin>() dentro de AddDoconut(). ConverterPlugin se entrega en su propio paquete NuGet, Doconut.NET8.Converter, instalado junto al paquete base del visor.

csharp
builder.Services.AddDoconut(options =>
{
    options.LicensePath = "Doconut.Viewer.lic";
    options.AddPlugin<Doconut.Plugins.Converter.ConverterPlugin>();
});

Esta llamada lanza una excepción al iniciar si falta la licencia, hay un archivo legado TRIAL, o una licencia no temporal que no otorga la capacidad Converter — una InvalidOperationException generada dentro de AddDoconut(), antes de que la aplicación atienda solicitudes. Se aceptan registros temporales Demo/NFR; después de su expiración de calendario, la conversión sigue disponible con salida marcada con agua. No hay un nivel gratuito silencioso. Consulte Configuración de Licencia para saber cómo se cargan las licencias.

Convertir desde C#

Cada conversión devuelve un MemoryStream buscable posicionado en 0, listo para leer o copiar inmediatamente. Resuelve DocumentConverter desde DI donde lo necesites — es sin estado por diseño, por lo que una única instancia es segura para reutilizarse en múltiples solicitudes.

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);

Dos detalles que son fáciles de equivocarse: sourceExtension en la sobrecarga de flujo debe incluir el punto inicial (".xlsx", no "xlsx") — el convertidor lo compara con el catálogo de formatos y una extensión sin punto no se resolverá. Y a pesar de su nombre, WordToHtmlAsync devuelve Task<Stream>, no Task<string> — obtienes el documento HTML (imágenes incrustadas como Base64) como un flujo, igual que cualquier otro resultado de conversión.

Formatos de destino

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

No todas las fuentes se convierten a todos los destinos — el plugin asigna cada familia de formato de origen (Word, Excel, PowerPoint, PDF, CAD, Imagen, Email, Diagrama, Proyecto/Tarea, PSD, documento web) a su propio conjunto fijo de destinos permitidos. No codifiques este enum como la lista de destinos de tu UI: ?convert=open devuelve los allowedTargets reales para el archivo que se acaba de subir, y eso es lo que debe alimentar un selector.

Widget listo para usar

Los endpoints ?convert=open|run|download del widget son opcionales y están deshabilitados por defecto — seguros por defecto. Habilítalos del lado del servidor, junto con el registro del plugin:

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>

Sin AddConverterWidget(), los tres endpoints ?convert= responden 404 — pero el archivo JS sigue sirviéndose de todos modos (es un recurso estático incrustado simple; solo los endpoints a los que se comunica están restringidos). AddConverterWidget() aún requiere que el plugin Convertidor esté registrado y una licencia que otorgue Converter — no otorga derechos de conversión por sí mismo.

Personalizar el widget

Opciones de inicialización pasadas a Doconut.convert(selector, options):

OpciónTipoPredeterminadoNotas
basePathstring/doconutRuta base para los endpoints ?convert=; debe coincidir con la rama ASP.NET donde UseDoconut() está realmente montado (normalmente coordinado a través de MiddlewarePath)
resPathstring/doconut-resAceptado por consistencia de configuración con otros widgets Doconut; el widget del convertidor actualmente no construye ninguna URL a partir de él
maxUploadMbnumber25Solo verificación previa del lado del cliente — rechaza un archivo demasiado grande antes de subirlo. El servidor impone su propio límite de forma independiente y responde 413 si se supera
licenseUrlstring | nullnullCuando se establece, convierte el aviso de marca de agua en la pantalla de resultados en un enlace a esta URL
labelsobject{}Sobrescribe cualquier subconjunto de las cadenas predeterminadas en inglés del widget (texto de arrastre, botones, anuncios aria‑live, mensajes de error)

Retornos

RetornoSe dispara cuandoCarga
onReady()El widget ha renderizado su pantalla inactiva/de arrastre
onSourceLoaded({ token, pages, sourceExt, allowedTargets })?convert=open tiene éxitotoken de sesión de origen, recuento de páginas, extensión de origen (sin punto inicial), lista de destinos permitidos
onConverted({ downloadToken, resultToken, resultPages, downloadName, watermarked, target })?convert=run tiene éxitolos mismos campos que la respuesta de run, más el target solicitado
onDownload({ downloadName, downloadToken })El usuario hace clic en el enlace Descargarse dispara junto con la descarga nativa del navegador — no la intercepta ni la reemplaza
onError({ phase, message })Una solicitud open o run fallaphase es 'open' o 'run'; message es el error del servidor sanitizado (o un mensaje del cliente para la verificación previa del tamaño de carga)

Doconut.convert() devuelve la propia instancia del widget — mantenla para controlar el widget programáticamente:

javascript
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

Construir tu propio frontend

El widget es solo un cliente para este contrato HTTP — construye tu propio frontend contra él directamente para una UX diferente. Las tres rutas se encuentran bajo la rama ASP.NET donde UseDoconut() está montado (normalmente /doconut):

| Ruta | Propósito | Respuesta exitosa | |---|---|---|---| | POST ?convert=open (multipart, field file) | Cargar y abrir un documento fuente para vista previa | 200{ token, pages, sourceExt, allowedTargets } | | POST ?token=<token>&convert=run&target=<ext> | Convertir la fuente almacenada a target | 200{ downloadToken, resultToken, resultPages, downloadName, watermarked } | | GET ?convert=download&token=<downloadToken> | Transmitir el archivo convertido | 200 — bytes del archivo, Content-Disposition: attachment, Cache-Control: no-store |

Los bytes de la fuente cargada se almacenan en el servidor con un TTL de 30 minutos; una vez que esa ventana expira, run responde 404 y el archivo debe volver a abrirse. El resultado convertido vive en el mismo almacén — downloadToken obtiene su propia ventana fresca de 30 minutos cuando la conversión termina — mientras que resultToken es un token de sesión de visor ordinario cuyo tiempo de vida sigue la caché de sesión del visor, independiente del almacén.

sourceExt en la respuesta open no tiene punto inicial (p. ej. "docx") — la convención opuesta al parámetro sourceExtension en DocumentConverter.ConvertAsync, que sí lo requiere.

Modos de falla, agrupados por ruta

RutaEstadoCuándoCuerpo
cualquier404El widget no está habilitado (AddConverterWidget() nunca se llamó) — verificado antes de que cualquiera de las tres rutas se despachesolo estado
cualquier405Verbo HTTP incorrecto (open/run requieren POST; download requiere GET)solo estado
open413El archivo cargado supera MaxUploadMb{ "error": "El archivo es demasiado grande." }
open400No hay cuerpo multipart, no hay archivo, o una extensión de origen que no se puede convertir{ "error": "..." }
run400Token malformado (no es un GUID), o un target que no se puede analizar a un ConversionTarget{ "error": "Token inválido." } / { "error": "Formato de destino desconocido." }
run400target no está en los allowedTargets de la fuente{ "error": "Ese formato de destino no está disponible para este archivo." }
run404La carga almacenada ha expirado (TTL de 30 minutos) o el token nunca se abrió{ "error": "Carga expirada — por favor vuelva a abrir el archivo." }
open, run500Falló el procesamiento internamente{ "error": "<sanitized message>" } — sanitizado de la misma manera que cualquier otro camino de error de Doconut; nunca revela nombres internos del motor
download400Token malformado (no es un GUID)solo estado
download404Token de descarga desconocido o expiradosolo estado

Propiedad de recursos

El convertidor devuelve un MemoryStream buscable posicionado en cero. El llamador posee ese flujo y debe disponerlo después de copiar o devolver su contenido. El propio servicio DocumentConverter es sin estado y se resuelve mediante inyección de dependencias; no lo construyas ni lo dispongas manualmente.

Para el widget web, los almacenes de carga y descarga tienen TTLs independientes de 30 minutos. Un resultToken de visor sigue la duración de la sesión del visor. Cerrar un resultado del visor no elimina un almacén de descarga aún válido, y reiniciar el widget del navegador no extiende ninguno de los TTL.

Solución de problemas

SíntomaVerificación
Falla al resolver DocumentConverterEl registro de ConverterPlugin ocurrió dentro de AddDoconut()
La aplicación falla durante el inicioLa licencia cargada otorga Converter
La conversión de flujo indica que el formato no es compatiblesourceExtension incluye el punto inicial
El JavaScript del widget se carga pero las solicitudes devuelven 404AddConverterWidget() no se llamó
Las solicitudes del widget usan la URL incorrectabasePath coincide con la rama donde UseDoconut() está mapeado
Falta el destinoUtiliza allowedTargets devuelto por convert=open; no todas las fuentes admiten cada objetivo del enum
Descarga expiradaRepite convert=open/convert=run; los tokens de almacén son intencionalmente temporales

Marca de agua

Con ConverterPlugin registrado, la licencia del host está en uno de tres estados:

Estado de la licenciaPuerta de inicioSalida de conversión
Licencia de visor pagada que otorga Converter, dentro de su período de validezPasaLimpia — watermarked: false
Licencia de evaluación activa (demo/NFR)PasaConvierte con éxito, marcada con la marca de agua de evaluación — watermarked: true
Sin licencia, un archivo legado TRIAL, o una licencia no temporal que no otorga ConverterLa aplicación nunca inicia — la puerta de inicio descrita arriba lanza una excepción
Licencia Temporal/Demo expiradaEl registro sobrevive a la expiraciónConvierte con la marca de agua de evaluación — watermarked: true

Ambas rutas de llamada calculan la bandera a partir de la misma regla: la fachada C# DocumentConverter la deriva internamente del estado IsViewerLicensed y IsTemporary de la licencia, y el manejador ?convert=run del widget realiza la comprobación equivalente (IsViewerLicensed && !IsTrial && !IsTemporary) para rellenar el campo watermarked que devuelve. Se puede construir e probar una integración de extremo a extremo con una licencia de evaluación antes de la compra — solo cambian los bytes de salida.

¿Fue útil esta página?