Plugin Convertisseur

Convertir des documents en 24 formats cibles

Le plugin Converter transforme Doconut en un service de conversion de documents. Il fournit le moteur derrière la façade publique DocumentConverter et — en option — un widget prêt à l'emploi avec son propre contrat HTTP, vous permettant de convertir des documents depuis C#, depuis le widget, ou depuis une interface que vous développez vous‑même.

Installer le paquet

Installez la dernière version stable du plugin Converter :

bash
dotnet add package Doconut.NET8.Converter

Pour fixer le plugin à la version actuelle 26.7.0, indiquez la version séparément :

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

Conservez le même numéro de version que Doconut.NET8. L’identifiant du paquet est Doconut.NET8.Converter ; .26.7.0 n’apparaît que dans le nom du fichier .nupkg téléchargé.

Enregistrer le plugin

Il n’existe pas de méthode AddConverter() — le modèle de plugins de Doconut est uniforme. Chaque plugin, y compris Converter, s’enregistre de la même façon : appelez AddPlugin<TPlugin>() à l’intérieur de AddDoconut(). ConverterPlugin est fourni dans son propre paquet NuGet, Doconut.NET8.Converter, installé à côté du paquet de visualisation de base.

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

Cet appel lève une exception au démarrage si la licence est manquante, si un fichier TRIAL hérité est présent, ou si une licence non temporaire ne confère pas la capacité Converter — une InvalidOperationException levée depuis l’intérieur de AddDoconut(), avant que l’application ne serve les requêtes. Les enregistrements de démonstration/évaluation temporaires sont acceptés ; après leur expiration, la conversion reste disponible avec un filigrane. Il n’existe aucun niveau gratuit silencieux. Voir la Configuration de licence pour savoir comment les licences sont chargées.

Convertir depuis C#

Chaque conversion renvoie un MemoryStream recherchable positionné à 0, prêt à être lu ou copié immédiatement. Résolvez DocumentConverter via l’injection de dépendances où que vous en ayez besoin — il est sans état par conception, ainsi une seule instance peut être réutilisée entre les requêtes.

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

Deux détails faciles à se tromper : sourceExtension dans la surcharge de flux doit inclure le point initial (".xlsx", pas "xlsx" ) — le convertisseur le compare au catalogue de formats et une extension sans point ne sera pas résolue. Et malgré son nom, WordToHtmlAsync renvoie Task<Stream>, pas Task<string> — vous obtenez le document HTML (images intégrées en Base64) sous forme de flux, comme pour tout autre résultat de conversion.

Formats cibles

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

Tous les formats source ne se convertissent pas vers tous les formats cible — le plugin associe chaque famille de formats source (Word, Excel, PowerPoint, PDF, CAD, Image, Email, Diagram, Project/Task, PSD, document web) à son propre ensemble fixe de cibles autorisées. Ne codez pas en dur cet enum comme liste de cibles de votre UI : ?convert=open renvoie les allowedTargets réels pour le fichier qui vient d’être téléchargé, et c’est ce qui doit alimenter le sélecteur.

Widget prêt à l'emploi

Les points de terminaison ?convert=open|run|download du widget sont désactivés par défaut — sécurisés par défaut. Activez‑les côté serveur, en même temps que l’enregistrement du 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>

Sans AddConverterWidget(), les trois points de terminaison ?convert= renvoient 404 — mais le fichier JS est tout de même servi (c’est une ressource statique embarquée ; seuls les points de terminaison qu’il interroge sont protégés). AddConverterWidget() nécessite toujours que le plugin Converter soit enregistré et qu’une licence accordant Converter soit présente — il ne confère pas de droits de conversion à lui seul.

Personnaliser le widget

Options d’initialisation passées à Doconut.convert(selector, options) :

OptionTypeValeur par défautRemarques
basePathstring/doconutChemin de base pour les points de terminaison ?convert= ; il doit correspondre à la branche ASP.NET où UseDoconut() est réellement montée (généralement coordonnée via MiddlewarePath)
resPathstring/doconut-resAccepté pour la cohérence de configuration avec les autres widgets Doconut ; le widget de conversion ne construit actuellement aucune URL à partir de ce paramètre
maxUploadMbnumber25Vérification côté client uniquement — rejette un fichier trop volumineux avant l’envoi. Le serveur impose sa propre limite indépendamment et renvoie 413 si elle est dépassée
licenseUrlstring | nullnullLorsqu’elle est définie, transforme l’avertissement de filigrane sur l’écran de résultat en un lien vers cette URL
labelsobject{}Remplace tout sous‑ensemble des chaînes par défaut anglaises du widget (texte d’invite, boutons, annonces aria‑live, messages d’erreur)

Rappels :

RappelSe déclenche quandCharge utile
onReady()Le widget a rendu son écran d’attente/inactif
onSourceLoaded({ token, pages, sourceExt, allowedTargets })?convert=open réussitjeton de session source, nombre de pages, extension source (sans point), liste des cibles autorisées
onConverted({ downloadToken, resultToken, resultPages, downloadName, watermarked, target })?convert=run réussitmêmes champs que la réponse du run, plus le target demandé
onDownload({ downloadName, downloadToken })L’utilisateur clique sur le lien Téléchargerse déclenche en même temps que le téléchargement natif du navigateur — il n’intercepte pas et ne le remplace pas
onError({ phase, message })Une requête open ou run échouephase vaut 'open' ou 'run' ; message est l’erreur serveur assainie (ou un message côté client pour la vérification de taille)

Doconut.convert() renvoie l’instance du widget elle‑même — conservez‑la pour piloter le widget par programme :

javascript
const conv = Doconut.convert('#doconut-convert', { basePath: '/doconut' });
conv.reset();         // revient à l’écran d’attente/inactif ; ne relance pas onReady
conv.loadFile(file);  // démarre le flux avec un objet File ; aucun effet si le widget n’est pas inactif
conv.destroy();       // supprime les écouteurs, vide le montage ; l’instance devient inutilisable après cela

Construire votre propre interface

Le widget n’est qu’un client pour ce contrat HTTP — construisez votre propre interface directement contre celui‑ci pour offrir une UX différente. Les trois routes se trouvent sous la branche ASP.NET où UseDoconut() est montée (généralement /doconut) :

RouteObjectifRéponse réussie
POST ?convert=open (multipart, champ file)Télécharger et ouvrir un document source pour prévisualisation200 — { token, pages, sourceExt, allowedTargets }
POST ?token=<token>&convert=run&target=<ext>Convertir la source stockée en target200 — { downloadToken, resultToken, resultPages, downloadName, watermarked }
GET ?convert=download&token=<downloadToken>Diffuser le fichier converti200 — octets du fichier, Content-Disposition: attachment, Cache-Control: no-store

Les octets source sont stockés côté serveur avec un TTL de 30 minutes ; une fois ce délai écoulé, run renvoie 404 et le fichier doit être ré‑ouvert. Le résultat converti vit dans le même stockage — downloadToken obtient son propre nouveau créneau de 30 minutes à la fin de la conversion — tandis que resultToken est un jeton de session de visualisation ordinaire dont la durée suit le cache de session du visualiseur, indépendamment du stockage.

sourceExt dans la réponse open n’a pas de point initial (ex. "docx" ) — l’inverse de la convention du paramètre sourceExtension de DocumentConverter.ConvertAsync, qui en requiert un.

Modes d’échec, regroupés par route :

RouteStatutQuandCorps
any404Le widget n’est pas activé (AddConverterWidget() n’a jamais été appelé) — vérifié avant le dispatch des trois routesstatut uniquement
any405Verbe HTTP incorrect (open/run nécessitent POST ; download nécessite GET)statut uniquement
open413Le fichier téléchargé dépasse MaxUploadMb{ "error": "File is too large." }
open400Aucun corps multipart, aucun fichier, ou une extension source non convertible{ "error": "..." }
run400Jeton mal formé (pas un GUID), ou un target qui ne peut pas être analysé en ConversionTarget{ "error": "Invalid token." } / { "error": "Unknown target format." }
run400target absent des allowedTargets de la source{ "error": "That target format is not available for this file." }
run404Le stockage de l’upload a expiré (TTL 30 min) ou le jeton n’a jamais été ouvert{ "error": "Upload expired — please re-open the file." }
open, run500Échec de traitement interne{ "error": "<sanitized message>" } — assaini de la même façon que chaque autre chemin d’erreur Doconut ; ne divulgue jamais les noms internes du moteur
download400Jeton mal formé (pas un GUID)statut uniquement
download404Jeton de téléchargement inconnu ou expiréstatut uniquement

Propriété des ressources

Le convertisseur renvoie un MemoryStream recherchable positionné à zéro. L’appelant possède ce flux et doit le libérer après en avoir copié ou renvoyé le contenu. Le service DocumentConverter lui‑même est sans état et est résolu via l’injection de dépendances ; ne le construisez ni ne le libérez manuellement.

Pour le widget web, les stockages d’upload et de téléchargement possèdent chacun un TTL indépendant de 30 minutes. Un resultToken de visualiseur suit la durée de vie de la session du visualiseur. Fermer un résultat de visualiseur ne supprime pas un stockage de téléchargement encore valide, et réinitialiser le widget du navigateur n’étend aucune des deux durées.

Dépannage

SymptômeVérification
La résolution de DocumentConverter échoueL’enregistrement de ConverterPlugin a eu lieu à l’intérieur de AddDoconut()
L’application échoue au démarrageLa licence chargée accorde Converter
La conversion de flux indique que le format n’est pas pris en chargesourceExtension inclut le point initial
Le JavaScript du widget se charge mais les requêtes renvoient 404AddConverterWidget() n’a pas été appelé
Les requêtes du widget utilisent une mauvaise URLbasePath correspond à la branche où UseDoconut() est mappée
Une cible est manquanteUtilisez les allowedTargets renvoyés par convert=open ; toutes les sources ne supportent pas chaque cible d’enum
Le téléchargement a expiréRépétez convert=open/convert=run ; les jetons de stockage sont intentionnellement temporaires

Filigrane

Avec ConverterPlugin enregistré, la licence de l’hôte se trouve dans l’un des trois états :

État de la licenceBarrière de démarrageSortie de conversion
Licence de visualisation payante accordant Converter, dans sa période de validitéPassePropre — watermarked: false
Licence d’évaluation active (démo/NFR)PasseConvertit avec le filigrane d’évaluation — watermarked: true
Sans licence, fichier TRIAL hérité, ou licence non temporaire qui n’accorde pas ConverterL’application ne démarre jamais — la barrière décrite ci‑dessus lève une exception
Licence temporaire/démo expiréeL’enregistrement survit à l’expirationConvertit avec le filigrane d’évaluation — watermarked: true

Les deux chemins de calcul déterminent le drapeau de la même façon : la façade C# DocumentConverter le déduit en interne à partir des états IsViewerLicensed et IsTemporary de la licence, et le gestionnaire ?convert=run du widget effectue la vérification équivalente (IsViewerLicensed && !IsTrial && !IsTemporary) pour remplir le champ watermarked renvoyé. Une intégration peut être construite et testée de bout en bout avec une licence d’évaluation avant l’achat — seuls les octets de sortie changent.

Cette page vous a-t-elle été utile ?