
快速概览: 本文介绍如何在 React 应用中使用 JavaScript 和 Spire.Doc WebAssembly(WASM),直接在浏览器中将 Markdown 文件或字符串转换为 HTML,无需服务器端处理。
Markdown 常用于 README 文件、技术文档、技术文章以及其他结构化内容。但在某些应用场景中,需要将这些内容转换为 HTML 文件,例如发布为网页,或交给其他基于 HTML 的工作流继续处理。
本文将介绍如何在 React 应用中使用 Spire.Doc for JavaScript 将 Markdown 转换为 HTML,主要包括以下两种常见场景:
前提条件与项目配置
步骤 1:安装 Spire.Doc for JavaScript
在 React 项目的根目录中打开终端,并通过 NPM 安装 Spire.Doc:
npm i spire.office
步骤 2:复制运行时资源
安装完成后,将 node_modules/spire.office 中的以下运行时资源复制到 React 项目的 public 目录:
- _framework
- spire.doc.js
- Spire.Doc.Wasm.zip
- spire.common.js
- Spire.Common.Wasm.zip
下面的示例还会使用 CALIBRI.ttf 进行文本渲染。请将该字体文件放置在 public/static/font/ 目录下。
对于基于文件的转换示例,请将源 Markdown 文档放置在 public/static/data/MarkdownExample.md。
有关详细的项目配置方法,请参阅 如何在 React 中集成 Spire.Doc for JavaScript。
注意: 以下示例使用
process.env.PUBLIC_URL,这是 Create React App 中常用的公共资源路径写法。如果项目使用 Vite 或其他构建工具,请根据实际项目结构调整公共资源路径。
在 React 中使用 JavaScript 将 Markdown 文件转换为 HTML
如果 Markdown 内容已经以 .md 文件形式存在,可以先将文件加载到 WebAssembly 虚拟文件系统(VFS)中,再通过 Document.LoadFromFile() 打开。随后,使用 Document.SaveToFile() 即可将文档导出为 HTML。
基于文件的转换主要分为以下四个阶段:
- 初始化模块: React 组件挂载后,加载并初始化 Spire.Doc WebAssembly 模块。
- 加载输入文件: 使用
FetchFileToVFS()将所需字体和源 Markdown 文件加载到 VFS。 - 转换文档: 使用
FileFormat.Markdown加载.md文件,并通过FileFormat.Html保存为 HTML。 - 处理输出文件: 从 VFS 中读取生成的 HTML 文件,并在浏览器中下载。
下面的示例将 MarkdownExample.md 转换为 MarkdownToHtml.html。
import React, { useState, useEffect } from 'react';
function App() {
const [wasmModule, setWasmModule] = useState(null);
// 加载 Spire.Doc
useEffect(() => {
(async () => {
try {
const publicUrl = process.env.PUBLIC_URL || '';
const spireModule = await import(
/* webpackIgnore: true */
`${publicUrl}/spire.doc.js`
);
const rawModule = spireModule.default || spireModule;
window.wasmModule =
typeof rawModule === 'function'
? await rawModule({
locateFile: (path) =>
path.endsWith('.wasm')
? `${publicUrl}/${path}`
: path
})
: rawModule;
setWasmModule(window.wasmModule);
} catch (error) {
console.error(
'Failed to load spire.doc.js WASM module:',
error
);
}
})();
}, []);
// 将 Markdown 文件转换为 HTML
const convertMarkdownFileToHtml = async () => {
const wasmModule = window.wasmModule?.spiredoc;
if (!wasmModule) return;
// 将所需字体加载到 VFS
await window.spire.FetchFileToVFS(
'CALIBRI.ttf',
'/Library/Fonts/',
`${process.env.PUBLIC_URL}/static/font/`
);
// 将 Markdown 文件加载到 VFS
const inputFileName = 'MarkdownExample.md';
await window.spire.FetchFileToVFS(
inputFileName,
'',
`${process.env.PUBLIC_URL}/static/data/`
);
// 创建 Document 实例
const doc = new wasmModule.Document();
try {
// 加载 Markdown 文档
doc.LoadFromFile({
fileName: inputFileName,
fileFormat: wasmModule.FileFormat.Markdown
});
// 设置 HTML 导出选项
doc.HtmlExportOptions.CssStyleSheetType = wasmModule.CssStyleSheetType.Internal;
doc.HtmlExportOptions.ImageEmbedded = true;
// 将文档保存为 HTML
const outputFileName = 'MarkdownToHtml.html';
doc.SaveToFile({
fileName: outputFileName,
fileFormat: wasmModule.FileFormat.Html
});
// 从 VFS 中读取生成的 HTML 文件
const htmlBytes =
window.dotnetRuntime.Module.FS.readFile(
outputFileName
);
// 下载 HTML 文件
const blob = new Blob(
[htmlBytes],
{ type: 'text/html;charset=utf-8' }
);
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = outputFileName;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
URL.revokeObjectURL(url);
} finally {
doc.Dispose();
}
};
return (
<div style={{ textAlign: 'center', height: '300px' }}>
<h1>转换 Markdown 文件为 HTML</h1>
<button
onClick={convertMarkdownFileToHtml}
disabled={!wasmModule}
>
转换并下载
</button>
</div>
);
}
export default App;
WebAssembly 模块加载完成后,点击 转换并下载。应用会从 public/static/data/ 目录加载 MarkdownExample.md,将其转换为 HTML,并下载生成的 MarkdownToHtml.html 文件。
在这一过程中,FetchFileToVFS() 用于将源 Markdown 文件加载到 WebAssembly 虚拟文件系统中,Document.LoadFromFile() 用于从 VFS 读取该文件。CssStyleSheetType.Internal 和 ImageEmbedded 用于将样式和图片直接嵌入 HTML 中,最后通过 Document.SaveToFile() 将文档导出为 HTML。
输出结果:

在 React 中使用 JavaScript 将 Markdown 字符串转换为 HTML
Markdown 内容也经常直接在应用中生成或编辑。例如,从 API 或 CMS 返回的内容可能已经是 JavaScript 字符串,而不是现有的 .md 文件。
由于 Document.LoadFromFile() 需要从 WebAssembly 虚拟文件系统中读取文件,因此可以先使用 FS.writeFile() 将 Markdown 字符串写入一个临时 .md 文件,再按照处理普通 Markdown 文件的方式完成转换。
基于字符串的转换主要包括以下五个步骤:
- 初始化模块: 加载并初始化 Spire.Doc WebAssembly 模块。
- 准备内容: 定义或获取需要转换的 Markdown 字符串。
- 创建虚拟文件: 使用 FS.writeFile() 将 Markdown 字符串写入 VFS 中的临时 .md 文件。
- 转换文档: 加载虚拟 Markdown 文件并将其保存为 HTML。
- 处理输出文件: 从 VFS 中读取 HTML 文件,根据需要进行下载或后续处理。
下面的示例将一段包含标题、列表、代码、链接和表格的 Markdown 字符串转换为 HTML。
import React, { useState, useEffect } from 'react';
function App() {
const [wasmModule, setWasmModule] = useState(null);
// 加载 Spire.Doc
useEffect(() => {
(async () => {
try {
const publicUrl = process.env.PUBLIC_URL || '';
const spireModule = await import(
/* webpackIgnore: true */
`${publicUrl}/spire.doc.js`
);
const rawModule = spireModule.default || spireModule;
window.wasmModule =
typeof rawModule === 'function'
? await rawModule({
locateFile: (path) =>
path.endsWith('.wasm')
? `${publicUrl}/${path}`
: path
})
: rawModule;
setWasmModule(window.wasmModule);
} catch (error) {
console.error(
'Failed to load spire.doc.js WASM module:',
error
);
}
})();
}, []);
// 将 Markdown 字符串转换为 HTML
const convertMarkdownStringToHtml = async () => {
const wasmModule = window.wasmModule?.spiredoc;
if (!wasmModule) return;
// 将所需字体加载到 VFS
await window.spire.FetchFileToVFS(
'CALIBRI.ttf',
'/Library/Fonts/',
`${process.env.PUBLIC_URL}/static/font/`
);
// 定义 Markdown 字符串
const markdownString = `# 项目文档
本项目提供一个**基于浏览器的文档转换工具**。
## 功能特点
- 将 Markdown 转换为 HTML
- 在浏览器中直接处理文档内容
- 导出生成的 HTML 文件
## 代码示例
\`\`\`javascript
function greet(name) {
console.log(\`你好,\${name}!\`);
}
greet("世界");
\`\`\`
## 支持的内容
| 功能 | 是否支持 |
|------|----------|
| 标题 | 是 |
| 列表 | 是 |
| 表格 | 是 |
| 链接 | 是 |
有关 Markdown 的更多信息,请访问 [Markdown 官方指南](https://www.markdownguide.org/)。
`;
const inputFileName = 'MarkdownString.md';
const outputFileName = 'MarkdownStringToHtml.html';
// 将 Markdown 字符串写入 VFS
window.dotnetRuntime.Module.FS.writeFile(
inputFileName,
markdownString,
{ encoding: 'utf8' }
);
// 创建 Document 实例
const doc = new wasmModule.Document();
try {
// 加载 Markdown 文档
doc.LoadFromFile({
fileName: inputFileName,
fileFormat: wasmModule.FileFormat.Markdown
});
// 设置 HTML 导出选项
doc.HtmlExportOptions.CssStyleSheetType = wasmModule.CssStyleSheetType.Internal;
doc.HtmlExportOptions.ImageEmbedded = true;
// 将文档保存为 HTML
doc.SaveToFile({
fileName: outputFileName,
fileFormat: wasmModule.FileFormat.Html
});
// 从 VFS 中读取生成的 HTML 文件
const htmlBytes =
window.dotnetRuntime.Module.FS.readFile(
outputFileName
);
// 下载 HTML 文件
const blob = new Blob(
[htmlBytes],
{ type: 'text/html;charset=utf-8' }
);
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = outputFileName;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
URL.revokeObjectURL(url);
} finally {
doc.Dispose();
}
};
return (
<div style={{ textAlign: 'center', height: '300px' }}>
<h1>转换 Markdown 字符串为 HTML</h1>
<button
onClick={convertMarkdownStringToHtml}
disabled={!wasmModule}
>
转换并下载
</button>
</div>
);
}
export default App;
与前一个示例不同,这里没有现成的 .md 文件需要加载,而是直接通过 FS.writeFile() 将 Markdown 内容写入 VFS:
window.dotnetRuntime.Module.FS.writeFile(
inputFileName,
markdownString,
{ encoding: 'utf8' }
);
这种方式同样适用于从 API、数据库、CMS 或文本编辑器中获取的 Markdown 内容。实际使用时,无需在代码中直接定义 markdownString,只需将获取到的 Markdown 内容传入 FS.writeFile() 即可。
输出结果:

Markdown 转 HTML 常见问题排查
在 React JavaScript 项目中,常见的转换问题通常与 WebAssembly 初始化、公共资源路径配置,或文件未正确加载到 VFS 有关。下表列出了几种常见问题以及优先检查的内容。
| 问题 | 可能原因 | 检查方法 |
|---|---|---|
spiredoc 为 undefined |
WASM 尚未初始化完成就开始执行转换 | 在 wasmModule 可用之前保持转换按钮禁用状态 |
加载运行时文件时出现 404 |
一个或多个 Spire.Doc 资源缺失,或公共资源路径配置不正确 | 检查 spire.doc.js、_framework/、WASM 资源以及浏览器的 Network 面板 |
无法加载 MarkdownExample.md |
传递给 FetchFileToVFS() 的源文件路径不正确 |
确认文件位于 public/static/data/ 目录下 |
| 字体加载失败 | 缺少 CALIBRI.ttf,或字体路径配置不正确 |
确认字体文件可以通过 public/static/font/ 路径访问 |
| 本地转换正常,但部署后失败 | 部署环境使用了不同的公共基础路径 | 检查生成的资源 URL,并调整 process.env.PUBLIC_URL 或对应构建工具中的公共路径设置 |
| 多次转换后浏览器内存持续增加 | 创建的 Document 对象未释放 |
每次转换完成后调用 doc.Dispose(),建议放在 finally 块中执行 |
常见问题
Q:如何将用户选择的 Markdown 文件转换为 HTML?
A:通过 <input type="file"> 选择的文件,与存放在应用公共资源目录中的 Markdown 文件处理方式不同。
可以先使用浏览器 File API 读取用户选择的文件:
const markdownString = await file.text();
然后使用 FS.writeFile() 将字符串写入 VFS,并按照前面的 Markdown 字符串转换流程进行处理。
Q:可以直接预览生成的 HTML,而不是下载文件吗?
A:可以。先从 VFS 中读取生成的 HTML,并对返回的字节数据进行解码:
const htmlBytes = window.dotnetRuntime.Module.FS.readFile(outputFileName);
const html = new TextDecoder('utf-8').decode(htmlBytes);
得到 HTML 字符串后,可以通过 iframe 显示:
<iframe
title="HTML Preview"
srcDoc={html}
/>
安全提示: 如果 Markdown 内容来自不受信任的用户或外部来源,应同样将生成的 HTML 视为不受信任内容。在生产环境中渲染之前,应对其进行安全过滤或采用隔离方式展示。
Q:将 Markdown 转换为 HTML 是否需要后端?
A:不需要。在上述示例中,文档处理通过 WebAssembly 直接在浏览器中完成,源 Markdown 和生成的 HTML 均通过客户端虚拟文件系统进行处理。
不过,如果应用需要存储生成的文件、读取受保护的源内容,或执行其他服务器端操作,仍然可能需要后端服务配合。
总结
本文介绍了如何在 React 中使用 JavaScript 将 Markdown 转换为 HTML,包括 Markdown 文件和 Markdown 字符串两种常见输入方式。借助 WebAssembly,可以直接在浏览器中处理来自文件、编辑器、API 或 CMS 的 Markdown 内容,并将其转换为可下载、可预览或可继续处理的 HTML。两种场景使用的是同一套核心转换逻辑,因此也便于在不同 Markdown 数据来源之间复用。







