化学式里的原子个数、数学公式中的指数、单位符号上的平方与立方、离子式末尾的电荷——这些字符在排版上都要比正文小一号、位置也要上下偏移,读起来才符合习惯。把它们与普通文字排成同样大小,读者只能靠上下文去猜。Excel 的富文本允许同一个单元格里的不同字符带上各自的格式,上标与下标是其中使用最频繁的两种。Spire.XLS for JavaScript 基于 WebAssembly 在浏览器端直接完成这些操作,通过虚拟文件系统(VFS)管理输入输出文件,无需后端服务支持。
本文介绍两个核心功能点:
有关安装和项目配置,请参考 React 项目中集成 Spire.XLS for JavaScript。以下示例默认已安装 Spire.XLS 并完成 WebAssembly 模块初始化。
设置下标
上标与下标的设置方式与普通字体属性不同:它并非给整个单元格套用一种样式,而是用 RichText.SetFont 为单元格文字中的某一段单独指定字体。因此需要三步配合——先写入一段富文本,再准备一份带下标效果的字体,最后把这份字体套用到指定的字符区间上。具体操作步骤如下:
- 将字体载入 VFS。
- 新建工作簿,取得第一个工作表。
- 写入示例项名称,用
RichText.Text写入化学式文本。 - 用
workbook.CreateFont()创建字体对象,把IsSubscript设为true。 - 用
RichText.SetFont(startIndex, endIndex, font)把该字体应用到化学式中的数字上,保存工作簿。
以下为完整的代码示例,演示如何在 React 中设置单元格文字的下标:
function App() {
const setSubscript = async () => {
// 获取 Spire.XLS WASM 模块
const xlsModule = window.wasmModule?.spirexls;
// 检查模块是否就绪
if (!xlsModule) {
alert('Spire.Xls is not ready yet');
return;
}
// 将字体载入 VFS
await window.spire.FetchFileToVFS('simsun.ttc', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
// 新建工作簿,取第一个工作表
const workbook = new xlsModule.Workbook();
const sheet = workbook.Worksheets.get(0);
// 写入表头与示例项名称
sheet.Range.get("A1").Text = "示例项目";
sheet.Range.get("B1").Text = "显示效果";
sheet.Range.get("A2").Text = "水的化学式";
sheet.Range.get("A3").Text = "硫酸的化学式";
// 写入化学式文本
const waterRange = sheet.Range.get("B2");
waterRange.RichText.Text = "H2O";
const acidRange = sheet.Range.get("B3");
acidRange.RichText.Text = "H2SO4";
// 新建字体,将 IsSubscript 设为 true
const font = workbook.CreateFont();
font.IsSubscript = true;
// 只把下标字体应用到化学式中的数字上,索引从 0 开始,区间首尾都包含
waterRange.RichText.SetFont(1, 1, font);
acidRange.RichText.SetFont(1, 1, font);
acidRange.RichText.SetFont(4, 4, font);
// 加宽 A、B 两列,让富文本完整显示
sheet.Range.get("A1:A3").ColumnWidth = 18;
sheet.Range.get("B1:B3").ColumnWidth = 18;
// 保存工作簿
const outputFileName = "SetSubscript.xlsx";
workbook.SaveToFile({ fileName: outputFileName });
// 释放 workbook 对象以释放资源
workbook.Dispose();
// 从 VFS 读取结果文件,触发下载
const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
const blob = new Blob([fileArray], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
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={setSubscript}>Start</button>
</div>
);
}
export default App;
运行后,设置下标的效果:

设置上标
上标的用法与下标完全对称,区别只在于把字体偏移的方向反过来——下标向下压,上标向上抬。上标常用于幂次与指数:勾股定理中的二次方、面积单位 cm2 的平方、体积单位 m3 的立方,都应当写成上标形式。一次 RichText.SetFont 调用只作用于一段连续区间,像 a2 + b2 = c2 这样有三处需要抬高的文本,就要调用三次。具体操作步骤如下:
- 将字体载入 VFS。
- 新建工作簿,取得第一个工作表。
- 写入示例项名称,用
RichText.Text写入待设置的文本。 - 用
workbook.CreateFont()创建字体对象,把IsSuperscript设为true。 - 用
RichText.SetFont(startIndex, endIndex, font)把该字体应用到需要抬高的字符上,保存工作簿。
以下为完整的代码示例,演示如何在 React 中设置单元格文字的上标:
function App() {
const setSuperscript = async () => {
// 获取 Spire.XLS WASM 模块
const xlsModule = window.wasmModule?.spirexls;
// 检查模块是否就绪
if (!xlsModule) {
alert('Spire.Xls is not ready yet');
return;
}
// 将字体载入 VFS
await window.spire.FetchFileToVFS('simsun.ttc', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
// 新建工作簿,取第一个工作表
const workbook = new xlsModule.Workbook();
const sheet = workbook.Worksheets.get(0);
// 写入表头与示例项名称
sheet.Range.get("A1").Text = "示例项目";
sheet.Range.get("B1").Text = "显示效果";
sheet.Range.get("A2").Text = "勾股定理";
sheet.Range.get("A3").Text = "面积单位";
sheet.Range.get("A4").Text = "体积单位";
// 写入待设置的文本
const theoremRange = sheet.Range.get("B2");
theoremRange.RichText.Text = "a2 + b2 = c2";
const areaRange = sheet.Range.get("B3");
areaRange.RichText.Text = "cm2";
const volumeRange = sheet.Range.get("B4");
volumeRange.RichText.Text = "m3";
// 新建字体,将 IsSuperscript 设为 true
const font = workbook.CreateFont();
font.IsSuperscript = true;
// 只把上标字体应用到需要抬高的字符上
theoremRange.RichText.SetFont(1, 1, font);
theoremRange.RichText.SetFont(6, 6, font);
theoremRange.RichText.SetFont(11, 11, font);
areaRange.RichText.SetFont(2, 2, font);
volumeRange.RichText.SetFont(1, 1, font);
// 加宽 A、B 两列,让富文本完整显示
sheet.Range.get("A1:A4").ColumnWidth = 18;
sheet.Range.get("B1:B4").ColumnWidth = 18;
// 保存工作簿
const outputFileName = "SetSuperscript.xlsx";
workbook.SaveToFile({ fileName: outputFileName });
// 释放 workbook 对象以释放资源
workbook.Dispose();
// 从 VFS 读取结果文件,触发下载
const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
const blob = new Blob([fileArray], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
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={setSuperscript}>Start</button>
</div>
);
}
export default App;
运行后,设置上标的效果:

常见问题
已经设好的上标或下标怎么去掉?
原因:上标与下标是字符上的格式。在同一个区间再次调用 SetFont 时,新字体的属性会覆盖原来的,所以换一份不带上下标的字体重新设置一次,原来的效果就会被去掉。
解决:新建一份字体,把 IsSubscript 或 IsSuperscript 设为 false,在原来的区间上再调用一次 SetFont:
// 用一份普通字体覆盖原来的下标设置
const normal = workbook.CreateFont();
normal.IsSubscript = false;
range.RichText.SetFont(1, 1, normal);
读回文件时,怎么判断某个字符是不是上标?
原因:上下标只是字符上的格式,不算单元格的文字内容。Range.Text、Range.Value 与 RichText.Text 读到的都只有纯文本,看不出哪些字符带上下标。
解决:按字符的位置读取它的字体,再看字体上的上下标属性。位置与 SetFont 一样从 0 开始计数:
// 读取索引 1 处字符的字体,H2O 中即中间的 2
const font = range.RichText.GetFont(1);
console.log(font.IsSubscript); // true
console.log(font.IsSuperscript); // false
获取免费许可证
如果您希望删除结果文档中的评估消息,或者摆脱功能限制,请该Email地址已收到反垃圾邮件插件保护。要显示它您需要在浏览器中启用JavaScript。获取有效期 30 天的临时许可证。







