Plugin Conversor
Converta documentos para 24 formatos-alvo
O plugin Converter 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 a versão estável mais recente do plugin Converter:
dotnet add package Doconut.NET6.ConverterPara fixar o plugin na versão atual 26.7.0, passe a versão separadamente:
dotnet add package Doconut.NET6.Converter --version 26.7.0Mantenha o pacote Converter na mesma versão que o Doconut.NET6. O ID do pacote é
Doconut.NET6.Converter; .26.7.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. Todo plugin, inclusive o Converter, registra‑se da mesma forma: chame AddPlugin<TPlugin>() dentro de AddDoconut(). O ConverterPlugin é distribuído em seu próprio pacote NuGet, Doconut.NET6.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 lança uma exceção na inicialização se a licença estiver ausente, se houver um arquivo legado
TRIALou se a licença não‑temporária não conceder a capacidadeConverter— umaInvalidOperationExceptiongerada dentro deAddDoconut(), antes que o aplicativo atenda solicitações. Registros temporários de demonstração/NFR são aceitos; após seu vencimento, a conversão continua disponível com saída marcada por marca d'água. Não há nível gratuito silencioso. Consulte License Setup 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 a partir do DI onde precisar — ele é sem estado por design, portanto uma única instância pode ser reutilizada com segurança entre requisições.
// 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 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 embutidas como Base64) como stream, assim como todo resultado de conversão.
Formatos de destino
Pdf, Docx, Doc, Html, Xlsx, Pptx, Png, Jpeg, Csv, Tiff, Bmp, Gif, Svg, Xml,
Txt, Xls, Jp2, Rtf, Odt, Ods, Odp, Epub, Xps, WebpNem todo formato de origem converte para todo destino — o plugin mapeia a família de formato de cada 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 que deve alimentar um seletor.
Widget pronto para uso
Os endpoints ?convert=open|run|download do widget são opcionais e vêm desativados por padrão — seguros por padrão. Habilite‑os no servidor, junto ao 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= respondem 404 — mas o arquivo JS ainda é servido (é um recurso estático embutido; apenas os endpoints que ele chama são restritos). AddConverterWidget() ainda requer que o plugin Converter esteja registrado e que a licença 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 via 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é‑vaga apenas no cliente — rejeita arquivos excessivamente grandes antes do upload. O servidor impõe seu próprio limite independentemente e responde 413 se for ultrapassado |
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 arraste, botões, anúncios aria‑live, mensagens de erro) |
Callbacks:
| Callback | Dispara quando | Payload |
|---|---|---|
onReady() | O widget renderizou sua tela ociosa/de arraste | — |
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), lista de destinos permitidos |
onConverted({ downloadToken, resultToken, resultPages, downloadName, watermarked, target }) | ?convert=run tem sucesso | mesmos campos da resposta de run, mais o target 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 sanitizado do servidor (ou uma mensagem do cliente para a verificação pré‑vaga 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 arraste; não dispara onReady novamente
conv.loadFile(file); // inicia o fluxo com um objeto File; não faz nada se não estiver ocioso
conv.destroy(); // remove listeners, esvazia a montagem; a instância fica inutilizável após issoConstruir seu próprio frontend
O widget é apenas um cliente para este contrato HTTP — construa seu próprio frontend contra ele diretamente 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, campo 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; ao expirar esse período, run responde 404 e o arquivo deve ser reaberto. O resultado convertido permanece na mesma stash — downloadToken recebe sua própria janela fresca de 30 minutos quando a conversão termina — enquanto resultToken é um token de sessão de visualizador comum cujo tempo de vida segue o cache da sessão do visualizador, independente da stash.
sourceExt na resposta de open não tem ponto inicial (ex.: "docx") — a convenção oposta ao parâmetro sourceExtension de 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 errado (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, sem arquivo, ou extensão da fonte que não pode ser convertida | { "error": "..." } |
run | 400 | Token malformado (não é GUID), ou target que não pode ser convertido para um ConversionTarget | { "error": "Invalid token." } / { "error": "Unknown target format." } |
run | 400 | target não está em allowedTargets da fonte | { "error": "That target format is not available for this file." } |
run | 404 | O upload armazenado expirou (TTL 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 do 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 dos recursos
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 via injeção de dependência; não construa nem descarte o serviço manualmente.
Para o widget web, as stashes de upload e download têm TTLs independentes de 30 minutos. Um resultToken de visualizador segue a vida da sessão do visualizador. Fechar um resultado de visualizador não exclui uma stash de download ainda válida, e redefinir o widget no navegador não estende nenhum dos TTLs.
Solução de problemas
| Sintoma | Verificação |
|---|---|
Falha ao resolver DocumentConverter | O registro de ConverterPlugin ocorreu 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 requisições retornam 404 | AddConverterWidget() não foi chamado |
| Requisiçõ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 origem suporta todos os alvos do enum |
| Download expirado | Repita convert=open/convert=run; os tokens de stash 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 | Gate de inicialização | Saída da conversão |
|---|---|---|
Licença de visualizador paga concedendo Converter, dentro do 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, arquivo legado TRIAL, ou licença não‑temporária que não concede Converter | Aplicação nunca inicia — o gate de inicialização descrito acima lança exceção | — |
| Licença Temporária/Demo expirada | Registro sobrevive ao vencimento | 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 devolve. Uma integração pode ser construída e testada de ponta a ponta com uma licença de avaliação antes da compra — apenas os bytes de saída mudam.
Esta página foi útil?