Word-Dokumente mit JavaScript im Browser in HTML konvertieren

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

Convert Word to HTML in the browser

Word-Dokumente sind oft der Ausgangspunkt für Webinhalte – Artikel, Produktspezifikationen und Compliance-Dokumente müssen irgendwann auf einer Website verfügbar sein. Der Weg von .docx zu sauberem HTML ohne einen Backend-Konvertierungsdienst ist die eigentliche Herausforderung. Spire.Doc for JavaScript macht dies möglich, indem eine vollständige Dokumentverarbeitungs-Engine auf WebAssembly ausgeführt wird, die Word-Datei über ein virtuelles Dateisystem (VFS) gelesen wird, die Konvertierung lokal erfolgt und Sie das resultierende HTML herunterladen können – alles clientseitig, ohne Server-Roundtrip.

Zwei Exportstrategien dominieren den Workflow, und die Entscheidung zwischen ihnen ist die eigentliche Wahl:

  • Eingebetteter Modus bündelt CSS und Bilder direkt in der HTML-Datei und erzeugt ein einziges, in sich geschlossenes Dokument, das überall geöffnet werden kann.
  • Externer Modus schreibt CSS und Bilder in separate Dateien und liefert Ihnen kleineres HTML, wiederverwendbare Stylesheets und einzelne Bild-Assets, die Sie unabhängig verwalten können.

Dieser Artikel führt durch beide Ansätze in einem React-Projekt und vergleicht sie direkt miteinander. Zur Einrichtung lesen Sie Spire.Doc for JavaScript in ein React-Projekt integrieren. Die folgenden Beispiele setzen voraus, dass Spire.Doc installiert und das WebAssembly-Modul initialisiert ist.


Grundlegende Konvertierung: Alles in eine Datei einbetten

Der einfachste Weg, ein Word-Dokument als Webseite zu veröffentlichen, besteht darin, eine einzelne HTML-Datei zu erzeugen, die alles enthält – Markup, Stile und Bilder – in einem in sich geschlossenen Paket. Das ist ideal, wenn Sie ein portables Artefakt benötigen, das unabhängig vom Ort des Öffnens korrekt gerendert wird, ohne fehlende Dateiverweise oder fehlerhafte Links.

Die Konvertierung erfolgt in drei Schritten. Zuerst laden Sie die Schriftdatei und das Word-Quelldokument mit FetchFileToVFS in das virtuelle Dateisystem von WASM. Zweitens erstellen Sie eine Document-Instanz, laden die Datei, konfigurieren HtmlExportOptions so, dass sowohl CSS als auch Bilder eingebettet werden, und rufen SaveToFile auf, um das HTML zu schreiben. Drittens lesen Sie die erzeugte Datei aus dem VFS zurück, verpacken sie in ein Blob und lösen einen Browser-Download aus.

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;

Über SaveToFile aus einem Word-Dokument erzeugte HTML-Seite

HTML page generated from a Word document via SaveToFile


Exportoptionen: CSS und Bilder separat

Alles in eine Datei einzubetten ist praktisch, hat aber Nachteile. Ein großes Dokument mit vielen Bildern erzeugt eine sehr große HTML-Datei, und jede Seite, die dasselbe Styling verwendet, trägt ihre eigene Kopie des CSS mit sich. Wenn Sie Stile zentral pflegen, Bild-Assets seitenübergreifend wiederverwenden oder die HTML-Nutzlast klein halten möchten, um ein schnelleres erstes Rendering zu erreichen, sollten Sie CSS und Bilder stattdessen als separate Dateien exportieren.

HtmlExportOptions gibt Ihnen eine feingranulare Kontrolle darüber, wie jeder Ressourcentyp geschrieben wird. Sie können das CSS in eine benannte Stylesheet-Datei leiten, Bilder in ein eigenes Verzeichnis schreiben und sogar steuern, wie Formularfelder serialisiert werden. Das Ergebnis ist keine einzelne Datei mehr, sondern eine Verzeichnisstruktur mit dem HTML, dem Stylesheet und den Bilddateien.

Der Workflow entspricht dem eingebetteten Ansatz, mit zwei Ergänzungen. Erstellen Sie vor der Konvertierung ein Ausgabeverzeichnis im VFS und legen Sie mit CssStyleSheetFileName und ImagesPath fest, wohin Spire.Doc jeden Ressourcentyp schreiben soll. Lesen Sie nach der Konvertierung das gesamte Ausgabeverzeichnis rekursiv ein, packen Sie alles mit JSZip in ein Zip-Archiv und laden Sie es in einem Vorgang herunter.

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;

HTML-, CSS- und Bilddateien, die nach der Konfiguration der Exportoptionen erzeugt wurden

HTML, CSS, and image files generated after configuring the export options

Ein erwähnenswertes Detail: Spire.Doc legt Bilder nicht direkt in dem durch ImagesPath angegebenen Verzeichnis ab. Stattdessen erstellt es in diesem Verzeichnis einen Unterordner external_images, der die Bilddateien enthält. Die resultierende Struktur sieht wie Demo/external_images/*.png aus, weshalb addFilesToZip den Verzeichnisbaum rekursiv durchläuft, anstatt eine flache Dateiliste zu lesen.


Eingebettet vs. extern: Die richtige Strategie wählen

Beide Exportmodi erzeugen gültiges HTML aus demselben Word-Dokument, dienen aber unterschiedlichen Anforderungen an die Veröffentlichung. Die folgende Tabelle fasst die wichtigsten Unterschiede zusammen, damit Sie entscheiden können, welcher Ansatz zu Ihrem Workflow passt.

Aspekt Eingebettet (einzelne Datei) Extern (separate Dateien)
Ausgabe Eine .html-Datei mit Inline-CSS und Base64-Bildern HTML + .css + Bilddateien in einem Verzeichnis
Dateigröße Größer – alle Assets werden Base64-kodiert in das HTML eingebettet Kleineres HTML; die Gesamtgröße ist ähnlich, aber die Assets sind einzelne Dateien
Portabilität Vollständig eigenständig; öffnet überall korrekt, ohne Abhängigkeiten Erfordert, dass alle Dateien zusammenbleiben; relative Pfade müssen erhalten bleiben
Download-Mechanismus Download einer einzelnen Datei über Blob Download eines Zip-Archivs (z. B. mit JSZip)
Stil-Wiederverwendung Jedes Dokument trägt seine eigene Kopie des CSS mit sich Mehrere Seiten können eine gemeinsame Stylesheet-Datei nutzen
Bildverwaltung Bilder sind Base64-Strings innerhalb des HTML; sie können nicht separat referenziert oder zwischengespeichert werden Bilder sind einzelne Dateien, die zwischengespeichert, lazy geladen oder wiederverwendet werden können
Geschwindigkeit des ersten Renderns Langsamer bei großen Dokumenten – der Browser muss eine große Datei parsen Schnelleres initiales HTML-Parsing; CSS und Bilder werden parallel geladen
Am besten geeignet für E-Mail-Anhänge, einmalige Vorschauen, Archiv-Snapshots, Weitergabe eines einzelnen Dokuments CMS-Inhaltsmigration, mehrseitige Veröffentlichung, Wissensdatenbanken, Websites mit gemeinsamem Styling
Wartbarkeit Gering – eine Stiländerung bedeutet, die gesamte Datei neu zu erzeugen Hoch – die CSS-Datei einmal bearbeiten und alle verlinkten Seiten werden aktualisiert

Kurzer Entscheidungsleitfaden:

  • Wählen Sie eingebettet, wenn Sie ein einzelnes, portables Artefakt benötigen – zum Beispiel, um eine Vorschau zu erzeugen, die ein Benutzer herunterlädt und offline öffnet, oder um ein konvertiertes Dokument an eine E-Mail anzuhängen.
  • Wählen Sie extern, wenn Sie auf einer Webplattform veröffentlichen, auf der mehrere Dokumente dasselbe Designsystem verwenden, wenn Sie Bilder zwischenspeichern oder lazy laden möchten oder wenn die HTML-Dateigröße für die Performance relevant ist.

FAQ

Schriftarten im exportierten HTML stimmen nicht mit dem Originaldokument überein

Wenn die Schriftarten in Ihrem konvertierten HTML anders aussehen als in der Word-Quelldatei, liegt die Ursache fast immer in fehlenden Schriftdaten im virtuellen Dateisystem von WASM. Spire.Doc ist auf die in das VFS geladenen Schriftarten angewiesen, um während der Konvertierung präzise Layoutberechnungen und die Auflösung von Schriftartnamen durchzuführen. Wenn eine erforderliche Schriftart nicht verfügbar ist, ersetzt die Engine sie durch eine Ausweichschrift, und die font-family-Deklarationen im ausgegebenen CSS stimmen nicht mit denen des Originaldokuments überein. Bei Dokumenten, die Symbolschriftarten wie Wingdings verwenden, können die betroffenen Zeichen außerdem als unleserlicher Text dargestellt werden.

Die Lösung ist unkompliziert: Laden Sie die erforderlichen Schriftdateien vor der Konvertierung über FetchFileToVFS in das VFS vor. Verwenden Sie für Dokumente mit chinesischem, japanischem oder koreanischem Text eine Schriftart mit breiter Unicode-Abdeckung wie ARIALUNI.TTF:

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

Exportiertes HTML verliert beim Öffnen seine Stile und Bilder

Wenn Sie den externen Modus verwenden (CssStyleSheetType.External mit ImageEmbedded = false), werden die CSS- und Bilddateien an separaten Orten gespeichert, und das HTML verweist über relative Pfade darauf. Wenn Sie nur die HTML-Datei ohne die zugehörigen Ressourcen herunterladen, kann der Browser diese Pfade nicht auflösen, und die Seite fällt auf unformatierten Klartext mit defekten Bildern zurück.

Um dies zu vermeiden, sollten Sie das HTML immer zusammen mit seinem Ressourcenverzeichnis paketieren – der im Abschnitt zu den Exportoptionen gezeigte addFilesToZip-Ansatz erledigt dies, indem alles in einen einzigen Zip-Download gebündelt wird. Wenn Sie keine separaten Ressourcendateien benötigen, wechseln Sie alternativ in den eingebetteten Modus, damit alles in einer einzigen, in sich geschlossenen HTML-Datei bleibt:

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

Siehe auch