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 文档管理的需求,开发者可以根据实际业务场景对示例代码进行适配和扩展。

相关推荐
avi911111 小时前
[AI教做人]AI平台做2项目;一个3D模型展示,另一个框架多人
javascript·人工智能·ai·3d模型·3d引擎·顶点和法线
kyriewen11 小时前
我用Claude Code两天干完了团队两周的排期——周报发出去那一刻我就后悔了
前端·javascript·ai编程
用户9385156350712 小时前
手写一个 LLM Harness 框架:用工程化手段把大模型幻觉踩在脚下
javascript·人工智能·后端
油丶酸萝卜别吃13 小时前
jquery-ajax.js 说明文档
前端·javascript·jquery
windliang13 小时前
Claude Code 源码分析(九):子 Agent 如何分叉、继续与回到父会话
前端·javascript·面试
柒和远方13 小时前
V063: TS 面试必考:interface 与 type 的四大差异,与 LLM Harness 的自动化择优
前端·javascript
半个落月13 小时前
React useRef 详解:DOM 引用、持久化值与 Worker 实例
前端·react.js
汉堡大王952714 小时前
Vue 3 + TS + Element Plus 实战:如何从零搭建企业级违章记录管理 SaaS 前端
前端·javascript·vue.js
海天鹰14 小时前
屏幕颜色检测
javascript·html5
用户79172867619715 小时前
opencode-plugin-peers完全指南:OpenCode如何实现 Claude Code式跨会话消息
javascript