一份做好的报表常常要复用到不同品牌、不同部门的场合,颜色得跟着换。麻烦的地方在于,工作簿里的颜色分两种:一种是写死的 RGB 值,只认自己那一处;另一种指向主题里的槽位,标题栏、表头、隔行底色和边框虽然看上去各不相同,其实都从同一组槽位取值。前一种只能逐个单元格去改,改漏一处就露出旧配色;后一种改一个槽位,整张表一起重绘。Spire.XLS for JavaScript 基于 WebAssembly 在浏览器端直接完成此操作,通过虚拟文件系统(VFS)管理输入输出文件,无需后端服务支持。
本文介绍三个核心功能点:
有关安装和项目配置,请参考 React 项目中集成 Spire.XLS for JavaScript。以下示例默认已安装 Spire.XLS 并完成 WebAssembly 模块初始化。
替换主题中的强调色
报表里用得最多的那个颜色通常只有一个:表头铺它、标题栏用它的深色、隔行底纹用它的浅色、边框再用一档更淡的。这些深浅不同的色阶不是各调一次调出来的,而是同一个槽位按不同明暗系数算出来的。因此换肤时不必逐格挑颜色,只把那个槽位换成新的品牌色,深浅各档会自己重算,整张表连同图表一起落到新的色系上。具体操作步骤如下:
- 将字体与测试数据文件载入 VFS。
- 用
workbook.LoadFromFile加载工作簿。 - 用
workbook.SetThemeColor替换xlsModule.ThemeColorType.Accent1槽位,新颜色用xlsModule.Color.FromArgb给出。 - 用
workbook.SaveToFile保存工作簿,标题栏、表头、隔行底色与边框随之换色。
以下为完整的代码示例,演示如何在 React 中替换主题的强调色:
function App() {
const setThemeColor = 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 inputFileName = 'ThemeSource.xlsx';
await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}data/`);
// 加载工作簿
const workbook = new xlsModule.Workbook();
workbook.LoadFromFile({ fileName: inputFileName });
// 替换主题中的强调色 1:标题栏、表头、隔行底色和边框会一并换色
workbook.SetThemeColor(
xlsModule.ThemeColorType.Accent1,
xlsModule.Color.FromArgb(255, 46, 125, 91),
);
// 保存工作簿
const outputFileName = "SetThemeColor.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 id="set-theme-color" onClick={setThemeColor}>替换主题中的强调色</button>
</div>
);
}
export default App;
运行后,替换主题中的强调色的效果:

定制整套主题配色
只换一个强调色,表格主体是统一了,可图表里的其他系列、合计行、警示色仍停在旧配色上——它们取的是主题里的其他槽位。要让整份文档彻底换一套色系,就得把六个强调色槽位一起改掉,让所有引用主题的图形元素同时落到新方案上,而不是改一个、留一串。改动前先把当前值读出来留个底,换完之后也能对照确认。具体操作步骤如下:
- 将字体与测试数据文件载入 VFS。
- 用
workbook.LoadFromFile加载工作簿,再用workbook.GetThemeColor读一眼当前强调色 1 的R、G、B分量,作为对照基线。 - 把六组「槽位 + 颜色」写进一个数组,颜色仍由
xlsModule.Color.FromArgb生成。 - 遍历数组,对每一项调用
workbook.SetThemeColor,六个强调色一次换完。 - 用
workbook.SaveToFile保存工作簿。
以下为完整的代码示例,演示如何在 React 中定制整套主题配色:
function App() {
const applyThemeScheme = 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 inputFileName = 'ThemeSource.xlsx';
await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}data/`);
// 加载工作簿
const workbook = new xlsModule.Workbook();
workbook.LoadFromFile({ fileName: inputFileName });
// 换色前先读一眼当前的强调色,便于和换色后的结果对照
const before = workbook.GetThemeColor(xlsModule.ThemeColorType.Accent1);
console.log(`换色前的强调色 1:R=${before.R} G=${before.G} B=${before.B}`);
// 六种强调色一次换完,整套配色随之改变
const scheme = [
[xlsModule.ThemeColorType.Accent1, xlsModule.Color.FromArgb(255, 109, 46, 95)],
[xlsModule.ThemeColorType.Accent2, xlsModule.Color.FromArgb(255, 18, 89, 94)],
[xlsModule.ThemeColorType.Accent3, xlsModule.Color.FromArgb(255, 138, 106, 22)],
[xlsModule.ThemeColorType.Accent4, xlsModule.Color.FromArgb(255, 47, 93, 58)],
[xlsModule.ThemeColorType.Accent5, xlsModule.Color.FromArgb(255, 67, 48, 122)],
[xlsModule.ThemeColorType.Accent6, xlsModule.Color.FromArgb(255, 138, 59, 46)],
];
for (const [themeColorType, color] of scheme) {
workbook.SetThemeColor(themeColorType, color);
}
// 保存工作簿
const outputFileName = "ApplyThemeScheme.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 id="apply-theme-scheme" onClick={applyThemeScheme}>定制整套主题配色</button>
</div>
);
}
export default App;
运行后,定制整套主题配色的效果:

沿用其他工作簿的主题
配色方案定稿之后,往往已经躺在一份现成的工作簿里——设计给的样板、上一季度的报表、或者公司统一的模板。这时候再照着色号一个槽位一个槽位地抄,既费事又容易抄错一两位。既然主题本身就是工作簿里的一部分,可以直接把整份主题搬过来,连深浅两对底色和超链接颜色一并带走,目标工作簿里所有引用主题的颜色随之重绘。提供主题的工作簿不必与目标工作簿同形同构,行列多少、放的是哪套数据、画的是哪类图表都不碍事,搬过来的只是主题本身,目标工作簿原有的数据与图表不会被牵动。具体操作步骤如下:
- 将字体与两个工作簿文件载入 VFS。
- 用
workbook.LoadFromFile加载待换肤的目标工作簿,再用themeWorkbook.LoadFromFile加载提供主题的源工作簿。 - 用
workbook.CopyTheme(themeWorkbook)把源工作簿的主题整套搬到目标工作簿。 - 用
workbook.SaveToFile保存目标工作簿,最后分别对两个workbook对象调用Dispose。
以下为完整的代码示例,演示如何在 React 中沿用其他工作簿的主题:
function App() {
const copyWorkbookTheme = 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 inputFileName = 'ThemeSource.xlsx';
const themeFileName = 'ThemeAlt.xlsx';
await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}data/`);
await window.spire.FetchFileToVFS(themeFileName, '', `${process.env.PUBLIC_URL}data/`);
// 加载待换肤的工作簿
const workbook = new xlsModule.Workbook();
workbook.LoadFromFile({ fileName: inputFileName });
// 加载提供主题的源工作簿
const themeWorkbook = new xlsModule.Workbook();
themeWorkbook.LoadFromFile({ fileName: themeFileName });
// 把源工作簿的主题整套搬到目标工作簿
workbook.CopyTheme(themeWorkbook);
// 保存工作簿
const outputFileName = "CopyWorkbookTheme.xlsx";
workbook.SaveToFile({ fileName: outputFileName });
// 释放两个 workbook 对象以释放资源
workbook.Dispose();
themeWorkbook.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 id="copy-workbook-theme" onClick={copyWorkbookTheme}>沿用其他工作簿的主题</button>
</div>
);
}
export default App;
运行后,沿用其他工作簿的主题的效果:

常见问题
哪些颜色会随主题变化,哪些不会
原因:颜色分为两类。在 Excel 中由「主题颜色」指定的颜色,会随主题一同变化;由「标准色」指定的颜色是固定值,主题变化时不会改变。
解决:若需颜色随主题变化,在 Excel 中选中单元格,从「主题颜色」中选择。代码中写入的颜色均为固定值,不随主题变化:
const cell = sheet.Range.get('A1');
// 固定色:不随主题变化
cell.Style.Interior.Color = xlsModule.Color.FromArgb(255, 192, 0, 0);
只改图表、不动表格可以吗
原因:主题属于整份工作簿,不区分表格与图表。修改主题时,所有取用主题颜色的对象会一同变化,表格与图表都在其中。图表的系列本身并不保存颜色,绘制时取自主题,因此主题一变,图表随之改变,无法只让其中一方变化。
解决:若只需调整图表,则不要修改主题,直接为系列单独设色。这样写入图表的是固定颜色,不随主题变化:
const chart = sheet.Charts.get(0);
const serie = chart.Series.get(0);
serie.Format.Fill.FillType = xlsModule.ShapeFillType.SolidColor;
serie.Format.Fill.ForeColor = xlsModule.Color.FromArgb(255, 46, 125, 91);
获取免费许可证
如果您希望删除结果文档中的评估消息,或者摆脱功能限制,请该Email地址已收到反垃圾邮件插件保护。要显示它您需要在浏览器中启用JavaScript。获取有效期 30 天的临时许可证。







