Convertire documenti Word in HTML nel browser con JavaScript

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

Convertire Word in HTML nel browser

I documenti Word sono spesso il punto di partenza per i contenuti web: articoli, specifiche di prodotto e documenti di conformità devono prima o poi finire su un sito web. Passare da .docx a HTML pulito senza un servizio di conversione lato backend è la vera sfida. Spire.Doc for JavaScript lo rende possibile eseguendo un motore completo di elaborazione dei documenti su WebAssembly, leggendo il file Word attraverso un file system virtuale (VFS), eseguendo la conversione localmente e permettendoti di scaricare l'HTML risultante — tutto lato client, senza alcun passaggio al server.

Due strategie di esportazione dominano il flusso di lavoro, e scegliere tra esse è la vera decisione:

  • Modalità incorporata: raggruppa CSS e immagini direttamente nel file HTML, producendo un unico documento autonomo che si apre ovunque.
  • Modalità esterna: scrive CSS e immagini in file separati, offrendoti un HTML più leggero, fogli di stile riutilizzabili e singoli asset immagine che puoi gestire in modo indipendente.

Questo articolo illustra entrambi gli approcci in un progetto React e li confronta fianco a fianco. Per la configurazione, fai riferimento a Integrare Spire.Doc for JavaScript in un progetto React. Gli esempi seguenti presuppongono che Spire.Doc sia installato e che il modulo WebAssembly sia inizializzato.


Conversione di base: incorporare tutto in un unico file

Il modo più semplice per pubblicare un documento Word come pagina web è produrre un unico file HTML che contenga tutto — markup, stili e immagini — in un unico pacchetto autonomo. Questo è l'ideale quando hai bisogno di un artefatto portatile che venga visualizzato correttamente ovunque venga aperto, senza riferimenti a file mancanti o link interrotti.

La conversione segue tre passaggi. Innanzitutto, carica il file dei font e il documento Word di origine nel file system virtuale WASM usando FetchFileToVFS. In secondo luogo, crea un'istanza Document, carica il file, configura HtmlExportOptions per incorporare sia il CSS sia le immagini e chiama SaveToFile per scrivere l'HTML. In terzo luogo, rileggi il file generato dal VFS, avvolgilo in un Blob e attiva il download dal browser.

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;

Pagina HTML generata da un documento Word tramite SaveToFile

Pagina HTML generata da un documento Word tramite SaveToFile


Opzioni di esportazione: CSS e immagini separati

Incorporare tutto in un unico file è comodo, ma presenta dei compromessi. Un documento di grandi dimensioni con molte immagini produce un file HTML molto pesante, e ogni pagina che condivide lo stesso stile porta con sé una copia duplicata del CSS. Quando vuoi mantenere gli stili in modo centralizzato, riutilizzare gli asset immagine tra più pagine o mantenere il payload HTML ridotto per un rendering iniziale più rapido, è invece preferibile esportare CSS e immagini come file separati.

HtmlExportOptions ti offre un controllo granulare su come viene scritto ciascun tipo di risorsa. Puoi indirizzare il CSS verso un file di foglio di stile denominato, inviare le immagini in una directory dedicata e persino controllare come vengono serializzati i campi modulo. Il risultato non è più un singolo file ma una struttura di directory contenente l'HTML, il foglio di stile e i file immagine.

Il flusso di lavoro rispecchia l'approccio incorporato, con due aggiunte. Prima della conversione, crea una directory di output nel VFS e usa CssStyleSheetFileName e ImagesPath per indicare a Spire.Doc dove scrivere ciascun tipo di risorsa. Dopo la conversione, leggi ricorsivamente l'intera directory di output, impacchetta tutto in un archivio zip usando JSZip e scaricalo con un'unica operazione.

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;

File HTML, CSS e immagini generati dopo la configurazione delle opzioni di esportazione

File HTML, CSS e immagini generati dopo la configurazione delle opzioni di esportazione

Un dettaglio da notare: Spire.Doc non inserisce le immagini direttamente nella directory specificata da ImagesPath. Crea invece una sottocartella external_images all'interno di quella directory per contenere i file immagine. La struttura risultante è simile a Demo/external_images/*.png, ed è per questo che addFilesToZip percorre l'albero delle directory in modo ricorsivo anziché leggere un elenco piatto di file.


Incorporato vs. esterno: scegliere la strategia giusta

Entrambe le modalità di esportazione producono HTML valido dallo stesso documento Word, ma rispondono a diverse esigenze di pubblicazione. La tabella seguente riassume le differenze principali per aiutarti a decidere quale approccio si adatta al tuo flusso di lavoro.

Aspetto Incorporato (file singolo) Esterno (file separati)
Output Un file .html con CSS inline e immagini in Base64 HTML + .css + file immagine in una directory
Dimensione del file Maggiore — tutti gli asset sono codificati in Base64 nell'HTML HTML più leggero; la dimensione totale è simile ma gli asset sono file individuali
Portabilità Completamente autonomo; si apre correttamente ovunque senza dipendenze Richiede che tutti i file rimangano insieme; i percorsi relativi devono essere preservati
Meccanismo di download Download di un singolo file tramite Blob Download di un archivio zip (ad es. con JSZip)
Riutilizzo degli stili Ogni documento porta con sé la propria copia del CSS Più pagine possono condividere un unico file di foglio di stile
Gestione delle immagini Le immagini sono stringhe Base64 all'interno dell'HTML; non possono essere referenziate o memorizzate separatamente nella cache Le immagini sono file individuali che possono essere memorizzati nella cache, caricati in modo lazy o riutilizzati
Velocità di rendering iniziale Più lenta per documenti di grandi dimensioni — il browser deve analizzare un unico file di grandi dimensioni Analisi iniziale dell'HTML più rapida; CSS e immagini si caricano in parallelo
Ideale per Allegati email, anteprime occasionali, snapshot di archivio, condivisione di un singolo documento Migrazione di contenuti CMS, pubblicazione multi-pagina, knowledge base, siti con stili condivisi
Manutenibilità Bassa — modificare uno stile significa rigenerare l'intero file Alta — modifica il file CSS una volta e tutte le pagine collegate si aggiornano

Guida rapida alla scelta:

  • Scegli la modalità incorporata quando hai bisogno di un unico artefatto portatile — ad esempio, per generare un'anteprima che l'utente scarica e apre offline, o per allegare un documento convertito a un'email.
  • Scegli la modalità esterna quando pubblichi su una piattaforma web in cui più documenti condividono lo stesso design system, quando vuoi memorizzare le immagini nella cache o caricarle in modo lazy, o quando la dimensione del file HTML influisce sulle prestazioni.

Domande frequenti

I font nell'HTML esportato non corrispondono al documento originale

Se i font nell'HTML convertito appaiono diversi dal file Word di origine, la causa è quasi sempre la mancanza dei dati dei font nel file system virtuale WASM. Spire.Doc si affida ai font caricati nel VFS per eseguire calcoli accurati del layout e la risoluzione dei nomi dei font durante la conversione. Quando un font richiesto non è disponibile, il motore sostituisce un font di fallback e le dichiarazioni font-family nel CSS di output non corrisponderanno a quelle specificate nel documento originale. Per i documenti che utilizzano font simbolici come Wingdings, i caratteri interessati possono anche essere visualizzati come testo illeggibile.

La soluzione è semplice: precarica i file dei font necessari nel VFS tramite FetchFileToVFS prima di eseguire la conversione. Per i documenti contenenti testo cinese, giapponese o coreano, usa un font con ampia copertura Unicode come ARIALUNI.TTF:

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

L'HTML esportato perde gli stili e le immagini quando viene aperto

Quando usi la modalità esterna (CssStyleSheetType.External con ImageEmbedded = false), i file CSS e immagine vengono scritti in posizioni separate e l'HTML li referenzia tramite percorsi relativi. Se scarichi solo il file HTML senza le risorse che lo accompagnano, il browser non può risolvere quei percorsi e la pagina ricade su testo semplice senza stile con immagini mancanti.

Per evitarlo, impacchetta sempre l'HTML insieme alla sua directory di risorse — l'approccio addFilesToZip mostrato nella sezione delle opzioni di esportazione lo gestisce raggruppando tutto in un unico download zip. In alternativa, se in realtà non hai bisogno di file di risorse separati, passa alla modalità incorporata in modo che tutto rimanga in un unico file HTML autonomo:

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

Vedi anche