- 前端
- UI组件
【免费下载链接】ce
Jspreadsheet is a lightweight JavaScript data grid component for creating interactive data grids with advanced spreadsheet controls.
Jspreadsheet CE 是一款轻量级的 JavaScript 数据网格库,提供类 Excel 的电子表格交互能力,并可通过官方 React 封装无缝集成到 React 应用中。本文基于仓库内 React 集成文档,完整讲解从 npm 安装、样式引入、两种 React 集成写法(<Spreadsheet>封装组件与直接调用工厂函数),到如何通过事件系统与 React 状态同步的完整流程,并辅以 src 目录下源码级实现证据。读完本文,你将能够在自己已有的 React 项目中快速搭建带标签页、工具栏、多工作表等高级控件的数据网格,并让网格数据变更实时反馈到 React 组件与外部图表。
安装与前置准备
安装 React 封装包
Jspreadsheet CE 官方提供了 React 数据网格封装(wrapper),通过 NPM 即可安装:
npm install @jspreadsheet-ce/react@5.0.0-beta.3该封装包以@jspreadsheet-ce/react为包名,导出Spreadsheet与Worksheet两个 React 组件(对应仓库源码中的工作表构建逻辑,参见 factory.js)。如果你需要直接操作底层库,也可以同时安装核心包jspreadsheet-ce。
引入必要的样式
封装组件依赖两套样式:jSuites(基础 UI 控件,如工具栏、标签页)与 jspreadsheet(数据网格本体)。在项目入口或组件文件中引入:
import "jsuites/dist/jsuites.css"; import "jspreadsheet-ce/dist/jspreadsheet.css";这两行样式对应仓库根目录 jspreadsheet.css 与 jspreadsheet.themes.css 所定义的网格主题体系:前者负责网格布局、选区高亮、表头/行列操作等核心外观,后者提供多套配色主题。
引入 Material Icons 字体
工具栏与各类控件中的图标依赖 Material Icons 字体,需要在主 HTML 文件中加入:
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Material+Icons" />注意:该行是外部字体链接,属于原文档的标准配置步骤。若你的应用有离线或内网部署要求,可将 Material Icons 字体文件下载后自托管,并把上述
<link>替换为本地资源路径。
方式一:使用 React 封装组件(React Wrapper)
这是官方推荐的声明式写法:外层用<Spreadsheet>描述整个电子表格,内层用<Worksheet>描述具体工作表。
最小可用示例
import React, { useRef, useEffect } from "react"; import { Spreadsheet, Worksheet } from "@jspreadsheet-ce/react"; import "jspreadsheet-ce/dist/jspreadsheet.css"; import "jsuites/dist/jsuites.css"; export default function App() { // Spreadsheet array of worksheets const spreadsheet = useRef(); // Render component return ( <Spreadsheet ref={spreadsheet} tabs={true} toolbar={true}> <Worksheet minDimensions={[6, 6]} /> </Spreadsheet> ); }要点说明:
ref={spreadsheet}:通过 ref 拿到整个 Spreadsheet 实例,后续可在父组件中调用实例上的方法(如读取数据、插入行列、切换工作表等)。源码层面,每个 spreadsheet 实例由 factory.js 中的factory.spreadsheet(el, options, worksheets)创建,并挂载到libraryBase.jspreadsheet.spreadsheet数组中(见 index.js)。tabs={true}:开启工作表标签页,多个<Worksheet>会以 Sheet1、Sheet2……命名并可通过标签切换。从 factory.js 的实现看,tabs为true时允许动态创建新工作表(allowCreate = true),否则隐藏标签头。toolbar={true}:显示工具栏,提供撤销/重做、插入行列、合并单元格、排序等快捷操作;工具栏状态会随当前激活工作表联动(factory.js 中标签切换时调用updateToolbar)。<Worksheet minDimensions={[6, 6]} />:minDimensions以[列数, 行数]指定工作表的最小尺寸,网格将至少渲染 6 列 6 行;超出部分的数据区域仍可编辑扩展。
带数据的多工作表
<Worksheet>还支持data(二维数组)、columns(列配置,如{ type: "text", width: "200" })、mergedCells、freezeColumns等属性,可在一个<Spreadsheet>内声明多个工作表,实现类似 Excel 的多 Sheet 工作簿体验。
方式二:直接调用 jspreadsheet 工厂函数(React Component)
如果希望获得更底层的控制力,可以跳过封装组件,直接用 ref 指向一个普通<div>,再调用jspreadsheet()工厂函数完成初始化。这种方式与仓库内 getting-started.md 中描述的纯 JS 用法一致,只是把创建时机放进了 React 生命周期:
import React, { useRef, useEffect } from "react"; import jspreadsheet from "@jspreadsheet-ce/react"; import "jspreadsheet-ce/dist/jspreadsheet.css"; import "jsuites/dist/jsuites.css"; export default function App() { const jssRef = useRef(null); useEffect(() => { // Create the spreadsheet only once if (!jssRef.current.jspreadsheet) { jspreadsheet(jssRef.current, { worksheets: [{ minDimensions: [10, 10] }], }); } }, null); return (<div ref={jssRef} />); }关键点:
- 工厂函数签名是
jspreadsheet(element, options),第一个参数是 HTML 容器元素,第二个参数为配置对象;它返回工作表实例数组(见 index.js)。 if (!jssRef.current.jspreadsheet)守卫非常重要:Jspreadsheet 创建后会在容器元素上挂载spreadsheet引用,该判断确保只在组件首次挂载时创建一次,避免 React 严格模式或重复渲染导致重复初始化。worksheets数组中的每个元素对应一个工作表配置,minDimensions: [10, 10]等价于封装写法中的<Worksheet minDimensions={[10, 10]} />。- 销毁时调用
jspreadsheet.destroy(element)(实现见 index.js),它会把容器内容清空、从全局实例数组中移除;也可用destroyAll()一次性销毁当前命名空间下所有实例。
与 React 状态(State)的同步机制
为什么不能直接绑定 React State
由于 Jspreadsheet 的架构设计,它并不直接与 React State 协同工作。官方文档明确说明:Jspreadsheet 内部以普通对象(包括大数据集)运行,为了优化性能、降低开销并维持高效的数据处理,它在内部维护对象引用,并提供专有的方法与事件来与内部状态交互。
从源码可以印证这一点:工作表实例维护着options.data、records(渲染记录)、selection、history(撤销栈)等内部状态(见 factory.js),所有变更都直接作用于这些内部对象,而不是走 React 的受控组件数据流。因此,如果直接把 React state 作为表格数据源来回写,会造成渲染路径重复与性能损耗。
正确做法:通过事件同步到 React
正确的集成姿势是:声明 Jspreadsheet 事件,在事件回调中把网格内部变化同步到 React 状态(如setState、Context、Redux 等)。例如监听onafterchanges,在数据发生批量变更后触发 React 侧更新:
import React, { useRef, useEffect } from "react"; import { Spreadsheet, Worksheet } from "@jspreadsheet-ce/react"; import "jspreadsheet-ce/dist/jspreadsheet.css"; import "jsuites/dist/jsuites.css"; export default function App() { // Spreadsheet array of worksheets const spreadsheet = useRef(); const afterchanges = function() { // There were changes on the data } // Render component return ( <Spreadsheet ref={spreadsheet} onafterchanges={afterchanges}> <Worksheet minDimensions={[6, 6]} /> </Spreadsheet> ); }封装组件会把onafterchanges这类on*属性映射为表格配置中的同名事件回调。事件可在spreadsheet 级别声明,完整的事件列表与用法示例见仓库内 events 文档。
源码视角:事件是如何被派发的
事件系统的核心在 dispatch.js:
dispatch(event)会依次调用全局onevent回调、spreadsheet.config[event]指定的具体事件回调,以及所有插件的onevent(见 dispatch.js),因此一个事件可以同时被多级监听器处理。- 以
onafterchanges为例,它在 data.js 中于setValue批量写入完成后被触发:每次调用会收集变更记录(每个记录含x、y、value、oldValue),再dispatch.call(obj, 'onafterchanges', obj, records)派发出去。也就是说,回调拿到的参数依次是工作表实例与变更记录数组,你可以在回调中据此精确更新 React 侧的 diff 数据。 - 若配置了
persistence(数据持久化),onafterchanges还会触发save(),把变更后的 JSON 通过POST提交到url(见 dispatch.js),实现服务端自动保存。
常用事件速查
以下表格整理自 events 文档,是 React 集成中最常配合使用的关键事件:
| 事件 | 触发时机 |
|---|---|
onload | 电子表格加载完成 |
onbeforechange/onchange | 单元格值变更前 / 变更后 |
onafterchanges | 所有待处理变更已应用到表格后(批量同步首选) |
onbeforepaste/onpaste | 粘贴前(可解析输入数据)/ 粘贴后 |
oninsertrow/ondeleterow | 插入行 / 删除行之后 |
oninsertcolumn/ondeletecolumn | 插入列 / 删除列之后 |
onmoverow/onmovecolumn | 移动行 / 移动列之后 |
onresizerow/onresizecolumn | 行高 / 列宽变化后 |
onselection | 选区变化时 |
onsort | 列排序后 |
onmerge/onunmerge | 合并单元格 / 取消合并 |
onchangeheader | 表头文字变更后 |
onundo/onredo | 执行撤销 / 重做后 |
oneditionstart/oneditionend | 打开编辑器 / 关闭编辑器 |
典型联动场景:在onchange或onafterchanges回调中调用setState更新 React 组件(例如同步一个外部图表、统计面板或提交按钮状态),即可实现"网格编辑 → React 状态 → 外部组件"的闭环。仓库 events.md 中还提供了一个用onchange把表格数据实时联动 Highcharts 图表的完整示例,可直接迁移到 React 项目。
Jspreadsheet Pro 与 React 的扩展能力
本文聚焦 CE(社区版,MIT 协议,仓库源码即 CE)。官方同时提供商业版Jspreadsheet Pro,在原文档中描述了面向 React 的增强能力,可作为选型参考(以下内容来自官方文档对 Pro 的介绍,CE 仓库不包含 Pro 实现):
- 增强的 React 集成:完整的 TypeScript 类型定义、
useSpreadsheet/useWorksheet自定义 Hooks、Redux/MobX 状态管理集成、React Context 全局状态、Next.js/Gatsby 的 SSR/SSG 支持,以及 React 18 并发渲染与自动批处理。 - 专业级组件:条件下拉、富文本/HTML 编辑器,500+ Excel 函数公式系统,条件格式化(数据条、色阶、图标集),实时数据校验,.xlsx 完整导入导出,内置图表组件。
- 性能与规模:支持 10 万行以上数据的虚拟滚动、按需懒加载、React 优化渲染、Web Worker 后台计算与内存管理。
- 开发体验:React 专属文档、专业支持、CE 到 Pro 的迁移工具,并支持用自定义 React 组件作为单元格编辑器、PropTypes/TypeScript 校验、Jest/React Testing Library 测试示例。
此外,原文档还列举了若干社区示例方向,包括:实时协作的 React 电子表格(服务端同步)、React 自定义单元格编辑器、用 Recharts 等 React 组件嵌入表格、React 类组件写法、带单元格校验的数据网格、MUI/Antd 组件作为日期编辑器,以及 NextJS 下的在线 XLSX 读取与 Excel 文件导入。这些示例均以 Jspreadsheet 官方 React 封装为基座,与本文介绍的Spreadsheet/Worksheet用法一脉相承。
小结与进一步阅读
在 React 项目中集成 Jspreadsheet CE 的完整路径可归纳为三步:
- 安装与样式:
npm install @jspreadsheet-ce/react@5.0.0-beta.3,引入jsuites.css、jspreadsheet.css与 Material Icons; - 选择集成方式:声明式使用
<Spreadsheet>+<Worksheet>,或命令式调用jspreadsheet(ref.current, options)并做好一次性初始化守卫; - 状态同步:牢记"不与 React State 直接绑定",通过
onafterchanges等事件把内部变更同步到 React 侧,必要时配合persistence实现服务端保存。
继续深入可参考仓库内的相关文档与源码:
- React 集成官方文档(本文主体来源)
- 事件系统完整文档(含 Highcharts 联动完整示例)
- React 测试指南(封装组件的测试写法)
- 快速上手文档(纯 JS 创建、销毁网格的全局方法)
- Angular 集成文档 与 Vue 集成文档(其他框架对照)
- 源码入口 src/index.js、工厂创建 src/utils/factory.js、事件派发 src/utils/dispatch.js、数据写入与
onafterchanges触发 src/utils/data.js
如需在本地构建与验证,可参考仓库根目录 package.json 中的脚本:npm install安装依赖、npm start启动开发服务器、npm test运行测试(Mocha + jsdom,测试用例位于 test 目录)。
- 前端
- UI组件
【免费下载链接】ce
Jspreadsheet is a lightweight JavaScript data grid component for creating interactive data grids with advanced spreadsheet controls.
相关推荐
攻克TypeScript类型难题:一文掌握Join类型挑战
攻克TypeScript类型难题:一文掌握Join类型挑战 你是否在TypeScript项目中遇到过需要将数组类型拼接成字符串的场景?是否对泛型编程感到困惑?本
前端UI组件在 Angular 中集成 Jspreadsheet 构建 TypeScript 数据网格:完整实战指南
在 Angular 中集成 Jspreadsheet 构建 TypeScript 数据网格:完整实战指南 Jspreadsheet CE 是一款轻量级、纯 Ja
前端UI组件Jspreadsheet CE 与 jQuery 集成实战:基于 v5 创建可交互的数据表格
Jspreadsheet CE 与 jQuery 集成实战:基于 v5 创建可交互的数据表格 本篇技术指南以 jquery.md https://link.gi
前端UI组件
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考