Univer 表格 UI 插件指南:使用 @univerjs/sheets-table-ui 为电子表格接入结构化表格交互
2026/9/14 4:16:37 网站建设 项目流程

Univer 表格 UI 插件指南:使用 @univerjs/sheets-table-ui 为电子表格接入结构化表格交互

【免费下载链接】univerUniver is a full-stack framework for creating and editing spreadsheets / word processor / presentation on both web and server.项目地址: https://gitcode.com/GitHub_Trending/un/univer

@univerjs/sheets-table-ui是 Univer Sheets 的结构化表格(Structured Table)UI 层插件,它把「插入表格」「筛选面板」「表格选择器」「行/列增删菜单」「主题切换」等表格相关的界面与交互能力集成到 Univer 电子表格中。本文以 packages/sheets-table-ui/README.md 为主线,结合仓库源码讲解该插件的安装、注册、配置、命令与控制器体系,帮助你快速在项目中落地可用的表格交互工作流。

包概览与定位

在 Univer 的模块化架构中,@univerjs/sheets-table-ui与「表格(Table)」相关的几个包分工明确:

Package定位
@univerjs/sheets-table表格核心模型层,提供TableManagerSheetTableServiceSetSheetTableFilterCommand等数据与命令能力(不含 UI)
@univerjs/sheets-table-ui表格 UI 层,提供菜单、筛选面板、选择器、主题面板、渲染控制器等界面交互

从 package.json 的依赖可以看出,UI 层依赖了@univerjs/sheets-table(表格核心模型)、@univerjs/sheets(电子表格)、@univerjs/sheets-ui(电子表格 UI 基础)以及@univerjs/engine-render(渲染引擎)等,说明它是在表格核心能力之上叠加的交互层。

包元信息

README 的 Package Overview 表格给出了关键打包信息:

属性
Package@univerjs/sheets-table-ui
UMD globalUniverSheetsTableUi
CSS是(需要单独引入lib/index.css
Locales是(内置 20 种语言)
Facade entry
  • UMD global:使用 CDN 的 UMD 构建时,全局变量名为UniverSheetsTableUi
  • CSS:该包包含样式文件,使用前必须导入。
  • Locales:内置了ar-SAca-ESde-DEen-USes-ESfa-IRfr-FRid-IDit-ITja-JPko-KRpl-PLpt-BRru-RUsk-SKvi-VNzh-CNzh-HKzh-TW等语言资源(见 src/locale 目录)。
  • Facade entry:本包未提供 Facade 入口(README 中标记为 No),意味着你主要直接通过插件与命令 API 使用它,而不是通过FWorksheet等 Facade 对象。

安装

README 提供了两种安装方式(包管理器任选其一,注意保持所有@univerjs/*包版本一致):

pnpm add @univerjs/sheets-table-ui # or npm install @univerjs/sheets-table-ui

提示:本仓库采用 pnpm workspace 管理,仓库内该包版本为1.0.0-beta.2(见 package.json)。README 强调Keep all@univerjs/*packages on the same version,这是 Univer 各插件包之间的版本耦合约定,混用不同版本可能导致类型或运行时的不兼容。

使用:注册插件

README 给出了最小注册代码:

import '@univerjs/sheets-table-ui/lib/index.css'; import EnUS from '@univerjs/sheets-table-ui/locale/en-US'; import { UniverSheetsTableUIPlugin } from '@univerjs/sheets-table-ui'; univer.registerPlugin(UniverSheetsTableUIPlugin); // Merge EnUS into your Univer locale map when this package contributes UI text.

这里有三点值得展开:

  1. CSS 必须单独引入@univerjs/sheets-table-ui/lib/index.css对应 src/global.css,入口 src/index.ts 通过import './global.css'声明了样式依赖。构建产物(publishConfig 的exports映射)会把样式输出到lib/es/index.css
  2. Locale 合并:该包贡献了界面文案(如sheets-table-ui.titlesheets-table-ui.condition.empty等),需要把对应语言包合并进 Univer 的 locale 映射后再创建 Univer 实例。语言包文件位于 src/locale 下,可通过@univerjs/sheets-table-ui/locale/en-US这类子路径导入。
  3. 插件类型是 SheetUniverSheetsTableUIPlugintypeUniverInstanceType.UNIVER_SHEET(见 src/plugin.ts),即该插件只作用于电子表格实例,不会影响文档或幻灯片。

插件的依赖关系

从 src/plugin.ts 的@DependentOn装饰器可以看到,注册该插件前必须已经注册以下插件:

@DependentOn( UniverRenderEnginePlugin, // 渲染引擎 UniverSheetsPlugin, // 电子表格核心 UniverSheetsTablePlugin, // 表格核心模型 UniverSheetsUIPlugin // 电子表格 UI 基础 ) export class UniverSheetsTableUIPlugin extends Plugin

因此一个完整的初始化顺序大致为:UniverSheetsPluginUniverSheetsUIPluginUniverSheetsTablePluginUniverSheetsTableUIPlugin,渲染引擎插件则需先行或同时注册。

插件生命周期:onStarting / onReady / onRendered

UniverSheetsTableUIPlugin在三个生命周期钩子中完成了核心装配(见 src/plugin.ts):

  • onStarting:向注入器注册ComponentsController(并立即实例化)、SheetsTableComponentControllerSheetsTableUiServiceSheetTableMenuControllerSheetTableThemeUIControllerSheetTableSelectionController等依赖。
  • onReady:通过touchDependencies实例化上述依赖,确保控制器和服务的副作用(事件订阅、命令监听)生效。
  • onRendered_registerRenderModules()向渲染管理器注册渲染模块:
    • 当配置项hideAnchor !== true时注册SheetTableControlsRenderController(表格锚点控件渲染);
    • 无条件注册SheetsTableFilterButtonRenderController(筛选按钮渲染)与SheetsTableRenderController(表格区域渲染)。

此外,构造函数中通过_initRegisterCommand()注册了两个操作命令:OpenTableFilterPanelOperationOpenTableSelectorOperation(详见下文「命令与流程」)。

插件配置项

该插件支持通过univer.registerPlugin(UniverSheetsTableUIPlugin, { ... })的第二个参数传入配置。配置类型与默认值定义在 src/config/config.ts:

export interface IUniverSheetsTableUIConfig { anchorHeight?: number; anchorBackgroundColor?: string; hideAnchor?: boolean; menu?: MenuConfig; } export const defaultPluginConfig: IUniverSheetsTableUIConfig = { anchorHeight: 24, anchorBackgroundColor: 'rgb(134,139,156)', };

各配置项说明如下:

配置项类型默认值作用
anchorHeightnumber24表格锚点(插入/调整表格范围的悬浮控件)的高度(像素)
anchorBackgroundColorstringrgb(134,139,156)表格锚点的背景色
hideAnchorbooleanundefined(不隐藏)设为true时隐藏锚点控件,此时 src/plugin.ts 的_registerRenderModules()将不再注册SheetTableControlsRenderController
menuMenuConfig自定义菜单项配置,会通过configService.setConfig('menu', menu, { merge: true })合并进全局菜单配置

插件构造函数对配置的处理方式是:将传入配置与defaultPluginConfig做深合并,menu部分单独合并进全局menu配置,其余部分以SHEETS_TABLE_UI_PLUGIN_CONFIG_KEY'sheets-table-ui.config')为键写入配置服务。

示例:

univer.registerPlugin(UniverSheetsTableUIPlugin, { anchorHeight: 32, anchorBackgroundColor: '#8B8F9C', hideAnchor: false, });

命令与交互流程

UI 插件的核心价值体现在两个操作命令上,二者都在 src/plugin.ts 中注册,对应命令定义在 src/commands/operations 目录。

OpenTableSelectorOperation:插入表格(选择范围)

定义于 open-table-selector.operation.ts,命令 ID 为sheet.operation.open-table-selector。它的执行流程是:

  1. 通过getSheetCommandTarget获取当前工作簿与工作表;
  2. 取当前最后一次选区SheetsSelectionsService.getCurrentLastSelection();若为空则回退到A1单格;
  3. 若是单格选区,则调用expandToContinuousRange(range, { up: true, left: true, right: true, down: true }, worksheet)向四周扩展到连续数据区域,作为默认的表格范围;
  4. 调用openRangeSelector()打开表格范围选择对话框(TABLE_SELECTOR_DIALOG,宽 300,可拖拽、无遮罩);
  5. 用户确认后,通过AddSheetTableCommand(来自@univerjs/sheets-table)真正创建表格。

这段逻辑把「选区 → 范围推断 → 范围确认 → 建表」串成了完整的插入表格流程。其中openRangeSelector基于IDialogService打开对话框,并通过onConfirm/onCancel/onClose三个回调把选择结果以 Promise 形式返回给调用方。

OpenTableFilterPanelOperation:打开筛选面板

定义于 open-table-filter-dialog.opration.ts,命令 ID 为sheet.operation.open-table-filter-panel。它接收参数:

export interface IOpenTableFilterPanelOperationParams { row: number; col: number; unitId: string; subUnitId: string; tableId: string; }

执行时通过TableManager.getTable(unitId, tableId)校验表格存在,然后委托给SheetsTableComponentController.openOrToggleFilterPanel()打开或切换筛选面板。

筛选面板的开合机制

SheetsTableComponentController(见 src/controllers/sheet-table-component.controller.ts)用上下文键SHEETS_TABLE_FILTER_PANEL_OPENED_KEY管理面板状态:

  • 面板已打开且点击的是同一个筛选按钮 → 关闭面板;
  • 面板已打开但点击的是其他列 → 先销毁旧的浮层,再打开新的;
  • 面板未打开 → 置上下文为已打开,面板由_initUIPopup()中订阅subscribeContextValue$的回调创建(基于SheetCanvasPopManagerService的浮层)。

这种「上下文键 + RxJS 订阅」的模式,与 Univer 其他 UI 浮层(如筛选、数据验证面板)保持一致,属于可复用的交互范式。

UI 组件层

视图组件集中在 src/views/components 目录,主要包括:

组件职责
SheetTableSelector表格范围选择器(插入表格时选择区域)
SheetTableFilterPanel筛选主面板
SheetTableConditionPanel条件筛选面板(数值/文本条件)
SheetTableItemsFilterPanel按项(值)筛选面板,支持勾选与计数
SheetTableRenameDialog表格重命名对话框
SheetTableThemePanel表格主题(配色)面板
SheetTableMenu表格上下文菜单

配套的 src/views/widgets 目录提供渲染层形状:table-controls.shape.ts(表格锚点控件形状)、table-filter-button.shape.ts(表头筛选按钮形状)、drawings.tsicons.ts等,负责在 canvas 渲染层绘制交互元素。

服务层:筛选数据聚合

SheetsTableUiService(见 src/services/sheets-table-ui.service.ts)是 UI 层与表格模型之间的桥梁,负责:

  • 缓存筛选项:以tableId + columnIndex为键缓存每列的候选值列表(_itemsCache),并在两种情况下主动失效:
    • 单元格值被修改(监听SetRangeValuesMutation)且与某个表格范围相交时,删除对应列的缓存;
    • 表格筛选条件被设置(监听SetSheetTableFilterCommand)时,清空该工作表内所有表格的整行缓存。
  • 聚合候选值getTableFilterItems()遍历表格过滤范围的所有行,跳过其他列已过滤掉的行,统计当前列的取值分布(itemsCountMap)与总数(allItemsCount),空值显示为本地化的「(空白)」文案(sheets-table-ui.condition.empty)。
  • 读写筛选条件getTableFilterCheckedItems()读取手动筛选的勾选项,setTableFilter()通过SetSheetTableFilterCommand写入筛选条件。

这套缓存 + 事件失效机制保证了筛选面板在大量数据下不会重复扫描全表,同时数据一变立刻刷新候选列表。

菜单集成

菜单定义与控制器位于 src/menu 目录,index.ts导出了SheetsTableUIMenuSchemamenuSchema),你可以按需把它合并到自定义菜单配置中。菜单工厂函数包括:

  • 工具栏插入按钮sheetTableToolbarInsertMenuFactory——TableIcon图标、tooltip/标题为sheets-table-ui.title,点击触发OpenTableSelectorOperation(即插入表格);通过getCurrentRangeDisable$在非法选区(如整个工作表被选中)时自动禁用。
  • 右键菜单SheetTableInsertContextMenuFactory/SheetTableRemoveContextMenuFactory提供「插入行/列」「删除行/列」子菜单,分别绑定SheetTableInsertRowCommandSheetTableInsertColCommandSheetTableRemoveRowCommandSheetTableRemoveColCommand(均来自@univerjs/sheets-table),并用hidden$按当前上下文(是否位于表头、是否在表格内)动态显隐。

渲染控制器

渲染相关的控制器位于 src/controllers,通过IRenderManagerService.registerRenderModule注册到电子表格渲染单元:

  • SheetsTableRenderController:绘制表格区域(表头、行列边框、斑马纹等)。
  • SheetTableControlsRenderController:绘制表格锚点控件(拖拽调整表格范围),受hideAnchor配置控制。
  • SheetsTableFilterButtonRenderController:绘制表头筛选按钮,点击触发OpenTableFilterPanelOperation
  • SheetTableSelectionController:处理表格内的选区交互(如整行整列选择)。
  • SheetTableThemeUIController:管理表格主题的 UI 呈现。

每个控制器都有对应的单元测试(见 src/controllers/tests),例如sheet-table-controls-render.controller.spec.tssheet-table-filter-button-render.controller.spec.ts,可作为理解渲染行为的参考。

与表格核心层的配合

需要强调的是,UI 层本身不维护表格数据,所有数据操作最终都落到@univerjs/sheets-table

  • 建表:AddSheetTableCommand
  • 筛选:SetSheetTableFilterCommandSheetTableService
  • 行列操作:SheetTableInsertRowCommand/SheetTableInsertColCommand/SheetTableRemoveRowCommand/SheetTableRemoveColCommand
  • 表格元数据:TableManagergetTable/getTablesBySubunitId

从源码结构看,@univerjs/sheets-table-ui通过依赖注入(@Inject(TableManager)@Inject(SheetTableService))直接消费这些能力,并补充了面板、菜单、控件与本地化文案。因此在集成排错时,如果 UI 行为异常,应先确认底层@univerjs/sheets-table插件已正确注册。

小结

@univerjs/sheets-table-ui为 Univer Sheets 补齐了结构化表格的完整交互闭环:从「插入表格(范围选择)」到「筛选面板(条件/按项)」「行列表头右键操作」「主题与锚点控件」,并以插件生命周期、命令服务、上下文面板、渲染模块和缓存服务五层结构组织代码。接入时只需遵循 README 的三步(安装、导入 CSS、注册插件并合并 Locale),再按需通过配置项与菜单 Schema 定制行为即可。

【免费下载链接】univerUniver is a full-stack framework for creating and editing spreadsheets / word processor / presentation on both web and server.项目地址: https://gitcode.com/GitHub_Trending/un/univer

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询