Convertir des documents Word en HTML dans le navigateur avec JavaScript

2026-09-30 09:25:51 Allen Yang
AI Summarize:
ChatGPT
ChatGPT ✓
Claude ✓
Grok ✓
Perplexity ✓
Quick
Quick
Concise overview
Highlights
Key takeaways
Detailed
Structured explanation
Brief
One sentence summary
Summarize |

Convertir Word en HTML dans le navigateur

Les documents Word sont souvent le point de départ du contenu web — articles, spécifications produit et documents de conformité doivent tous finir par vivre sur un site web. Passer d'un fichier .docx à un HTML propre sans service de conversion côté serveur, voilà le défi. Spire.Doc for JavaScript rend cela possible en exécutant un moteur complet de traitement de documents sur WebAssembly, en lisant le fichier Word via un système de fichiers virtuel (VFS), en effectuant la conversion localement et en vous permettant de télécharger le HTML obtenu — le tout côté client, sans aller-retour vers un serveur.

Deux stratégies d'exportation dominent le flux de travail, et c'est le choix entre elles qui constitue la véritable décision :

  • Le mode intégré regroupe le CSS et les images directement dans le fichier HTML, produisant un document unique et autonome qui s'ouvre partout.
  • Le mode externe écrit le CSS et les images dans des fichiers séparés, ce qui donne un HTML plus léger, des feuilles de style réutilisables et des ressources d'images individuelles que vous pouvez gérer indépendamment.

Cet article présente les deux approches dans un projet React et les compare côte à côte. Pour l'installation, reportez-vous à Intégrer Spire.Doc for JavaScript dans un projet React. Les exemples ci-dessous supposent que Spire.Doc est installé et que le module WebAssembly est initialisé.


Conversion de base : tout intégrer dans un seul fichier

La façon la plus simple de publier un document Word sous forme de page web consiste à produire un seul fichier HTML contenant tout — balisage, styles et images — dans un ensemble autonome. C'est idéal lorsque vous avez besoin d'un artefact portable qui s'affiche correctement où qu'il soit ouvert, sans références de fichiers manquants ni liens brisés.

La conversion se déroule en trois étapes. Premièrement, chargez le fichier de police et le document Word source dans le système de fichiers virtuel WASM à l'aide de FetchFileToVFS. Deuxièmement, créez une instance Document, chargez le fichier, configurez HtmlExportOptions pour intégrer à la fois le CSS et les images, puis appelez SaveToFile pour écrire le HTML. Troisièmement, relisez le fichier généré depuis le VFS, encapsulez-le dans un Blob et déclenchez un téléchargement dans le navigateur.

function App() {
  const wordToHtml = async () => {
    // Get the Spire.Doc WASM module
    const docModule = window.wasmModule?.spiredoc;

    // Check if the module is ready
    if (!docModule) {
      alert('Spire.Doc is not ready yet');
      return;
    }

    // Load fonts and the Word file into VFS
    await window.spire.FetchFileToVFS('ARIALUNI.TTF', '/Library/Fonts/', `${process.env.PUBLIC_URL}/static/font/`);
    const inputFileName = 'ToHtml.docx';
    await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}/static/data/`);

    // Load the Word document
    const wordDocument = new docModule.Document();
    wordDocument.LoadFromFile(inputFileName);

    // Embed the CSS styles into the HTML and embed images as Base64
    wordDocument.HtmlExportOptions.CssStyleSheetType = docModule.CssStyleSheetType.Internal;
    wordDocument.HtmlExportOptions.ImageEmbedded = true;

    // Convert the document to HTML
    const outputFileName = 'ToHtml-result.html';
    wordDocument.SaveToFile({ fileName: outputFileName, fileFormat: docModule.FileFormat.Html });

    // Read the converted file from VFS and trigger download
    const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
    const blob = new Blob([fileArray], { type: 'text/html;charset=utf-8' });
    const url = URL.createObjectURL(blob);
    const a = window.document.createElement('a');
    a.href = url;
    a.download = outputFileName;
    a.click();
    URL.revokeObjectURL(url);

    // Release resources
    wordDocument.Dispose();
  };

  return (
    <div style={{ textAlign: 'center', height: '300px' }}>
      <h1>Convert Word To HTML</h1>
      <button onClick={wordToHtml}>
        Generate
      </button>
    </div>
  );
}

export default App;

Page HTML générée à partir d'un document Word via SaveToFile

Page HTML générée à partir d'un document Word via SaveToFile


Options d'exportation : séparer le CSS et les images

Tout intégrer dans un seul fichier est pratique, mais cela présente des compromis. Un document volumineux contenant de nombreuses images produit un fichier HTML très lourd, et chaque page qui partage le même style transporte sa propre copie dupliquée du CSS. Lorsque vous souhaitez maintenir les styles de manière centralisée, réutiliser les ressources d'images entre les pages ou garder la charge utile HTML réduite pour un rendu initial plus rapide, vous devriez plutôt exporter le CSS et les images dans des fichiers séparés.

HtmlExportOptions vous offre un contrôle précis sur la manière dont chaque type de ressource est écrit. Vous pouvez diriger le CSS vers un fichier de feuille de style nommé, envoyer les images vers un répertoire dédié et même contrôler la façon dont les champs de formulaire sont sérialisés. Le résultat n'est plus un fichier unique mais une structure de répertoires contenant le HTML, la feuille de style et les fichiers d'images.

Le flux de travail reprend celui de l'approche intégrée, avec deux ajouts. Avant la conversion, créez un répertoire de sortie dans le VFS et utilisez CssStyleSheetFileName et ImagesPath pour indiquer à Spire.Doc où écrire chaque type de ressource. Après la conversion, lisez l'intégralité du répertoire de sortie de manière récursive, empaquetez le tout dans une archive zip à l'aide de JSZip, puis téléchargez-la en une seule opération.

import JSZip from 'jszip';

function App() {
  const wordToHtmlWithOptions = async () => {
    // Get the Spire.Doc WASM module
    const docModule = window.wasmModule?.spiredoc;

    // Check if the module is ready
    if (!docModule) {
      alert('Spire.Doc is not ready yet');
      return;
    }

    // Load fonts and the Word file into VFS
    await window.spire.FetchFileToVFS('ARIALUNI.TTF', '/Library/Fonts/', `${process.env.PUBLIC_URL}/static/font/`);
    const inputFileName = 'ToHtml.docx';
    await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}/static/data/`);

    // Create the output directory in VFS
    const outputDirectoryName = 'ToHTMLFolder/';
    window.dotnetRuntime.Module.FS.mkdirTree(outputDirectoryName);

    // Load the Word document
    const wordDocument = new docModule.Document();
    wordDocument.LoadFromFile(inputFileName);

    // Export the CSS styles to a separate file
    wordDocument.HtmlExportOptions.CssStyleSheetFileName = outputDirectoryName + 'sample.css';
    wordDocument.HtmlExportOptions.CssStyleSheetType = docModule.CssStyleSheetType.External;

    // Export images to a separate directory
    wordDocument.HtmlExportOptions.ImageEmbedded = false;
    wordDocument.HtmlExportOptions.ImagesPath = outputDirectoryName + 'Demo/';

    // Export form fields as plain text
    wordDocument.HtmlExportOptions.IsTextInputFormFieldAsText = true;

    // Convert the document to HTML
    const outputFileName = 'ToHtmlExportOption-out.html';
    wordDocument.SaveToFile({ fileName: outputFileName, fileFormat: docModule.FileFormat.Html });

    // Release resources
    wordDocument.Dispose();

    // Read the output directory recursively and write each level of files into the zip
    const zip = new JSZip();
    const addFilesToZip = async (folderPath, zipFolder) => {
      let items = await window.dotnetRuntime.Module.FS.readdir(folderPath);
      items = items.filter((item) => item !== '.' && item !== '..');
      for (const item of items) {
        const itemPath = `${folderPath}/${item}`;
        try {
          const fileData = await window.dotnetRuntime.Module.FS.readFile(itemPath);
          zipFolder.file(item, fileData);
        } catch (error) {
          const zipSubFolder = zipFolder.folder(item);
          await addFilesToZip(itemPath, zipSubFolder);
        }
      }
    };

    // Package the HTML file together with the resource directory
    zip.file(outputFileName, window.dotnetRuntime.Module.FS.readFile(outputFileName));
    await addFilesToZip(outputDirectoryName, zip);
    const zipBlob = await zip.generateAsync({ type: 'blob' });
    const url = URL.createObjectURL(zipBlob);

    // Trigger download
    const a = window.document.createElement('a');
    a.href = url;
    a.download = 'ToHTMLFolder.zip';
    a.click();
    URL.revokeObjectURL(url);
  };

  return (
    <div style={{ textAlign: 'center', height: '300px' }}>
      <h1>Convert Word To HTML With Export Options</h1>
      <button onClick={wordToHtmlWithOptions}>
        Generate
      </button>
    </div>
  );
}

export default App;

Fichiers HTML, CSS et images générés après configuration des options d'exportation

Fichiers HTML, CSS et images générés après configuration des options d'exportation

Un détail mérite d'être signalé : Spire.Doc ne place pas les images directement dans le répertoire spécifié par ImagesPath. Il crée à la place un sous-dossier external_images dans ce répertoire pour y stocker les fichiers d'images. La structure obtenue ressemble à Demo/external_images/*.png, ce qui explique pourquoi addFilesToZip parcourt l'arborescence des répertoires de manière récursive plutôt que de lire une liste plate de fichiers.


Intégré ou externe : choisir la bonne stratégie

Les deux modes d'exportation produisent un HTML valide à partir du même document Word, mais ils répondent à des besoins de publication différents. Le tableau ci-dessous résume les principales différences pour vous aider à déterminer quelle approche convient à votre flux de travail.

Aspect Intégré (fichier unique) Externe (fichiers séparés)
Sortie Un fichier .html avec du CSS en ligne et des images en Base64 HTML + .css + fichiers d'images dans un répertoire
Taille du fichier Plus grande — toutes les ressources sont encodées en Base64 dans le HTML HTML plus léger ; la taille totale est similaire, mais les ressources sont des fichiers individuels
Portabilité Entièrement autonome ; s'ouvre correctement partout, sans aucune dépendance Nécessite que tous les fichiers restent ensemble ; les chemins relatifs doivent être préservés
Mécanisme de téléchargement Téléchargement d'un seul fichier via Blob Téléchargement d'une archive zip (par exemple avec JSZip)
Réutilisation des styles Chaque document transporte sa propre copie du CSS Plusieurs pages peuvent partager une même feuille de style
Gestion des images Les images sont des chaînes Base64 à l'intérieur du HTML ; elles ne peuvent pas être référencées ni mises en cache séparément Les images sont des fichiers individuels qui peuvent être mis en cache, chargés à la demande ou réutilisés
Vitesse de rendu initial Plus lente pour les documents volumineux — le navigateur doit analyser un seul gros fichier Analyse initiale du HTML plus rapide ; le CSS et les images se chargent en parallèle
Idéal pour Pièces jointes d'e-mails, aperçus ponctuels, instantanés d'archivage, partage d'un document unique Migration de contenu CMS, publication multi-pages, bases de connaissances, sites aux styles partagés
Maintenabilité Faible — modifier un style implique de régénérer tout le fichier Élevée — modifiez le fichier CSS une fois et toutes les pages liées sont mises à jour

Guide de décision rapide :

  • Choisissez le mode intégré lorsque vous avez besoin d'un artefact unique et portable — par exemple, générer un aperçu qu'un utilisateur télécharge et ouvre hors ligne, ou joindre un document converti à un e-mail.
  • Choisissez le mode externe lorsque vous publiez sur une plateforme web où plusieurs documents partagent le même système de design, où vous souhaitez mettre en cache ou charger à la demande les images, ou lorsque la taille du fichier HTML importe pour les performances.

FAQ

Les polices du HTML exporté ne correspondent pas au document d'origine

Si les polices de votre HTML converti semblent différentes de celles du fichier Word source, la cause est presque toujours l'absence de données de police dans le système de fichiers virtuel WASM. Spire.Doc s'appuie sur les polices chargées dans le VFS pour effectuer des calculs de mise en page précis et la résolution des noms de polices lors de la conversion. Lorsqu'une police requise n'est pas disponible, le moteur la remplace par une police de secours, et les déclarations font-family dans le CSS de sortie ne correspondront pas à ce que spécifie le document d'origine. Pour les documents qui utilisent des polices symboliques telles que Wingdings, les caractères concernés peuvent également s'afficher sous forme de texte illisible.

La solution est simple : préchargez les fichiers de polices nécessaires dans le VFS via FetchFileToVFS avant de lancer la conversion. Pour les documents contenant du texte chinois, japonais ou coréen, utilisez une police à large couverture Unicode telle qu'ARIALUNI.TTF :

await window.spire.FetchFileToVFS(
  'ARIALUNI.TTF', '/Library/Fonts/', '/'
);

Le HTML exporté perd ses styles et ses images à l'ouverture

Lorsque vous utilisez le mode externe (CssStyleSheetType.External avec ImageEmbedded = false), les fichiers CSS et d'images sont écrits à des emplacements séparés, et le HTML y fait référence via des chemins relatifs. Si vous ne téléchargez que le fichier HTML sans les ressources qui l'accompagnent, le navigateur ne peut pas résoudre ces chemins et la page retombe sur du texte brut sans style, avec des images brisées.

Pour éviter cela, empaquetez toujours le HTML avec son répertoire de ressources — l'approche addFilesToZip présentée dans la section sur les options d'exportation s'en charge en regroupant le tout dans un seul téléchargement zip. Sinon, si vous n'avez pas réellement besoin de fichiers de ressources séparés, passez en mode intégré pour que tout reste dans un seul fichier HTML autonome :

wordDocument.HtmlExportOptions.CssStyleSheetType = docModule.CssStyleSheetType.Internal;
wordDocument.HtmlExportOptions.ImageEmbedded = true;

Voir aussi