脚注是 Word 文档中常用的注释工具,用于在页面底部对正文内容进行补充说明或标注引用来源。Spire.Doc for JavaScript 基于 WebAssembly 在浏览器端直接完成脚注的插入、格式设置与移除操作,通过虚拟文件系统(VFS)管理输入输出文件,无需后端服务支持。
本文介绍三个核心功能点:
有关安装和项目配置,请参考 React 项目中集成 Spire.Doc for JavaScript。以下示例默认已安装 Spire.Doc 并完成 WebAssembly 模块初始化。
插入脚注
插入脚注是在文档中添加注释信息的基础操作,适合对特定术语、引用来源或补充说明进行标注。Spire.Doc for JavaScript 通过 AppendFootnote 方法创建脚注,并允许开发者精确控制脚注插入的位置、脚注正文的文本内容以及脚注标记(上标数字)的显示样式。
function App() {
const insertFootnote = async () => {
// 获取 Spire.Doc WASM 模块
const docModule = window.wasmModule?.spiredoc;
// 检查模块是否就绪
if (!wasmModule) {
alert('Spire.Doc is not ready yet');
return;
}
const inputFileName = 'SampleB_2.docx';
await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}/data/`);
// 加载文档
const doc = new docModule.Document();
doc.LoadFromFile(inputFileName);
// 查找文档中第一个匹配的字符串
let selection = doc.FindString("Spire.Doc", false, true);
// 获取匹配文本所在的 TextRange
let textRange = selection.GetAsOneRange();
// 获取匹配文本所在的段落
let paragraph = textRange.OwnerParagraph;
// 获取 TextRange 在段落中的索引位置
let index = paragraph.ChildObjects.IndexOf(textRange);
// 在段落中追加一个脚注
let footnote = paragraph.AppendFootnote({ type: docModule.FootnoteType.Footnote });
// 将脚注插入到匹配文本之后
paragraph.ChildObjects.Insert(index + 1, footnote);
// 在脚注文本体中添加内容
textRange = footnote.TextBody.AddParagraph().AppendText("欢迎来评估Spire.Doc");
// 设置脚注内容的文字格式
textRange.CharacterFormat.FontName = "Arial Black";
textRange.CharacterFormat.FontSize = 10;
textRange.CharacterFormat.TextColor = docModule.Color.get_DarkGray();
// 设置脚注标记(上标数字)的格式
footnote.MarkerCharacterFormat.FontName = "Calibri";
footnote.MarkerCharacterFormat.FontSize = 12;
footnote.MarkerCharacterFormat.Bold = true;
footnote.MarkerCharacterFormat.TextColor = docModule.Color.get_DarkGreen();
// 定义输出文件名
const outputFileName = "InsertFootnote.docx";
// 保存文档
doc.SaveToFile({ fileName: outputFileName, fileFormat: docModule.FileFormat.Docx2013 });
// 释放资源
doc.Dispose();
// 从 VFS 读取生成的文件,触发下载
const modifiedFileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
const blob = new Blob([modifiedFileArray], { 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>插入脚注。</h1>
<button onClick={insertFootnote}>
Generate
</button>
</div>
);
}
export default App;
通过 AppendFootnote 方法插入脚注后,页面底部会显示注释内容,同时正文中的对应位置出现上标脚注标记。

设置脚注位置与编号格式
Word 文档的脚注默认采用阿拉伯数字(1, 2, 3...)编号,并在每页底部连续显示。但在学术论文、技术手册或排版要求严格的出版物中,往往需要按章节或页面重新编号、使用字母或罗马数字等不同的编号格式,甚至将脚注集中放置在节(Section)的末尾而非页面底部。Spire.Doc for JavaScript 通过 FootnoteOptions 对象提供了灵活的控制能力,允许开发者针对文档中的每个节单独设置编号格式、重新开始规则以及显示位置,以满足不同排版规范的需求。
function App() {
const setFootnoteFormat = async () => {
// 获取 Spire.Doc WASM 模块
const docModule = window.wasmModule?.spiredoc;
// 检查模块是否就绪
if (!docModule) {
alert('Spire.Doc is not ready yet');
return;
}
const inputFileName = 'Footnote.docx';
await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}/data/`);
// 加载文档
const doc = new docModule.Document();
doc.LoadFromFile(inputFileName);
// 获取第一个节
let sec = doc.Sections.get_Item(0);
// 设置脚注编号格式为大写字母
sec.FootnoteOptions.NumberFormat = docModule.FootnoteNumberFormat.UpperCaseLetter;
// 设置脚注重新开始规则为每页重新编号
sec.FootnoteOptions.RestartRule = docModule.FootnoteRestartRule.RestartPage;
// 设置脚注位置为节的末尾
sec.FootnoteOptions.Position = docModule.FootnotePosition.PrintAsEndOfSection;
// 定义输出文件名
const outputFileName = "SetPositionAndNumberFormat.docx";
// 保存文档
doc.SaveToFile({ fileName: outputFileName, fileFormat: docModule.FileFormat.Docx2013 });
// 释放资源
doc.Dispose();
// 从 VFS 读取生成的文件,触发下载
const modifiedFileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
const blob = new Blob([modifiedFileArray], { 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>设置脚注格式。</h1>
<button onClick={setFootnoteFormat}>
Generate
</button>
</div>
);
}
export default App;
通过 FootnoteOptions 对象修改编号格式和位置后,文档中的脚注会按照指定的样式重新编排。例如,将编号格式设为 UpperCaseLetter(大写字母)并将位置设为 PrintAsEndOfSection(节末尾),适用于附录或分章节编写的文档,让脚注在每节结束时统一呈现。设置 RestartRule 为 RestartPage 则可以让每页的脚注编号从 A(或 1)重新开始,避免跨页后编号持续增长。这些配置按节独立生效,同一文档中不同节可以拥有不同的脚注规则,非常适合多章节、多作者协作的复杂文档场景。

移除脚注
当文档经过多轮审阅或内容更新后,某些脚注可能不再适用或需要删除。Spire.Doc for JavaScript 通过遍历节(Section)中所有段落(Paragraph)的子对象,使用 instanceof 判断每个子对象是否为 Footnote 类型,找到后调用 RemoveAt 方法将其从段落的子对象集合中移除。这种逐段遍历的方式可以精准定位文档中任意位置的脚注,而无需预先知道脚注的具体页码或索引号。
function App() {
const removeFootnote = async () => {
// 获取 Spire.Doc WASM 模块
const docModule = window.wasmModule?.spiredoc;
// 检查模块是否就绪
if (!docModule) {
alert('Spire.Doc is not ready yet');
return;
}
const inputFileName = 'Footnote.docx';
await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}/data/`);
// 加载文档
const doc = new docModule.Document();
doc.LoadFromFile(inputFileName);
// 获取第一个节
let section = doc.Sections.get_Item(0);
// 遍历节中所有段落,查找并移除脚注
for (let p = 0; p < section.Paragraphs.Count; p++) {
let para = section.Paragraphs.get_Item(p);
let index = -1;
// 检查段落中的每个子对象是否为脚注
for (let i = 0, cnt = para.ChildObjects.Count; i < cnt; i++) {
let pBase = para.ChildObjects.get_Item(i);
if (pBase instanceof docModule.Footnote) {
index = i;
break;
}
}
// 如果找到脚注,则将其从段落中移除
if (index > -1) {
para.ChildObjects.RemoveAt(index);
}
}
// 定义输出文件名
const outputFileName = "RemoveFootnote.docx";
// 保存文档
doc.SaveToFile({ fileName: outputFileName, fileFormat: docModule.FileFormat.Docx2013 });
// 释放资源
doc.Dispose();
// 从 VFS 读取生成的文件,触发下载
const modifiedFileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
const blob = new Blob([modifiedFileArray], { 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>移除脚注。</h1>
<button onClick={removeFootnote}>
Generate
</button>
</div>
);
}
export default App;
移除脚注后,文档正文中原本显示上标标记的位置不再保留任何痕迹,页面底部的注释正文也一并清除,正文内容本身不会受到影响。

常见问题
插入的脚注未显示在预期位置
原因:脚注追加到段落后,未通过 Insert 方法将其插入到正确的子对象顺序中,导致脚注标记出现在段落末尾而非目标文本之后。
解决:通过 ChildObjects.IndexOf 获取目标文本的索引位置,再使用 Insert 方法将脚注插入到该位置之后:
let index = paragraph.ChildObjects.IndexOf(textRange);
paragraph.ChildObjects.Insert(index + 1, footnote);
脚注编号格式修改后未生效
原因:脚注编号格式设置在了错误的节上,或文档包含多个节但只修改了第一个节的设置。
解决:确认目标脚注所在的节,并为每个包含脚注的节分别设置编号格式:
for (let i = 0; i < document.Sections.Count; i++) {
let sec = document.Sections.get_Item(i);
sec.FootnoteOptions.NumberFormat = docModule.FootnoteNumberFormat.UpperCaseLetter;
}
获取免费许可证
如果您希望删除结果文档中的评估消息,或者摆脱功能限制,请该Email地址已收到反垃圾邮件插件保护。要显示它您需要在浏览器中启用JavaScript。获取有效期 30 天的临时许可证。







