在 Excel 文档处理场景中,工作表的增删改是最基础也最常用的操作之一。无论是基于模板快速生成新的数据表,还是清理冗余内容、调整文档结构,都离不开对工作表的灵活管理。本文介绍一种在 React 应用中实现 Excel 工作表添加、删除和移动的方案,基于 WebAssembly 技术在浏览器端直接完成这些操作,无需依赖后端服务。
环境准备
该方案通过一个独立的 JavaScript Excel 处理库实现,无需安装 Microsoft Office,适合部署在浏览器端环境。首先在 React 项目中安装依赖:
bash
npm i spire.xls
安装完成后,将 Spire.Xls.Base.js 和 Spire.Xls.Base.wasm 文件放置到项目的 public 目录下。在 React 组件中通过动态加载的方式初始化 WebAssembly 模块即可使用其 API。
添加工作表
在工作簿中添加新的工作表是日常开发中的高频需求------例如基于月度报表模板快速创建下个月的报表副本时,需要新增一张空白工作表来存放新数据。
该库提供了 Worksheets.Add() 方法,可以在工作簿的末尾追加一张新的工作表并为其命名。添加后,可以像操作普通工作表一样向单元格写入数据,最后保存工作簿。
jsx
const startProcessing = async () => {
// 获取 Spire.XLS WASM 模块
const xlsModule = window.wasmModule?.spirexls;
if (!xlsModule) {
alert('模块未就绪');
return;
}
// 将字体和 Excel 文件载入 VFS
await window.spire.FetchFileToVFS('simsun.ttc', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
const inputFileName = 'AddWorksheet.xlsx';
await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}/data/`);
// 创建工作簿实例并加载文件
const workbook = new xlsModule.Workbook();
workbook.LoadFromFile({ fileName: inputFileName });
// 添加新的工作表并命名为 "新增表"
const sheet = workbook.Worksheets.Add("新增表");
sheet.Range.get("C5").Text = "这是一张新增的工作表。";
// 自适应列宽
sheet.AllocatedRange.AutoFitColumns();
// 保存工作簿
const outputFileName = "AddWorksheet_output.xlsx";
workbook.SaveToFile({ fileName: outputFileName });
// 释放资源
workbook.Dispose();
// 从 VFS 读取输出文件,封装为 Blob 并触发下载
const modifiedFileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
const blob = new Blob([modifiedFileArray], { 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);
};
当使用 Add 方法时,新工作表默认被添加在所有已有工作表之后。如果需要在指定位置插入工作表,可以结合 Insert 相关方法实现。
删除工作表
当工作簿中包含无用或已过期的工作表时,可以通过删除操作保持文档的整洁。该库提供了两种删除方式:按工作表名称删除和按索引位置删除。
按名称删除的方式更直观,适合在明确知道要删除哪个工作表时使用:
jsx
const startProcessing = async () => {
const xlsModule = window.wasmModule?.spirexls;
if (!xlsModule) {
alert('模块未就绪');
return;
}
await window.spire.FetchFileToVFS('simsun.ttc', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
const inputFileName = 'RemoveWorksheet.xlsx';
await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}/data/`);
const workbook = new xlsModule.Workbook();
workbook.LoadFromFile({ fileName: inputFileName });
// 按工作表名称删除指定的工作表
const sheet = workbook.Worksheets.get("Sheet2");
workbook.Worksheets.Remove(sheet);
// 通过索引删除(注释部分)
// workbook.Worksheets.RemoveAt(1);
const outputFileName = "RemoveWorksheet_output.xlsx";
workbook.SaveToFile({ fileName: outputFileName });
workbook.Dispose();
const modifiedFileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
const blob = new Blob([modifiedFileArray], { 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);
};
需要注意的是,按名称删除时,指定的名称必须与工作簿中的实际名称完全匹配(区分大小写)。如果名称不匹配,操作将无法定位到目标工作表。删除前可以先遍历确认工作表的名称:
js
for (let i = 0; i < workbook.Worksheets.Count; i++) {
console.log(workbook.Worksheets.get(i).Name);
}
移动与重排序工作表
调整工作表的顺序是文档组织中的常见需求------例如将摘要表移到最前面,或将相关的工作表归拢到一起。该库通过 MoveWorksheet 方法实现这一功能,将指定工作表移动到目标索引位置。
jsx
const startProcessing = async () => {
const xlsModule = window.wasmModule?.spirexls;
if (!xlsModule) {
alert('模块未就绪');
return;
}
await window.spire.FetchFileToVFS('simsun.ttc', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
const inputFileName = 'Sample.xlsx';
await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}/data/`);
const workbook = new xlsModule.Workbook();
workbook.LoadFromFile({ fileName: inputFileName });
// 获取第一个工作表并将其移动到索引 1
const sheet = workbook.Worksheets.get(0);
sheet.MoveWorksheet(1);
const outputFileName = "MoveWorksheet_output.xlsx";
workbook.SaveToFile({ fileName: outputFileName });
workbook.Dispose();
const modifiedFileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
const blob = new Blob([modifiedFileArray], { 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);
};
目标索引从 0 开始计数,MoveWorksheet(0) 表示移动到最前面,MoveWorksheet(workbook.Worksheets.Count - 1) 表示移动到最后。移动后,原有工作表的位置会自动调整。
关于虚拟文件系统
上述操作中的输入文件和输出文件都通过虚拟文件系统(VFS)进行管理。FetchFileToVFS() 方法将字体文件和 Excel 文件加载到 WebAssembly 的内存文件系统中;SaveToFile() 生成的输出文件也存储在这个内存系统中,需要从中读取数据并转换为 Blob 对象才能触发浏览器下载。
每个 Workbook 实例在操作完成后,建议调用 Dispose() 方法释放内存资源,避免浏览器内存占用过高。
小结
通过基于 WebAssembly 的 Excel 处理方案,可以在 React 应用中完全在浏览器端完成工作表的添加、删除和移动操作,无需后端服务支持。这些基础操作足以覆盖大部分 Excel 文档管理的需求,开发者可以根据实际业务场景对示例代码进行适配和扩展。