
Los documentos de Word suelen ser el punto de partida para el contenido web: artículos, especificaciones de productos y documentos de cumplimiento, todo ello necesita eventualmente estar en un sitio web. Pasar de .docx a HTML limpio sin un servicio de conversión de backend es el desafío. Spire.Doc for JavaScript lo hace posible ejecutando un motor completo de procesamiento de documentos sobre WebAssembly, leyendo el archivo de Word a través de un sistema de archivos virtual (VFS), realizando la conversión localmente y permitiéndote descargar el HTML resultante, todo del lado del cliente, sin ida y vuelta al servidor.
Dos estrategias de exportación dominan el flujo de trabajo, y elegir entre ellas es la verdadera decisión:
- Modo integrado empaqueta CSS e imágenes directamente en el archivo HTML, produciendo un único documento autocontenido que se abre en cualquier lugar.
- Modo externo escribe CSS e imágenes en archivos separados, lo que te ofrece un HTML más pequeño, hojas de estilo reutilizables y recursos de imagen individuales que puedes gestionar de forma independiente.
Este artículo recorre ambos enfoques en un proyecto de React y los compara lado a lado. Para la configuración, consulta Integrar Spire.Doc for JavaScript en un proyecto de React. Los ejemplos a continuación asumen que Spire.Doc está instalado y que el módulo WebAssembly está inicializado.
Conversión básica: incrustar todo en un solo archivo
La forma más sencilla de publicar un documento de Word como página web es producir un único archivo HTML que contenga todo (marcado, estilos e imágenes) en un paquete autocontenido. Esto es ideal cuando necesitas un artefacto portátil que se represente correctamente sin importar dónde se abra, sin referencias a archivos faltantes ni enlaces rotos.
La conversión sigue tres pasos. Primero, carga el archivo de fuente y el documento de Word de origen en el sistema de archivos virtual de WASM usando FetchFileToVFS. Segundo, crea una instancia de Document, carga el archivo, configura HtmlExportOptions para incrustar tanto CSS como imágenes, y llama a SaveToFile para escribir el HTML. Tercero, lee el archivo generado desde VFS, envuélvelo en un Blob y activa una descarga del navegador.
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;
Página HTML generada a partir de un documento de Word mediante SaveToFile

Opciones de exportación: CSS e imágenes separados
Incrustar todo en un solo archivo es cómodo, pero tiene ventajas y desventajas. Un documento grande con muchas imágenes produce un archivo HTML muy grande, y cada página que comparte el mismo estilo lleva su propia copia duplicada del CSS. Cuando quieres mantener los estilos de forma centralizada, reutilizar recursos de imagen en varias páginas o mantener pequeño el contenido HTML para una representación inicial más rápida, deberías exportar CSS e imágenes como archivos separados en su lugar.
HtmlExportOptions te ofrece un control detallado sobre cómo se escribe cada tipo de recurso. Puedes dirigir el CSS a un archivo de hoja de estilos con nombre, enviar las imágenes a un directorio dedicado e incluso controlar cómo se serializan los campos de formulario. El resultado ya no es un solo archivo, sino una estructura de directorios que contiene el HTML, la hoja de estilos y los archivos de imagen.
El flujo de trabajo es similar al del enfoque integrado, con dos añadidos. Antes de la conversión, crea un directorio de salida en VFS y usa CssStyleSheetFileName y ImagesPath para indicarle a Spire.Doc dónde escribir cada tipo de recurso. Después de la conversión, lee todo el directorio de salida de forma recursiva, empaqueta todo en un archivo zip usando JSZip y descárgalo en una sola operación.
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;
Archivos HTML, CSS e imágenes generados después de configurar las opciones de exportación

Un detalle que vale la pena señalar: Spire.Doc no coloca las imágenes directamente en el directorio especificado por ImagesPath. En su lugar, crea una subcarpeta external_images dentro de ese directorio para contener los archivos de imagen. La estructura resultante es similar a Demo/external_images/*.png, y es por eso que addFilesToZip recorre el árbol de directorios de forma recursiva en lugar de leer una lista plana de archivos.
Integrado vs. externo: elegir la estrategia adecuada
Ambos modos de exportación producen HTML válido a partir del mismo documento de Word, pero responden a necesidades de publicación diferentes. La siguiente tabla resume las diferencias clave para ayudarte a decidir qué enfoque se adapta a tu flujo de trabajo.
| Aspecto | Integrado (archivo único) | Externo (archivos separados) |
|---|---|---|
| Salida | Un archivo .html con CSS en línea e imágenes Base64 |
HTML + .css + archivos de imagen en un directorio |
| Tamaño de archivo | Más grande: todos los recursos se codifican en Base64 dentro del HTML | HTML más pequeño; el tamaño total es similar, pero los recursos son archivos individuales |
| Portabilidad | Totalmente autocontenido; se abre correctamente en cualquier lugar sin dependencias | Requiere que todos los archivos permanezcan juntos; se deben conservar las rutas relativas |
| Mecanismo de descarga | Descarga de un solo archivo mediante Blob | Descarga de archivo zip (por ejemplo, con JSZip) |
| Reutilización de estilos | Cada documento lleva su propia copia del CSS | Varias páginas pueden compartir un único archivo de hoja de estilos |
| Gestión de imágenes | Las imágenes son cadenas Base64 dentro del HTML; no se pueden referenciar ni almacenar en caché por separado | Las imágenes son archivos individuales que se pueden almacenar en caché, cargar de forma diferida o reutilizar |
| Velocidad de representación inicial | Más lenta para documentos grandes: el navegador debe analizar un archivo grande | Análisis inicial del HTML más rápido; CSS e imágenes se cargan en paralelo |
| Ideal para | Archivos adjuntos de correo electrónico, vistas previas puntuales, instantáneas de archivo, compartir un único documento | Migración de contenido de CMS, publicación de varias páginas, bases de conocimiento, sitios con estilos compartidos |
| Mantenibilidad | Baja: cambiar un estilo implica regenerar todo el archivo | Alta: edita el archivo CSS una vez y todas las páginas vinculadas se actualizan |
Guía rápida de decisión:
- Elige el modo integrado cuando necesites un artefacto único y portátil; por ejemplo, generar una vista previa que un usuario descargue y abra sin conexión, o adjuntar un documento convertido a un correo electrónico.
- Elige el modo externo cuando publiques en una plataforma web donde varios documentos compartan el mismo sistema de diseño, donde quieras almacenar en caché o cargar de forma diferida las imágenes, o donde el tamaño del archivo HTML sea importante para el rendimiento.
Preguntas frecuentes
Las fuentes en el HTML exportado no coinciden con el documento original
Si las fuentes en tu HTML convertido se ven diferentes del archivo de Word de origen, la causa casi siempre son datos de fuente faltantes en el sistema de archivos virtual de WASM. Spire.Doc depende de las fuentes cargadas en VFS para realizar cálculos precisos de diseño y resolución de nombres de fuentes durante la conversión. Cuando una fuente requerida no está disponible, el motor sustituye una fuente de reserva, y las declaraciones font-family en el CSS de salida no coincidirán con lo que especifica el documento original. En documentos que usan fuentes de símbolos como Wingdings, los caracteres afectados también pueden mostrarse como texto ilegible.
La solución es sencilla: precarga los archivos de fuente necesarios en VFS mediante FetchFileToVFS antes de ejecutar la conversión. Para documentos que contienen texto en chino, japonés o coreano, usa una fuente con amplia cobertura Unicode, como ARIALUNI.TTF:
await window.spire.FetchFileToVFS(
'ARIALUNI.TTF', '/Library/Fonts/', '/'
);
El HTML exportado pierde sus estilos e imágenes al abrirlo
Cuando usas el modo externo (CssStyleSheetType.External con ImageEmbedded = false), los archivos CSS e imágenes se escriben en ubicaciones separadas, y el HTML los referencia mediante rutas relativas. Si descargas solo el archivo HTML sin sus recursos acompañantes, el navegador no puede resolver esas rutas y la página recurre a texto sin formato sin estilo con imágenes rotas.
Para evitar esto, empaqueta siempre el HTML junto con su directorio de recursos; el enfoque addFilesToZip que se muestra en la sección de opciones de exportación se encarga de esto al empaquetar todo en una única descarga zip. Como alternativa, si en realidad no necesitas archivos de recursos separados, cambia al modo integrado para que todo permanezca en un único archivo HTML autocontenido:
wordDocument.HtmlExportOptions.CssStyleSheetType = docModule.CssStyleSheetType.Internal;
wordDocument.HtmlExportOptions.ImageEmbedded = true;