
Markdown 常用于编写文档、README 文件、笔记以及其他结构化内容。但当内容需要打印、归档或以固定版式进行分享时,PDF 往往更加实用。
在 React 应用中,可以使用 Spire.Doc for JavaScript 将 Markdown 转换为 PDF。该库通过 WebAssembly(WASM)运行,可直接在浏览器本地处理 Markdown 内容并生成 PDF,无需将文件发送到服务器。
本文主要介绍以下三种常见转换场景:
在 React 中配置 Spire.Doc for JavaScript
在开始转换 Markdown 文件之前,需要先将 Spire.Doc for JavaScript 集成到 React 项目中,并准备所需的 WebAssembly 运行时文件。
有关详细的配置方法,请参阅 如何在 React 中集成 Spire.Doc for JavaScript。
步骤 1:安装所需包
在 React 项目的根目录中打开终端,并通过 npm 安装所需包:
npm i spire.office
步骤 2:添加所需运行时文件
将 node_modules/spire.office 中的以下文件和文件夹复制到项目的 public 目录:
_framework
spire.doc.js
Spire.Doc.Wasm.zip
spire.common.js
Spire.Common.Wasm.zip
下面的示例还会使用 SimSun.ttf 进行 PDF 文本渲染。请将字体文件放置在:
public/static/font/
对于基于文件的转换示例,请将 Markdown 示例文件放置在:
public/static/data/
相关项目结构如下:
public/
├── _framework/
├── spire.doc.js
├── Spire.Doc.Wasm.zip
├── spire.common.js
├── Spire.Common.Wasm.zip
└── static/
├── data/
│ └── MarkdownExample_CN.md
└── font/
└── SimSun.ttf
注意: 以下示例使用
process.env.PUBLIC_URL,这是 Create React App 中的常用写法。如果项目使用 Vite 或其他构建工具,请根据实际情况调整公共资源路径。
使用 JavaScript 将 Markdown 文件转换为 PDF
将 Markdown 文件转换为 PDF 的流程主要分为以下四个步骤:
- 将所需字体和 Markdown 文件加载到 WASM 虚拟文件系统(VFS)中。
- 调用
Document.LoadFromFile()方法,并指定输入格式为FileFormat.Markdown,将 Markdown 文件加载到Document对象中。 - 调用
Document.SaveToFile()方法,并指定输出格式为FileFormat.PDF,将加载后的文档保存为 PDF 文件。 - 从 VFS 中读取生成的 PDF,并在浏览器中下载。
以下 JavaScript 示例演示如何加载 .md 文件并将其保存为 .pdf 文件:
import React, { useEffect, useState } from 'react';
function App() {
const [wasmModule, setWasmModule] = useState(null);
// 初始化 Spire.Doc WebAssembly 模块
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(
'加载 Spire.Doc WASM 模块失败:',
error
);
}
})();
}, []);
// 下载 WASM 虚拟文件系统中生成的文件
const downloadVfsFile = (fileName, mimeType) => {
const fileData =
window.dotnetRuntime.Module.FS.readFile(fileName);
const blob = new Blob(
[fileData],
{ type: mimeType }
);
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = fileName;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
URL.revokeObjectURL(url);
};
const convertMarkdownToPdf = async () => {
const docModule = window.wasmModule?.spiredoc;
if (!docModule) return;
const publicUrl = process.env.PUBLIC_URL || '';
// 将字体加载到 VFS
await window.spire.FetchFileToVFS(
'SimSun.ttf',
'/Library/Fonts/',
`${publicUrl}/static/font/`
);
const inputFileName = 'MarkdownExample_CN.md';
const outputFileName = 'MarkdownToPDF.pdf';
// 将 Markdown 文件加载到 VFS
await window.spire.FetchFileToVFS(
inputFileName,
'',
`${publicUrl}/static/data/`
);
const doc = new docModule.Document();
try {
// 加载 Markdown 文件
doc.LoadFromFile({
fileName: inputFileName,
fileFormat: docModule.FileFormat.Markdown
});
// 将文档保存为 PDF
doc.SaveToFile({
fileName: outputFileName,
fileFormat: docModule.FileFormat.PDF
});
// 下载生成的 PDF
downloadVfsFile(
outputFileName,
'application/pdf'
);
} finally {
doc.Dispose();
}
};
return (
<div style={{ textAlign: 'center', padding: '40px' }}>
<h1>将 Markdown 转换为 PDF</h1>
<button
onClick={convertMarkdownToPdf}
disabled={!wasmModule}
>
转换并下载 PDF
</button>
</div>
);
}
export default App;
运行应用,等待 WASM 模块加载完成后,点击 转换并下载 PDF,应用会加载 MarkdownExample_CN.md,将其转换为 MarkdownToPDF.pdf,并在浏览器中下载。
输出结果
生成的 PDF 会保留 Markdown 中的主要结构,包括标题、段落、列表和表格等:

将 Markdown 转换为 PDF 并自定义页面设置
很多时候,默认页面布局并不一定适合所有场景。例如,包含宽表格的 Markdown 报告可能更适合横向页面,而用于打印的文档则可能需要指定纸张大小或页边距。
加载 Markdown 文件后,可以获取文档中的节(Section),并在生成 PDF 前调整其 PageSetup 属性。
下面的示例将第一个节设置为 A4 纸张、横向页面,并将四周页边距设置为 50 磅:
const section = doc.Sections.get_Item(0);
// 设置页面大小
section.PageSetup.PageSize =
docModule.PageSize.A4();
// 设置页面方向
section.PageSetup.Orientation =
docModule.PageOrientation.Landscape;
// 设置页边距
section.PageSetup.Margins.All = 50;
要在 Markdown 转 PDF 过程中应用这些设置,可以使用下面的函数:
const convertMarkdownToPdfWithPageSettings = async () => {
const docModule = window.wasmModule?.spiredoc;
if (!docModule) return;
const publicUrl = process.env.PUBLIC_URL || '';
// 将字体加载到 VFS
await window.spire.FetchFileToVFS(
'SimSun.ttf',
'/Library/Fonts/',
`${publicUrl}/static/font/`
);
const inputFileName = 'MarkdownExample_CN.md';
const outputFileName =
'MarkdownToPDFWithPageSettings.pdf';
// 将 Markdown 文件加载到 VFS
await window.spire.FetchFileToVFS(
inputFileName,
'',
`${publicUrl}/static/data/`
);
const doc = new docModule.Document();
try {
// 加载 Markdown 文件
doc.LoadFromFile({
fileName: inputFileName,
fileFormat: docModule.FileFormat.Markdown
});
// 获取第一个节
const section = doc.Sections.get_Item(0);
// 设置页面大小
section.PageSetup.PageSize =
docModule.PageSize.A4();
// 设置为横向页面
section.PageSetup.Orientation =
docModule.PageOrientation.Landscape;
// 将所有页边距设置为 50 磅
section.PageSetup.Margins.All = 50;
// 将文档保存为 PDF
doc.SaveToFile({
fileName: outputFileName,
fileFormat: docModule.FileFormat.PDF
});
// 下载生成的 PDF
downloadVfsFile(
outputFileName,
'application/pdf'
);
} finally {
doc.Dispose();
}
};
您可以根据 Markdown 文档的实际内容调整页面大小、方向和页边距。
使用 JavaScript 将 Markdown 字符串转换为 PDF
Markdown 内容不一定来自现有的 .md 文件。在 React 应用中,内容也可能来自 Markdown 编辑器、文本框、CMS、API 响应或应用状态,并以字符串形式存在。
这种情况下,可以先使用 FS.writeFile() 将 Markdown 字符串写入 WebAssembly 虚拟文件系统中的临时 .md 文件,再按照普通 Markdown 文件的方式将其转换为 PDF。
下面的示例将一段包含标题、列表和表格的 Markdown 字符串转换为 PDF:
const convertMarkdownStringToPdf = async () => {
const docModule = window.wasmModule?.spiredoc;
if (!docModule) return;
const publicUrl = process.env.PUBLIC_URL || '';
// 将字体加载到 VFS
await window.spire.FetchFileToVFS(
'SimSun.ttf',
'/Library/Fonts/',
`${publicUrl}/static/font/`
);
const markdownString = `# 项目记录
此 PDF 由 **React 应用中的 Markdown 字符串**生成。
## 待办事项
- 检查初稿
- 导出最终版本
- 分享 PDF
## 任务状态
| 项目 | 状态 |
| --- | --- |
| 初稿 | 已完成 |
| 审核 | 待处理 |
`;
const inputFileName = 'MarkdownInput.md';
const outputFileName = 'MarkdownStringToPDF.pdf';
// 将 Markdown 字符串写入 VFS
window.dotnetRuntime.Module.FS.writeFile(
inputFileName,
markdownString,
{ encoding: 'utf8' }
);
const doc = new docModule.Document();
try {
// 加载虚拟 Markdown 文件
doc.LoadFromFile({
fileName: inputFileName,
fileFormat: docModule.FileFormat.Markdown
});
// 将文档保存为 PDF
doc.SaveToFile({
fileName: outputFileName,
fileFormat: docModule.FileFormat.PDF
});
// 下载生成的 PDF
downloadVfsFile(
outputFileName,
'application/pdf'
);
} finally {
doc.Dispose();
}
};
在实际应用中,可以将示例字符串替换为现有数据源中的 Markdown 内容,例如:
const markdownString = editorValue;
或者:
const markdownString = apiResponse.content;
其余 PDF 转换流程保持不变。
输出结果

为什么需要将字体加载到 VFS?
生成 PDF 时需要使用字体数据来正确渲染文本。因此,上面的示例在处理 Markdown 文档之前,会先将 SimSun.ttf 加载到 WebAssembly 虚拟文件系统:
await window.spire.FetchFileToVFS(
'SimSun.ttf',
'/Library/Fonts/',
`${publicUrl}/static/font/`
);
如果 Markdown 中包含当前字体不支持的字符,还需要将相应字体加载到 /Library/Fonts/。在生成包含中文、日文、韩文、阿拉伯文或其他多语言文本的 PDF 时,这一点尤其重要。
常见问题
Q:可以将用户上传的 Markdown 文件转换为 PDF 吗?
A:可以。无需从 public 目录加载固定的 .md 文件,可以先在浏览器中读取用户上传的 Markdown 文件,将其内容写入 WASM 虚拟文件系统,再使用 Document.LoadFromFile() 加载。这样,用户就可以直接在 React 应用中选择并转换自己的 Markdown 文件。
Q:为什么生成的 PDF 中缺少部分字符?
A:通常是因为 WASM 环境中没有用于显示这些字符的字体。请在生成 PDF 前,将支持 Markdown 中相应字符的字体加载到 /Library/Fonts/。
Q:Markdown 中的宽表格在 PDF 中被截断怎么办?
A:可以尝试将页面设置为横向、减小页边距,或使用更大的页面尺寸后再保存为 PDF。
Q:为什么 Markdown 中的图片没有出现在 PDF 中?
A:Markdown 通常通过文件路径或 URL 引用图片,而不是直接嵌入图片数据。请确保转换过程中能够访问 Markdown 中引用的图片文件,并且转换环境可以正确解析相应路径。如果使用相对图片路径,根据 Markdown 文件和图片文件的实际存放位置,可能需要额外处理路径。
Q:Markdown 转 PDF 是否在浏览器本地运行?
A:是。在上述 React 示例中,Spire.Doc for JavaScript 通过 WebAssembly 运行,Markdown 输入和生成的 PDF 都通过浏览器端的虚拟文件系统进行处理。转换本身不需要后端服务器。不过,如果应用还需要存储生成的文件、进行身份验证或执行其他服务器端操作,仍然可以配合后端服务使用。
总结
本文介绍了如何在 React 应用中使用 JavaScript 将 Markdown 转换为 PDF,包括基础文件转换、自定义页面设置,以及 Markdown 字符串转换。
借助 Spire.Doc for JavaScript,开发者可以加载 Markdown 内容、控制 PDF 页面布局,并通过 WebAssembly 直接在浏览器中生成 PDF。该方式适用于文档工具、Markdown 编辑器、报告系统,以及其他需要将 Markdown 内容导出为 PDF 的应用。
获取免费许可证
如果希望在不受评估版限制的情况下完整体验 Spire.Doc for JavaScript 的功能,可以申请 30 天免费试用许可证。







