在整理销售记录、统计报表等数据时,把一段普通数据区域转换成 Excel 的表格(Table / ListObject),可以让数据拥有独立的标题行、自动筛选下拉按钮、条纹外观和"汇总行"等能力,后续查阅和统计都更方便。而创建之后,还可以随时通过内置样式或各类显示选项来调整表格的外观。Spire.XLS for JavaScript 基于 WebAssembly 在浏览器端直接完成这些操作,通过虚拟文件系统(VFS)管理输入输出文件,无需后端服务支持。
Spire.XLS for JavaScript 通过工作表对象的 ListObjects 集合来管理表格:调用 ListObjects.Create() 可以把指定单元格区域转换为表格;转换得到的 IListObject 对象支持设置内置样式(BuiltInTableStyle)、显示汇总行(DisplayTotalRow)、为汇总行各列设置计算方式(Columns[].TotalsCalculation)以及开启行条纹/列条纹(ShowTableStyleRowStripes / ShowTableStyleColumnStripes)等。
本文介绍两个核心功能点:
有关安装和项目配置,请参考 React 项目中集成 Spire.XLS for JavaScript。以下示例默认已安装 Spire.XLS 并完成 WebAssembly 模块初始化。
在 Excel 中创建表格(Table)
将数据区域转换为表格,是快速获得"自带筛选按钮 + 条纹外观"结构化区域的方式。本例先在工作表中写入一份销售明细(产品、区域、月份、数量、销售额),再通过 ListObjects.Create() 方法把 A1:E13 区域转换为名为 "Table1" 的表格,最后应用内置浅色样式 TableStyleLight9。具体操作步骤如下:
- 创建一个
Workbook对象并获取第一个工作表。 - 将表头和示例数据写入单元格。
- 调用
Worksheet.ListObjects.Create()方法,把包含表头的数据区域转换为表格。 - 通过
IListObject.BuiltInTableStyle属性为表格应用内置样式。 - 通过
Workbook.SaveToFile()方法保存工作簿。
下面是一个完整的代码示例,展示了在 React 中为工作表创建 Excel 表格:
function App() {
const createTable = 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').Value = '产品';
sheet.Range.get('B1').Value = '区域';
sheet.Range.get('C1').Value = '月份';
sheet.Range.get('D1').Value = '数量';
sheet.Range.get('E1').Value = '销售额';
// 写入示例数据
sheet.Range.get('A2').Value = '笔记本电脑';
sheet.Range.get('B2').Value = '华北';
sheet.Range.get('C2').Value = '一月';
sheet.Range.get('D2').NumberValue = 120;
sheet.Range.get('E2').NumberValue = 239760;
sheet.Range.get('A3').Value = '显示器';
sheet.Range.get('B3').Value = '华东';
sheet.Range.get('C3').Value = '一月';
sheet.Range.get('D3').NumberValue = 80;
sheet.Range.get('E3').NumberValue = 103920;
sheet.Range.get('A4').Value = '键盘';
sheet.Range.get('B4').Value = '华南';
sheet.Range.get('C4').Value = '一月';
sheet.Range.get('D4').NumberValue = 200;
sheet.Range.get('E4').NumberValue = 59800;
sheet.Range.get('A5').Value = '笔记本电脑';
sheet.Range.get('B5').Value = '华东';
sheet.Range.get('C5').Value = '二月';
sheet.Range.get('D5').NumberValue = 150;
sheet.Range.get('E5').NumberValue = 299700;
sheet.Range.get('A6').Value = '鼠标';
sheet.Range.get('B6').Value = '华北';
sheet.Range.get('C6').Value = '二月';
sheet.Range.get('D6').NumberValue = 300;
sheet.Range.get('E6').NumberValue = 26700;
sheet.Range.get('A7').Value = '打印机';
sheet.Range.get('B7').Value = '华南';
sheet.Range.get('C7').Value = '二月';
sheet.Range.get('D7').NumberValue = 60;
sheet.Range.get('E7').NumberValue = 65940;
sheet.Range.get('A8').Value = '显示器';
sheet.Range.get('B8').Value = '西部';
sheet.Range.get('C8').Value = '二月';
sheet.Range.get('D8').NumberValue = 90;
sheet.Range.get('E8').NumberValue = 116910;
sheet.Range.get('A9').Value = '键盘';
sheet.Range.get('B9').Value = '华北';
sheet.Range.get('C9').Value = '三月';
sheet.Range.get('D9').NumberValue = 180;
sheet.Range.get('E9').NumberValue = 53820;
sheet.Range.get('A10').Value = '路由器';
sheet.Range.get('B10').Value = '华东';
sheet.Range.get('C10').Value = '三月';
sheet.Range.get('D10').NumberValue = 70;
sheet.Range.get('E10').NumberValue = 27930;
sheet.Range.get('A11').Value = '笔记本电脑';
sheet.Range.get('B11').Value = '西部';
sheet.Range.get('C11').Value = '三月';
sheet.Range.get('D11').NumberValue = 140;
sheet.Range.get('E11').NumberValue = 279860;
sheet.Range.get('A12').Value = '打印机';
sheet.Range.get('B12').Value = '华北';
sheet.Range.get('C12').Value = '四月';
sheet.Range.get('D12').NumberValue = 110;
sheet.Range.get('E12').NumberValue = 120890;
sheet.Range.get('A13').Value = '鼠标';
sheet.Range.get('B13').Value = '华南';
sheet.Range.get('C13').Value = '四月';
sheet.Range.get('D13').NumberValue = 260;
sheet.Range.get('E13').NumberValue = 23140;
// 将 A1:E13 数据区域转换为 Excel 表格(ListObject)
const table = sheet.ListObjects.Create('Table1', sheet.Range.get({ row: 1, column: 1, lastRow: 13, lastColumn: 5 }));
// 应用内置浅色表格样式
table.BuiltInTableStyle = xlsModule.TableBuiltInStyles.TableStyleLight9;
// 自动调整列宽,使内容完整显示
sheet.AllocatedRange.AutoFitColumns();
// 保存文档
const outputFileName = 'CreateTable.xlsx';
workbook.SaveToFile({ fileName: outputFileName, version: xlsModule.ExcelVersion.Version2010 });
// 释放资源
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>Create Table</h1>
<button onClick={createTable}>Start</button>
</div>
);
}
export default App;
创建表格效果:

设置表格样式、汇总行与条纹
创建好的表格可以随时重新设置外观:例如将浅色样式换成内置的 Medium 深色样式,在表格底部显示汇总行并让"数量""销售额"两列自动求和,同时开启行条纹与列条纹让数据更易阅读。具体操作步骤如下:
- 创建一个
Workbook对象,并通过Workbook.LoadFromFile()方法加载已含表格的工作簿。 - 通过
Workbook.Worksheets.get()方法获取该工作表,再通过ListObjects.get()获取表格对象。 - 通过
BuiltInTableStyle属性重新指定内置样式。 - 将
DisplayTotalRow设为true显示汇总行,并用Columns[].TotalsRowLabel、Columns[].TotalsCalculation设置汇总行的标签与求和方式。 - 通过
ShowTableStyleRowStripes、ShowTableStyleColumnStripes开启行条纹与列条纹。 - 通过
Workbook.SaveToFile()方法保存工作簿。
下面是一个完整的代码示例,展示了在 React 中加载已创建的表格并重新设置样式与汇总行:
function App() {
const formatTable = 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/`);
// 加载上一节生成的、已包含表格的 Excel 文件
const inputFileName = 'CreateTable.xlsx';
await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}data/`);
// 创建 Workbook 对象并加载该工作簿
const workbook = new xlsModule.Workbook();
workbook.LoadFromFile({ fileName: inputFileName });
// 获取第一个工作表及其中的表格
const sheet = workbook.Worksheets.get(0);
const table = sheet.ListObjects.get(0);
// 重新应用内置 Medium 表格样式
table.BuiltInTableStyle = xlsModule.TableBuiltInStyles.TableStyleMedium9;
// 显示汇总行
table.DisplayTotalRow = true;
// 在汇总行的首列输入"合计"标签
table.Columns.get(0).TotalsRowLabel = '合计';
// 对文本列不计算,对"数量""销售额"两列自动求和
table.Columns.get(1).TotalsCalculation = xlsModule.ExcelTotalsCalculation.None;
table.Columns.get(2).TotalsCalculation = xlsModule.ExcelTotalsCalculation.None;
table.Columns.get(3).TotalsCalculation = xlsModule.ExcelTotalsCalculation.Sum;
table.Columns.get(4).TotalsCalculation = xlsModule.ExcelTotalsCalculation.Sum;
// 显示行条纹与列条纹
table.ShowTableStyleRowStripes = true;
table.ShowTableStyleColumnStripes = true;
// 自动调整列宽,使内容完整显示
sheet.AllocatedRange.AutoFitColumns();
// 保存文档
const outputFileName = 'FormatTable_out.xlsx';
workbook.SaveToFile({ fileName: outputFileName, version: xlsModule.ExcelVersion.Version2010 });
// 释放资源
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>Format Table</h1>
<button onClick={formatTable}>Start</button>
</div>
);
}
export default App;
设置表格样式效果:

常见问题
如何更换表格的内置样式?有哪些样式可选?
原因:创建表格后未重新指定 BuiltInTableStyle,或对属性赋值时使用了错误的枚举类型。
解决:通过 IListObject.BuiltInTableStyle 属性重新赋值即可,取值来自 TableBuiltInStyles 枚举,它提供了浅色(TableStyleLight1 ~ TableStyleLight21)、中等(TableStyleMedium1 ~ TableStyleMedium28)和深色(TableStyleDark1 ~ TableStyleDark11)多套内置样式。例如本示例先应用 TableStyleLight9,之后切换为 TableStyleMedium9。
如何给表格命名或修改名称?多个表格同名会怎样?
原因:ListObjects.Create() 的第一个参数就是表格名称,例如 Create("Table1", ...);在同一工作表中,表格名称不能重复,否则再次创建同名表格时会报错。
解决:创建时传入唯一的名称(如 "SalesTable1")。若需要修改已有表格的名称,可直接设置其 DisplayName 属性,例如 table.DisplayName = "SalesTable2025";。
获取免费许可证
如果您希望删除结果文档中的评估消息,或者摆脱功能限制,请该Email地址已收到反垃圾邮件插件保护。要显示它您需要在浏览器中启用JavaScript。获取有效期 30 天的临时许可证。







