RTF 是一种以纯文本记录内容的富文本格式,字体、段落、表格与页面设置都以可读的标记写在文件里,几乎所有文字处理软件都能打开。系统之间的数据对接、旧版工具的导入导出、邮件网关的内容传递,至今仍经常以 RTF 作为交换格式。
把 RTF 纳入文档处理流程,需要解决两个方向的问题:把 Word 文档导出成 RTF 交给下游系统,以及把拿到的 RTF 重新变成可以编辑的 Word 文档或便于分发的 PDF。本文用 Spire.Doc for JavaScript 在浏览器中完成这三件事,示例使用两份文档:WordToRtf.docx 是《“云雀”客户服务中心 2026 年第三季度运营报告》,含封面信息表、指标表格、柱状图与页眉页脚;Legacy.rtf 是旧系统导出的一份《设备巡检记录单》,含巡检路线图、三张明细表与交接说明。整个过程基于 WebAssembly 在浏览器端完成,无需安装 Office,也不依赖任何后端,文档留在用户的设备上。
本文介绍三个功能点:
有关安装和项目配置,请参考 React 项目中集成 Spire.Doc for JavaScript。下面的示例假定 Spire.Doc 已安装、WebAssembly 模块已初始化。
将 Word 文档转换为 RTF
将 Word 文档转换为 RTF,核心是在保存时把目标格式指定为 FileFormat.Rtf。加载环节与处理普通 docx 没有区别,Document 对象从 Word 文件读入后,原样写出即可,不需要逐段重建内容。
三个方向用到的格式枚举如下,后文两节同样从这张表取值:
| 格式枚举 | 数值 | 用途 |
|---|---|---|
FileFormat.Rtf |
120 | 保存为 RTF,或按 RTF 加载 |
FileFormat.Docx2013 |
12 | 保存为 docx |
FileFormat.PDF |
100 | 保存为 PDF |
具体操作步骤如下:
- 获取 Spire.Doc 的 WASM 模块,确认已就绪。
- 把中文字体与待转换的
WordToRtf.docx载入 VFS。 - 创建
Document实例并加载 Word 文档。 - 以
FileFormat.Rtf保存到 VFS,扩展名使用.rtf。 - 从 VFS 读出结果文件并触发浏览器下载。
将 Word 文档转换为 RTF 的代码如下:
function App() {
const wordToRtf = async () => {
// 获取 Spire.Doc 的 WASM 模块
const docModule = window.wasmModule?.spiredoc;
if (!docModule) {
alert('Spire.Doc is not ready yet');
return;
}
// 载入中文字体与待转换的文档
await window.spire.FetchFileToVFS('msyh.ttc', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
await window.spire.FetchFileToVFS('msyhbd.ttc', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
await window.spire.FetchFileToVFS('WordToRtf.docx', '', `${process.env.PUBLIC_URL}/data/`);
// 加载 Word 文档
const doc = new docModule.Document();
doc.LoadFromFile('WordToRtf.docx');
// 以 RTF 格式保存
const outputFileName = 'WordToRtf.rtf';
doc.SaveToFile({ fileName: outputFileName, fileFormat: docModule.FileFormat.Rtf });
doc.Dispose();
// 从 VFS 读取结果文件,触发下载
const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
const blob = new Blob([fileArray], { type: 'application/rtf' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = outputFileName;
a.click();
URL.revokeObjectURL(url);
};
return (
<div style={{ textAlign: 'center', height: '300px' }}>
<h1>Word 转 RTF</h1>
<button onClick={wordToRtf}>生成</button>
</div>
);
}
export default App;
生成的 RTF 在 Word 中打开后共两页,封面信息表、指标表格、柱状图与页眉页脚都在,版式与原稿接近:

转换后的 RTF 保留了哪些内容
示例中的报告从 docx 换成 RTF 之后,以下内容在 Word 中打开时保持原样:
- 文字、字体、字号与段落格式;
- 表格的行列结构、边框与单元格底纹;
- 内嵌图片与图表;
- 页眉、页脚与页面尺寸、页边距。
RTF 的表达能力停留在传统字处理的范围之内,原稿中的信息不一定全部进入 RTF。转换完成后建议在 Word 中打开结果核对一遍,确认下游系统依赖的内容都在;需要完整还原原件时,应保留 docx,把 RTF 交给只需要文字与基础版式的下游系统。
为什么生成的 RTF 文件更大
RTF 是纯文本格式,图片无法以二进制直接放入,只能转成十六进制字符写在文件里。示例中的报告原稿为 67 KB,转换后的 RTF 约为 3.7 MB,体积放大的部分主要来自内嵌的柱状图。需要控制体积时,可以在转换前压缩图片,或把图片尺寸缩小到实际排版所需的大小。
文件名与 MIME 类型需要一致
RTF 的 MIME 类型为 application/rtf,扩展名应为 .rtf。若沿用 .doc 扩展名,部分系统会按二进制 Word 文件解析而报错;下载时若声明的类型为 application/msword,浏览器可能交给本地组件打开,行为与预期不一致。
将 RTF 文档转换为 Word
将 RTF 文档转换为 Word,通过 LoadRtf 载入 RTF 文档,再以 FileFormat.Docx2013 保存。从旧系统导出的 RTF 往往需要重新编辑、套用模板或插入批注,转成 docx 之后可以继续使用 Word 的样式、修订与内容控件,也便于与其他文档合并。
具体操作步骤如下:
- 获取 Spire.Doc 的 WASM 模块,确认已就绪。
- 把中文字体与
Legacy.rtf载入 VFS。 - 创建
Document实例,使用LoadRtf显式加载 RTF。 - 以
FileFormat.Docx2013保存为 docx。 - 从 VFS 读出结果文件并触发浏览器下载。
将 RTF 文档转换为 Word 的代码如下:
function App() {
const rtfToWord = async () => {
// 获取 Spire.Doc 的 WASM 模块
const docModule = window.wasmModule?.spiredoc;
if (!docModule) {
alert('Spire.Doc is not ready yet');
return;
}
// 载入中文字体与 RTF 文件
await window.spire.FetchFileToVFS('msyh.ttc', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
await window.spire.FetchFileToVFS('msyhbd.ttc', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
await window.spire.FetchFileToVFS('Legacy.rtf', '', `${process.env.PUBLIC_URL}/data/`);
// 显式按 RTF 加载,参数为 VFS 中的文件名
const doc = new docModule.Document();
doc.LoadRtf('Legacy.rtf');
// 另存为 docx
const outputFileName = 'Legacy.docx';
doc.SaveToFile({ fileName: outputFileName, fileFormat: docModule.FileFormat.Docx2013 });
doc.Dispose();
// 从 VFS 读取结果文件,触发下载
const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
const blob = new Blob([fileArray], {
type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
});
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = outputFileName;
a.click();
URL.revokeObjectURL(url);
};
return (
<div style={{ textAlign: 'center', height: '300px' }}>
<h1>RTF 转 Word</h1>
<button onClick={rtfToWord}>生成</button>
</div>
);
}
export default App;
转换后的文档共两页,巡检路线图、三张明细表、页眉页脚与交接签名都完整保留:

LoadRtf 与 LoadFromFile 的三种加载方式
RTF 既可以显式加载,也可以交给 LoadFromFile 按格式或按扩展名识别。三种写法在示例中的输出一致,差别在于显式程度与出错时的提示:
| 写法 | 调用形式 | 适用情况 |
|---|---|---|
| 显式加载 | doc.LoadRtf('Legacy.rtf') |
文件扩展名不规范,或需要指定编码 |
| 按格式加载 | doc.LoadFromFile({ fileName, fileFormat: FileFormat.Rtf }) |
扩展名不可信,但格式已知 |
| 自动识别 | doc.LoadFromFile('Legacy.rtf') |
扩展名规范、逻辑统一的场景 |
LoadRtf 的参数是 VFS 中的文件名,不是 RTF 的文本内容。把读到的 RTF 字符串直接传进去,会得到 IO_FileNotFound_FileName 异常,因为库把它当成了路径去查找。
转换后表格底纹会丢失
RTF 用 \clcbpat 标记单元格底色,示例中的 RTF 一共带了 86 处。经 Spire.Doc 转换后,docx 中的底纹不再保留,表格回退为白底。若表头原本依赖「深色底 + 白色文字」的对比,转换后文字就与背景同为白色,看上去像是空白行。
处理方式是让表头不依赖底色:使用深色文字配浅色填充,或直接使用加粗文字加边框。示例中的三张明细表已按此设置,因此转换后表头仍然清晰可读。
字体需要一并载入 VFS
RTF 的 \fonttbl 只记录字体名称,不包含字体文件。转换时若 VFS 中缺少对应字体,排版会改用替代字体,换行与分页可能与原稿不同。示例在转换前把 msyh.ttc 载入 /Library/Fonts/;文档中用到其他字体时,把对应的字体文件一并载入即可。
将 RTF 文档转换为 PDF
将 RTF 文档转换为 PDF,流程与上一节完全相同,只把保存格式换成 FileFormat.PDF,不需要先保存成 docx 再转一次。PDF 适合归档与对外发送,转换后不再依赖字体与编辑软件,接收方看到的分页即为最终结果。
具体操作步骤如下:
- 获取 Spire.Doc 的 WASM 模块,确认已就绪。
- 把中文字体与
Legacy.rtf载入 VFS。 - 创建
Document实例,使用LoadRtf加载 RTF。 - 以
FileFormat.PDF保存到 VFS。 - 从 VFS 读出 PDF 并触发浏览器下载。
将 RTF 文档转换为 PDF 的代码如下:
function App() {
const rtfToPdf = async () => {
// 获取 Spire.Doc 的 WASM 模块
const docModule = window.wasmModule?.spiredoc;
if (!docModule) {
alert('Spire.Doc is not ready yet');
return;
}
// 载入中文字体与 RTF 文件
await window.spire.FetchFileToVFS('msyh.ttc', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
await window.spire.FetchFileToVFS('msyhbd.ttc', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
await window.spire.FetchFileToVFS('Legacy.rtf', '', `${process.env.PUBLIC_URL}/data/`);
// 加载 RTF
const doc = new docModule.Document();
doc.LoadRtf('Legacy.rtf');
// 直接输出 PDF
const outputFileName = 'Legacy.pdf';
doc.SaveToFile({ fileName: outputFileName, fileFormat: docModule.FileFormat.PDF });
doc.Dispose();
// 从 VFS 读取结果文件,触发下载
const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
const blob = new Blob([fileArray], { type: 'application/pdf' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = outputFileName;
a.click();
URL.revokeObjectURL(url);
};
return (
<div style={{ textAlign: 'center', height: '300px' }}>
<h1>RTF 转 PDF</h1>
<button onClick={rtfToPdf}>生成</button>
</div>
);
}
export default App;
导出的 PDF 共两页,页眉、巡检路线图与三张明细表都在,可以直接分发:

三个方向的调用对照
三个功能点的代码结构一致:加载、保存、下载。差异只在加载入口与保存格式:
| 方向 | 加载 | 保存 |
|---|---|---|
| Word 文档 → RTF | LoadFromFile('WordToRtf.docx') |
SaveToFile({ fileName, fileFormat: FileFormat.Rtf }) |
| RTF 文档 → Word | LoadRtf('Legacy.rtf') |
SaveToFile({ fileName, fileFormat: FileFormat.Docx2013 }) |
| RTF 文档 → PDF | LoadRtf('Legacy.rtf') |
SaveToFile({ fileName, fileFormat: FileFormat.PDF }) |
批量处理时,为每个文件单独创建 Document,处理完成后立即调用 Dispose(),避免多个文档实例同时占用 WASM 内存。
分页与页眉页脚是否保留
RTF 中记录的页面尺寸、页边距与页眉页脚会带入 PDF,示例的 PDF 为 A4 两页,页眉与页脚都在。分页位置与 Word 中打开同一份 RTF 时可能略有差异:PDF 的排版由 Spire.Doc 的排版引擎完成,字体度量与 Word 不完全一致,长表格跨页的位置因此可能前后移动。对分页敏感的文件,建议对照生成的 PDF 复核,必要时在 RTF 中先固定页面设置,或把跨页表格拆分。
常见问题
转换 RTF 时,文件需要上传到服务器吗
本文的用法不需要上传。Spire.Doc for JavaScript 基于 WebAssembly 在浏览器端运行,文档通过虚拟文件系统(VFS)在本地读写,加载、转换、保存都在本地完成,库本身不会把文件发往服务器。文件最终是否会离开设备,取决于你在页面上另外接入的代码。
生成的 RTF 文件为什么比 docx 大很多
原因:RTF 是纯文本格式,图片只能以十六进制字符嵌入,同样一张图在 RTF 中占用的体积远大于 docx 的压缩存储。示例中的运营报告原稿为 67 KB,转成 RTF 后约为 3.7 MB,其中绝大部分来自柱状图。
解决:转换前压缩图片或缩小图片尺寸;只需要文字与表格的场景,可以先删除图片再保存。
LoadRtf 为什么提示 IO_FileNotFound_FileName
原因:LoadRtf 的参数是虚拟文件系统(VFS)中的文件名,而不是 RTF 的文本内容。文件名没有先通过 FetchFileToVFS 写入 VFS,或传入的是以 {\rtf1 开头的字符串,库都会按路径查找并报这个错。
解决:先把文件载入 VFS,再把同一个文件名交给 LoadRtf;文件名保持与载入时一致:
await window.spire.FetchFileToVFS('Legacy.rtf', '', `${process.env.PUBLIC_URL}/data/`);
const doc = new docModule.Document();
doc.LoadRtf('Legacy.rtf');
RTF 转成 Word 后,表格的表头文字看不见了
原因:RTF 用单元格底色标记表头,Spire.Doc 转换后不再保留这部分底纹。原来靠「深色底 + 白色文字」做对比的表头,底色消失后文字与背景同为白色,看起来就是空白行。
解决:把表头改用深色文字,配合浅色填充或边框;已经拿到结果文档的,可以在 Word 中选中表头单元格,重新设置字体颜色或底纹。
RTF 转 PDF 的分页和 Word 里看到的不一样
原因:RTF 保留了页面尺寸、页边距与页眉页脚,但 PDF 由 Spire.Doc 的排版引擎生成,字体度量与 Word 存在差异,长表格或紧邻页尾的段落可能落在不同的页上。
解决:对照生成的 PDF 检查分页;对分页要求严格的文档,可以在转换前调整页面设置、压缩段前段后间距,或把跨页的表格拆成两张。
获取免费许可证
如果您希望删除结果文档中的评估消息,或者摆脱功能限制,请该Email地址已收到反垃圾邮件插件保护。要显示它您需要在浏览器中启用JavaScript。获取有效期 30 天的临时许可证。







