Plugin Conversor
Converta documentos para 45 formatos de destino
O plugin Conversor transforma o Doconut em um serviço de conversão de documentos. Ele fornece o motor por trás da fachada pública DocumentConverter e — opcionalmente — um widget pronto para uso com seu próprio contrato HTTP, permitindo que você converta documentos a partir de C#, do widget ou de um frontend que você mesmo desenvolva.
Instalar o pacote
Instale o plugin Conversor mais recente e estável:
dotnet add package Doconut.NETStandard.ConverterPara fixar o plugin na versão atual 26.8.0, passe a versão separadamente:
dotnet add package Doconut.NETStandard.Converter --version 26.8.0Mantenha o pacote Conversor na mesma versão que o Doconut.NETStandard. O ID do pacote é
Doconut.NETStandard.Converter; .26.8.0 aparece apenas no nome do arquivo .nupkg baixado.
Registrar o plugin
Não existe o método AddConverter() — o modelo de plugins do Doconut é uniforme. Cada plugin, inclusive o Conversor, é registrado da mesma forma: chame AddPlugin<TPlugin>() dentro de AddDoconut(). O ConverterPlugin é distribuído em seu próprio pacote NuGet, Doconut.NETStandard.Converter, instalado ao lado do pacote base do visualizador.
builder.Services.AddDoconut(options =>
{
options.LicensePath = "Doconut.Viewer.lic";
options.AddPlugin<Doconut.Plugins.Converter.ConverterPlugin>();
});Essa chamada gera uma exceção na inicialização quando falta a licença, há um arquivo legado
TRIALou a licença não temporária não concede a capacidadeConverter— umaInvalidOperationExceptionlançada de dentro deAddDoconut(), antes que o aplicativo atenda solicitações. Registros temporários de demonstração/NFR são aceitos; após a expiração do calendário, a conversão continua disponível com saída marca‑d’água. Não há nível gratuito silencioso. Consulte a Configuração de Licença para saber como as licenças são carregadas.
Converter a partir de C#
Cada conversão devolve um MemoryStream buscável posicionado em 0, pronto para leitura ou cópia imediata. Resolva DocumentConverter via DI onde precisar — ele é sem estado por design, portanto uma única instância pode ser reutilizada com segurança entre requisições.
viewer.Converter.GetConverter() não existe aqui. A conversão não é mais acessada através da instância do visualizador: injete Doconut.DocumentConverter em seu lugar.
// 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);Dois detalhes que são fáceis de errar: sourceExtension na sobrecarga que aceita stream deve incluir o ponto inicial (".xlsx", não "xlsx" ) — o conversor o compara com o catálogo de formatos e uma extensão sem ponto não será resolvida. E, apesar do nome, WordToHtmlAsync devolve Task<Stream>, não Task<string> — você recebe o documento HTML (imagens incorporadas como Base64) como um stream, assim como todo resultado de conversão.
Formatos de destino
ConversionTarget (namespace Doconut.Configs.Conversion) possui 45 membros:
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, IcoEsse enum cobre todas as famílias de origem. A biblioteca anterior possuía um tipo *ConfigConverter por família — WordConfigConverter, ExcelConfigConverter e assim por diante — cada um com seu próprio enum aninhado EnTargetFormat, além de um enum SourceFormatConverter para a entrada. Todos foram removidos; veja o guia de migração.
Nem toda origem converte para todo destino — o plugin mapeia cada família de formato de origem (Word, Excel, PowerPoint, PDF, CAD, Image, Email, Diagram, Project/Task, PSD, documento web) para seu próprio conjunto fixo de destinos permitidos. Não codifique esse enum como a lista de destinos da sua UI: ?convert=open devolve os allowedTargets reais para o arquivo que acabou de ser enviado, e isso é o que deve alimentar um seletor.
Widget incorporável
Os endpoints ?convert=open|run|download do widget são opcionais e ficam desativados por padrão — seguro por padrão. Habilite‑os no lado do servidor, juntamente com o registro do plugin:
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>Sem AddConverterWidget(), os três endpoints ?convert= retornam 404 — mas o arquivo JS ainda é servido (é um recurso estático embutido; apenas os endpoints com os quais ele se comunica são restritos). AddConverterWidget() ainda requer que o plugin Converter esteja registrado e que exista uma licença que conceda Converter — ele não concede direitos de conversão por conta própria.
Personalizar o widget
Opções de inicialização passadas para Doconut.convert(selector, options):
| Opção | Tipo | Padrão | Observações |
|---|---|---|---|
basePath | string | /doconut | Caminho base para os endpoints ?convert=; deve coincidir com o ramo ASP.NET onde UseDoconut() está realmente montado (normalmente coordenado através de MiddlewarePath) |
resPath | string | /doconut-res | Aceito para manter consistência de configuração com outros widgets Doconut; o widget conversor atualmente não constrói nenhuma URL a partir dele |
maxUploadMb | number | 25 | Verificação prévia apenas no cliente — rejeita um arquivo muito grande antes do upload. O servidor impõe seu próprio limite de forma independente e responde 413 se for excedido |
licenseUrl | string | null | null | Quando definido, transforma o aviso de marca‑d’água na tela de resultado em um link para esta URL |
labels | object | {} | Substitui qualquer subconjunto das strings padrão em inglês do widget (texto de arrastar, botões, anúncios aria‑live, mensagens de erro) |
Retornos de chamada:
| Retorno | Dispara quando | Carga |
|---|---|---|
onReady() | O widget renderizou sua tela ociosa/de arrastar | — |
onSourceLoaded({ token, pages, sourceExt, allowedTargets }) | ?convert=open tem sucesso | token da sessão de origem, contagem de páginas, extensão da origem (sem ponto inicial), lista de destinos permitidos |
onConverted({ downloadToken, resultToken, resultPages, downloadName, watermarked, target }) | ?convert=run tem sucesso | mesmos campos da resposta de run, mais o target que foi solicitado |
onDownload({ downloadName, downloadToken }) | O usuário clica no link Download | dispara junto ao download nativo do navegador — não intercepta nem substitui |
onError({ phase, message }) | Uma requisição open ou run falha | phase é 'open' ou 'run'; message é o erro do servidor sanitizado (ou uma mensagem do cliente para a verificação pré‑upload de tamanho) |
Doconut.convert() devolve a própria instância do widget — mantenha‑a para controlar o widget programaticamente:
const conv = Doconut.convert('#doconut-convert', { basePath: '/doconut' });
conv.reset(); // volta à tela ociosa/de arrastar; não dispara onReady novamente
conv.loadFile(file); // inicia o fluxo com um objeto File; não faz nada a menos que esteja ocioso
conv.destroy(); // remove listeners, esvazia a montagem; a instância torna‑se inutilizável após issoCrie sua própria interface
O widget é apenas um cliente para este contrato HTTP — construa sua própria interface diretamente contra ele para uma UX diferente. Todas as três rotas ficam sob o ramo ASP.NET onde UseDoconut() está montado (normalmente /doconut):
| Rota | Propósito | Resposta de sucesso |
|---|---|---|
POST ?convert=open (multipart, field file) | Enviar e abrir um documento fonte para pré‑visualização | 200 — { token, pages, sourceExt, allowedTargets } |
POST ?token=<token>&convert=run&target=<ext> | Converter a fonte armazenada para target | 200 — { downloadToken, resultToken, resultPages, downloadName, watermarked } |
GET ?convert=download&token=<downloadToken> | Transmitir o arquivo convertido | 200 — bytes do arquivo, Content-Disposition: attachment, Cache-Control: no-store |
Os bytes da fonte enviados são armazenados no servidor com TTL de 30 minutos; quando esse período expira, run responde 404 e o arquivo deve ser reaberto. O resultado convertido permanece na mesma área de armazenamento — downloadToken obtém sua própria janela fresca de 30 minutos ao término da conversão — enquanto resultToken é um token de sessão de visualizador comum cujo tempo de vida segue o cache da sessão do visualizador, independente da área de armazenamento.
sourceExt na resposta de open não tem ponto inicial (ex.: "docx") — a convenção oposta ao parâmetro sourceExtension em DocumentConverter.ConvertAsync, que requer o ponto.
Modos de falha, agrupados por rota:
| Rota | Status | Quando | Corpo |
|---|---|---|---|
| any | 404 | O widget não está habilitado (AddConverterWidget() nunca foi chamado) — verificado antes de qualquer uma das três rotas ser despachada | apenas status |
| any | 405 | Verbo HTTP incorreto (open/run exigem POST; download exige GET) | apenas status |
open | 413 | Arquivo enviado excede MaxUploadMb | { "error": "File is too large." } |
open | 400 | Corpo multipart ausente, nenhum arquivo, ou extensão de fonte que não pode ser convertida | { "error": "..." } |
run | 400 | Token malformado (não é GUID), ou um target que não pode ser analisado para um ConversionTarget | { "error": "Invalid token." } / { "error": "Unknown target format." } |
run | 400 | target não está nos allowedTargets da fonte | { "error": "That target format is not available for this file." } |
run | 404 | O upload armazenado expirou (TTL de 30 min) ou o token nunca foi aberto | { "error": "Upload expired — please re-open the file." } |
open, run | 500 | Falha interna de processamento | { "error": "<sanitized message>" } — sanitizado da mesma forma que todos os outros caminhos de erro Doconut; nunca vaza nomes internos do motor |
download | 400 | Token malformado (não é GUID) | apenas status |
download | 404 | Token de download desconhecido ou expirado | apenas status |
Propriedade do recurso
O conversor devolve um MemoryStream buscável posicionado em zero. O chamador possui esse stream e deve descartá‑lo após copiar ou devolver seu conteúdo. O serviço DocumentConverter em si é sem estado e é resolvido por injeção de dependência; não construa nem descarte o serviço manualmente.
Para o widget web, os armazenamentos de upload e download têm TTLs independentes de 30 minutos. Um resultToken do visualizador segue a duração da sessão do visualizador. Fechar um resultado do visualizador não exclui um armazenamento de download ainda válido, e redefinir o widget do navegador não estende nenhum dos TTLs.
Solução de Problemas
| Sintoma | Verificação |
|---|---|
Falha ao resolver DocumentConverter | ConverterPlugin foi registrado dentro de AddDoconut() |
| Aplicação falha durante a inicialização | A licença carregada concede Converter |
| Conversão de stream indica que o formato não é suportado | sourceExtension inclui o ponto inicial |
| JavaScript do widget carrega, mas as solicitações retornam 404 | AddConverterWidget() não foi chamado |
| Solicitações do widget usam a URL errada | basePath corresponde ao ramo onde UseDoconut() está mapeado |
| Alvo está ausente | Use allowedTargets retornado por convert=open; nem toda fonte suporta todos os alvos enum |
| Download expirado | Repita convert=open/convert=run; os tokens de armazenamento são intencionalmente temporários |
Marcação d'água
Com ConverterPlugin registrado, a licença do host está em um dos três estados:
| Estado da licença | Portão de inicialização | Saída da conversão |
|---|---|---|
Licença de visualizador paga concedendo Converter, dentro do seu período de validade | Passa | Limpo — watermarked: false |
| Licença de avaliação ativa (demo/NFR) | Passa | Converte com sucesso, marcado com a marca d'água de avaliação — watermarked: true |
Sem licença, um arquivo legado TRIAL, ou uma licença não temporária que não concede Converter | Aplicativo nunca inicia — o portão de inicialização descrito acima lança | — |
| Licença temporária/demo expirado | Registro sobrevive à expiração | Converte com a marca d'água de avaliação — watermarked: true |
Ambos os caminhos de chamada calculam a bandeira a partir da mesma regra: a fachada C# DocumentConverter a deriva internamente do estado IsViewerLicensed e IsTemporary da licença, e o manipulador ?convert=run do widget faz a verificação equivalente (IsViewerLicensed && !IsTrial && !IsTemporary) para preencher o campo watermarked que ele devolve. Uma integração pode ser construída e testada de ponta a ponta em uma licença de avaliação antes da compra — apenas os bytes de saída mudam.
Esta página foi útil?