React 项目中灵活管理 Excel 工作表:增删与移动

在 Excel 文档处理场景中,工作表的增删改是最基础也最常用的操作之一。无论是基于模板快速生成新的数据表,还是清理冗余内容、调整文档结构,都离不开对工作表的灵活管理。本文介绍一种在 React 应用中实现 Excel 工作表添加、删除和移动的方案,基于 WebAssembly 技术在浏览器端直接完成这些操作,无需依赖后端服务。

环境准备

该方案通过一个独立的 JavaScript Excel 处理库实现,无需安装 Microsoft Office,适合部署在浏览器端环境。首先在 React 项目中安装依赖:

bash 复制代码
npm i spire.xls

安装完成后,将 Spire.Xls.Base.jsSpire.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 文档管理的需求,开发者可以根据实际业务场景对示例代码进行适配和扩展。

相关推荐
weedsfly1 小时前
从类继承到自定义 Hook:模板方法模式的前端演进
前端·javascript·面试
bonechips1 小时前
React + WebGPU(二):合成事件与进度条组件封装
前端·react.js
我是大卫1 小时前
【图】React源码解析-从底层数据结构、渲染调度到闭包原理深挖useRef的核心机制
前端·react.js·源码
何时梦醒1 小时前
# ⚛️ React 19 + TypeScript 深度学习笔记 —— 从组件化思维到 WebGPU 端侧 AI 落地(续)
人工智能·react.js
光影少年1 小时前
RN导航与路由
前端·react native·react.js
smallcelebration1 小时前
139 @vueuse/core依赖介绍使用
前端·javascript·vue.js
蒜苔肉丝1 小时前
Vue3 动态表单:模块复用 + 动态增删行 + 数据回显
前端·javascript·vue.js
Cxiaomu2 小时前
从 TRTC Demo 到独立音视频服务:React + TRTC Web SDK 服务化实践
前端·react.js·音视频
索西引擎2 小时前
【React】Redux 中间件机制:副作用处理与数据流增强的形式化分析
前端·react.js·中间件