跳到主要内容

React Spreadsheet 概述

ReactSpreadsheet 是 DHTMLX Spreadsheet widget 的声明式 React 封装器。它提供基于组件的 API,以 props 描述电子表格状态,封装器负责与底层 widget 的同步。

备注

React Spreadsheet 封装器适用于 DHTMLX Spreadsheet 的 CommercialEnterpriseUltimate 授权版本。如需评估,请使用免费的 30 天评估包。安装说明请参见 安装

电子表格功能

React 封装器提供对 DHTMLX Spreadsheet 完整功能集的访问:

  • 多工作表电子表格,支持工作表标签页(添加、删除、重命名)
  • 单元格值、公式(90 余个内置函数)及数字格式化
  • 单元格样式、合并单元格、冻结窗格、数据校验
  • 排序、筛选和搜索
  • 行/列操作(添加、删除、隐藏/显示、调整大小、自动适应)
  • 通过 WebAssembly 模块实现 Excel(XLSX)导入和导出
  • 可自定义的工具栏和右键菜单
  • 单元格锁定和只读模式
  • 4 种内置主题(light、dark、contrast-light、contrast-dark),支持 CSS 变量自定义
  • UI 标签、公式名称及数字/日期格式的本地化
  • 撤销/重做历史记录
  • TypeScript 支持,内置类型定义和 JSDoc 注释

封装器设计原则

  • Props 描述状态,而非操作。 没有"触发"类 props。传入数据,组件将相应地更新 widget。
  • sheets 是唯一数据源,涵盖所有电子表格数据:单元格、合并区域、冻结窗格、筛选器、排序。
  • Ref 是逃生舱。 对于无法映射到声明式 props 的操作(导出、程序化选区、撤销/重做),可通过 ref 访问底层 widget 实例。
  • 所有 widget 事件均以类型化的 onXxx 回调 props 形式暴露。 "Before" 回调可返回 false 以取消操作。

版本要求

  • React 18+
  • 仅支持 ESM 包

快速开始

以下是一个最简可运行示例,展示如何渲染包含一个工作表和格式化单元格的电子表格。

import { useState } from "react";
import { ReactSpreadsheet, type SheetData } from "@dhtmlx/trial-react-spreadsheet";
import "@dhtmlx/trial-react-spreadsheet/spreadsheet.react.css";

function App() {
const [sheets] = useState<SheetData[]>([
{
id: "sheet1",
name: "Sales",
cells: {
A1: { value: "Product", css: "bold" },
B1: { value: "Revenue", css: "bold", format: "currency" },
A2: { value: "Widget" },
B2: { value: 15000, format: "currency" },
},
},
]);

const styles = {
bold: { "font-weight": "bold" },
};

return <ReactSpreadsheet sheets={sheets} styles={styles} activeSheet="sheet1" />;
}

导入路径

评估版(公开 npm,30 天免费试用):

import { ReactSpreadsheet } from "@dhtmlx/trial-react-spreadsheet";
import "@dhtmlx/trial-react-spreadsheet/spreadsheet.react.css";

商业版(私有 npm,需要授权):

import { ReactSpreadsheet } from "@dhx/react-spreadsheet";
import "@dhx/react-spreadsheet/spreadsheet.react.css";

注册表配置及所有可用版本说明,请参见 安装

Prop 更新行为

Props 按组件处理变更的方式分为以下几类:

类别Props变更时的行为
仅初始化menueditLinetoolbarBlocksmultiSheetsformatslocalizationimportModulePathexportModulePathspreadsheetLocalewidget 被销毁并重新创建。电子表格数据会被保留,但撤销/重做历史记录及 UI 状态(选区、滚动位置)将被重置。
运行时readonlyrowsCountcolsCount立即生效,不会造成数据丢失或 UI 状态重置。
数据sheetsactiveSheet增量应用;仅更新已变更的单元格、区域或设置。
重新解析styles样式变更需要完整的数据重新加载。电子表格数据会被保留,但撤销/重做历史记录及 UI 状态将被重置。
状态searchthemeloadUrl通过专用 widget API 应用,无副作用。
容器classNamestyle作用于封装器 <div> 的标准 React DOM props。

示例

包含公式的多工作表

两个工作表,包含单元格值和 SUM 公式,启用工作表标签页渲染。

const [sheets] = useState<SheetData[]>([
{
id: "revenue",
name: "Revenue",
cells: {
A1: { value: "Q1" }, B1: { value: "Q2" }, C1: { value: "Q3" }, D1: { value: "Q4" },
A2: { value: 12000 }, B2: { value: 15000 }, C2: { value: 18000 }, D2: { value: 21000 },
A3: { value: "Total" }, B3: { value: "=SUM(A2:D2)", format: "currency" },
},
},
{
id: "expenses",
name: "Expenses",
cells: {
A1: { value: "Category" }, B1: { value: "Amount", format: "currency" },
A2: { value: "Marketing" }, B2: { value: 5000, format: "currency" },
A3: { value: "Operations" }, B3: { value: 8000, format: "currency" },
},
},
]);

<ReactSpreadsheet sheets={sheets} multiSheets={true} activeSheet="revenue" />

自定义工具栏

toolbarBlocks 传入块标识符数组,仅显示所需的工具栏区域。

<ReactSpreadsheet
sheets={sheets}
toolbarBlocks={["undo", "colors", "decoration", "align", "format"]}
/>

只读模式与锁定单元格

设置 readonly={true} 可在 widget 层级禁用所有编辑。在单元格上添加 locked: true 可在非只读模式下单独保护特定单元格。

const sheets: SheetData[] = [
{
id: "sheet1",
name: "Report",
cells: {
A1: { value: "Metric", locked: true },
B1: { value: "Value", locked: true },
A2: { value: "Revenue", locked: true },
B2: { value: 50000, format: "currency", locked: true },
},
},
];

<ReactSpreadsheet sheets={sheets} readOnly={true} />

通过 ref 进行命令式访问

使用 SpreadsheetRef 可访问底层 widget 实例,用于无法映射到声明式 props 的操作,例如序列化数据、触发撤销/重做或以编程方式设置选区。

import { useRef } from "react";
import { ReactSpreadsheet, type SpreadsheetRef } from "@dhtmlx/trial-react-spreadsheet";

function App() {
const ref = useRef<SpreadsheetRef>(null);

const handleExport = () => {
const data = ref.current?.instance?.serialize();
console.log(data);
};

const handleUndo = () => {
ref.current?.instance?.undo();
};

return (
<>
<button onClick={handleExport}>Export</button>
<button onClick={handleUndo}>Undo</button>
<ReactSpreadsheet ref={ref} sheets={[]} />
</>
);
}

instance 属性在 widget 初始化之前及卸载之后均为 null

API 参考

文档内容
Props 参考所有组件 props 及其类型、默认值和示例
Events 参考按类别分组的事件回调 props
Types 参考TypeScript 接口、枚举及类型别名