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:

bash
dotnet add package Doconut.NETStandard.Converter

Para fixar o plugin na versão atual 26.8.0, passe a versão separadamente:

bash
dotnet add package Doconut.NETStandard.Converter --version 26.8.0

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

csharp
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 TRIAL ou a licença não temporária não concede a capacidade Converter — uma InvalidOperationException lançada de dentro de AddDoconut(), 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.

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

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:

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

Esse 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:

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>

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çãoTipoPadrãoObservações
basePathstring/doconutCaminho base para os endpoints ?convert=; deve coincidir com o ramo ASP.NET onde UseDoconut() está realmente montado (normalmente coordenado através de MiddlewarePath)
resPathstring/doconut-resAceito para manter consistência de configuração com outros widgets Doconut; o widget conversor atualmente não constrói nenhuma URL a partir dele
maxUploadMbnumber25Verificaçã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
licenseUrlstring | nullnullQuando definido, transforma o aviso de marca‑d’água na tela de resultado em um link para esta URL
labelsobject{}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:

RetornoDispara quandoCarga
onReady()O widget renderizou sua tela ociosa/de arrastar—
onSourceLoaded({ token, pages, sourceExt, allowedTargets })?convert=open tem sucessotoken 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 sucessomesmos campos da resposta de run, mais o target que foi solicitado
onDownload({ downloadName, downloadToken })O usuário clica no link Downloaddispara junto ao download nativo do navegador — não intercepta nem substitui
onError({ phase, message })Uma requisição open ou run falhaphase é '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:

javascript
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 isso

Crie 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):

RotaPropósitoResposta de sucesso
POST ?convert=open (multipart, field file)Enviar e abrir um documento fonte para pré‑visualização200 — { token, pages, sourceExt, allowedTargets }
POST ?token=<token>&convert=run&target=<ext>Converter a fonte armazenada para target200 — { downloadToken, resultToken, resultPages, downloadName, watermarked }
GET ?convert=download&token=<downloadToken>Transmitir o arquivo convertido200 — 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:

RotaStatusQuandoCorpo
any404O widget não está habilitado (AddConverterWidget() nunca foi chamado) — verificado antes de qualquer uma das três rotas ser despachadaapenas status
any405Verbo HTTP incorreto (open/run exigem POST; download exige GET)apenas status
open413Arquivo enviado excede MaxUploadMb{ "error": "File is too large." }
open400Corpo multipart ausente, nenhum arquivo, ou extensão de fonte que não pode ser convertida{ "error": "..." }
run400Token malformado (não é GUID), ou um target que não pode ser analisado para um ConversionTarget{ "error": "Invalid token." } / { "error": "Unknown target format." }
run400target não está nos allowedTargets da fonte{ "error": "That target format is not available for this file." }
run404O upload armazenado expirou (TTL de 30 min) ou o token nunca foi aberto{ "error": "Upload expired — please re-open the file." }
open, run500Falha interna de processamento{ "error": "<sanitized message>" } — sanitizado da mesma forma que todos os outros caminhos de erro Doconut; nunca vaza nomes internos do motor
download400Token malformado (não é GUID)apenas status
download404Token de download desconhecido ou expiradoapenas 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

SintomaVerificação
Falha ao resolver DocumentConverterConverterPlugin foi registrado dentro de AddDoconut()
Aplicação falha durante a inicializaçãoA licença carregada concede Converter
Conversão de stream indica que o formato não é suportadosourceExtension inclui o ponto inicial
JavaScript do widget carrega, mas as solicitações retornam 404AddConverterWidget() não foi chamado
Solicitações do widget usam a URL erradabasePath corresponde ao ramo onde UseDoconut() está mapeado
Alvo está ausenteUse allowedTargets retornado por convert=open; nem toda fonte suporta todos os alvos enum
Download expiradoRepita 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çaPortão de inicializaçãoSaída da conversão
Licença de visualizador paga concedendo Converter, dentro do seu período de validadePassaLimpo — watermarked: false
Licença de avaliação ativa (demo/NFR)PassaConverte 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 ConverterAplicativo nunca inicia — o portão de inicialização descrito acima lança—
Licença temporária/demo expiradoRegistro sobrevive à expiraçãoConverte 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?