本人之前擅长客户端GDI+,疫情期间偶然了解到Web前端的Canvas画布。突发奇想,遂一发不可收拾,于是就有了这么个产物--基于Canvas+React的高性能Table表格,可咸可甜

语言:JavaScript、TypeScript、ES6语法;

框架:React;

技术:Canvas画布;

性能:以装载并渲染18列、N行为标准,压测有以下性能指标(附,测试硬盘状态不是太好,08年的老盘)。

1 如需自适应列宽,30万行(30万,耗时24S)
2 若无需自适应列宽,可达百万级(30万,耗时5S)
3 自适应列宽模式,14500行,耗时1.5S
4 无自适应列宽,14500行,耗时忽略不计

特色:高性能、渲染流畅、操控顺滑、高扩展性(自定义派生列、单元格)、装载灵活、ES6语法、全程面向对象(class)、样式全部属性化(颜色、字体、尺寸、高度……抛弃繁杂的CSS样式表,降低入手门槛、维护复杂度);

目前已经支持的功能:

1、序号列、颜色(矩形、圆形)、进度、复选框、复选框集、按钮集、金额线、普通单元格;

2、右键显示隐藏列;

3、拖拽列索引顺序;

4、拖拽列宽;

5、自适应列宽;

6、数据结构(列表结构、树结构);

7、自定义行、单元格背景色、前景色;

8、自定义选中行、单元格的背景色;

9、焦点行背景色;

10、展开、折叠父子行;

11、表格数据排序;

12、表格内数据查找、定位;

13、数据选择模式(单选、多选--Shift辅助、鼠标滑动拖拽);

14、快捷键:↑(向上选择单元格或行)、↓(向下选择单元格或行)、←(向左选择单元格)、→(向右选择单元格)、PageUp(上翻一个显示范围)、PageDown(下翻一个显示范围)、Home(定位首行)、End(定位末行)、Ctrl+C(复制选中内容)、Ctrl+F(表格内数据查找、定位);

15、表格数据打印(目前针对页边距,还有点小瑕疵,需要手工调整一次页边距。大数据打印,尚且存有性能缺陷);

16、表格数据导出(时间紧迫,目前仅支持Excel);

17、多表头(支持表头合并);

18、单元格合并;

19、表头数据筛选、过滤(类似Excel数据筛选);

20、表格内容动态编辑(目前仅支持文本内容编辑,后续补充支持下拉框、日期框、数字框……);

21、表内,行数据拖拽交换(同级交换、父子级交换);

22、表外,行数据拖拽交换(不同表格之间,拖拽移除、或插入、或交换);

23、自定义右键菜单;

24、行定位(定位可视范围外、未渲染区域的选中行,并主动更新滚动条,使目标行处于可视范围内);

25、丰富的事件行为,总有一款适合您。单元格单击事件、行单击事件、行选择改变事件、表格勾选事件(行、列、单元格)、表格失焦事件、右键上下文选项单击事件……;

列表结构:

树结构:

右键菜单:

显示、隐藏列:

列头数据筛选:

案例一:绑定Column、Row、Cell对象

import React, { useEffect, useState } from 'react';
import ColumnCollection from '@/EniacComponents/Table/Collections/ColumnCollection';
import RowCollection from '@/EniacComponents/Table/Collections/RowCollection';
import TableCore, { IFieldData } from '@/EniacComponents/Table/TableCore';
import Table from '@/EniacComponents/Table/Index';const PageTableBindColumns = () => {const [columns, setColumns] = useState(new ColumnCollection());const [rows, setRows] = useState(new RowCollection());const BuildColumns = () => {let loColumns = columns;if (!loColumns || loColumns.Count === 0) {let loFieldList: IFieldData[] = [{ Name: 'colSequenceColumn', Text: '', Type: 'SequenceColumn' },{ Name: 'colCheckBoxColumn', Text: '', Type: 'CheckBoxColumn' },{ Name: 'name', Text: '姓名', Type: 'Column' },{ Name: 'age', Text: '年龄', Type: 'Column' },{ Name: 'sex', Text: '性别', Type: 'Column' },{ Name: 'items', Text: '功能清单', Type: 'CheckBoxListColumn' },{ Name: 'address', Text: '地址', Type: 'Column' },{ Name: 'assets_b', Text: '资产-本币', Type: 'AmountColumn' },{ Name: 'assets_y', Text: '资产-原币', Type: 'AmountColumn' },{ Name: 'controls', Text: '操作列', Type: 'ButtonColumn' },];loColumns = new ColumnCollection();for (let liIndex = 0; liIndex < loFieldList.length; liIndex++) {let loCulumnData = loFieldList[liIndex];let loColumn = TableCore.CreateColumn(loCulumnData);loColumns.Add(loColumn);}setColumns(loColumns);}return loColumns;};const BuildRows = (poColumns: ColumnCollection) => {if (!rows || rows.length === 0) {let loDataList = [{name: '辛弃疾',age: 37,items: '喝酒,true;文臣,true;武将,true',sex: '男',address: '南宋',assets_b: 56832.215,assets_y: 56832.215,controls: '新增;修改;复制;审核;反审核;删除',},{name: '苏洵',age: 62,items: '喝酒,true;文臣,true;武将,false',sex: '男',address: '北宋',assets_b: 65912.32,assets_y: 65912.32,controls: '新增;修改;复制;审核;反审核;删除',},{name: '苏轼',age: 46,items: '喝酒,true;文臣,true;武将,true',sex: '男',address: '北宋',assets_b: 92615.68,assets_y: 92615.68,controls: '新增;修改;复制;审核;反审核;删除',},{name: '苏辙',age: 43,items: '喝酒,true;文臣,true;武将,true',sex: '男',address: '北宋',assets_b: 4689.36,assets_y: 4689.36,controls: '新增;修改;复制;审核;反审核;删除',},{name: '欧阳修',age: 78,items: '喝酒,true;文臣,true;武将,false',sex: '男',address: '北宋',assets_b: 9956592.36,assets_y: 9956592.36,controls: '新增;修改;复制;审核;反审核;删除',},{name: '王维',age: 66,items: '喝酒,true;文臣,true;武将,false',sex: '男',address: '大唐',assets_b: 6588.66,assets_y: 6588.66,controls: '新增;修改;复制;审核;反审核;删除',},{name: '杜甫',age: 48,items: '喝酒,true;文臣,true;武将,false',sex: '男',address: '大唐',assets_b: 6523698.99,assets_y: 6523698.99,controls: '新增;修改;复制;审核;反审核;删除',},{name: '李白',age: 63,items: '喝酒,true;文臣,true;武将,true',sex: '男',address: '大唐',assets_b: 98217365.922,assets_y: 98217365.922,controls: '新增;修改;复制;审核;反审核;删除',},{name: '李清照',age: 53,items: '喝酒,true;文臣,true;武将,true',sex: '女',address: '大宋',assets_b: 16591.52,assets_y: 16591.52,controls: '新增;修改;复制;审核;反审核;删除',},{name: '施耐庵',age: 56,items: '喝酒,true;文臣,true;武将,true',sex: '男',address: '大明',assets_b: 32336.12,assets_y: 32336.12,controls: '新增;修改;复制;审核;反审核;删除',},{name: '曹雪芹',age: 36,items: '喝酒,true;文臣,true;武将,true',sex: '男',address: '大清',assets_b: 615292.77,assets_y: 615292.77,controls: '新增;修改;复制;审核;反审核;删除',},{name: '罗贯中',age: 68,items: '喝酒,true;文臣,true;武将,true',sex: '男',address: '元末明初',assets_b: 6668214.53,assets_y: 6668214.53,controls: '新增;修改;复制;审核;反审核;删除',},];let loRows = new RowCollection();loDataList.forEach((loRowData: object) => {let loRow = TableCore.CreateRow(poColumns, loRowData);if (loRow) {loRows.Add(loRow);}});setRows(loRows);}};const BuildTableData = () => {let loColumns = BuildColumns();BuildRows(loColumns);};useEffect(() => {BuildTableData();}, [columns, rows]);return (<TableWidth={'100%'}Height={'100%'}Properties={{Draggable: true,ShowCheckBoxColumn: true,ShowSequenceColumn: true,ContextMenuVisible: true,ColumnHeight: 40,}}DataSource={null}Items={{ Columns: columns, Rows: rows }}></Table>);
};export default PageTableBindColumns;

案例二:绑定数据源、事件的使用

import React, { useEffect, useState } from 'react';
import Table from '@/EniacComponents/Table/Index';
import ToolStripView from '../Components/ToolStrip/ToolStripView';
import { IFieldData } from '@/EniacComponents/Table/TableCore';const PageTableBindFields = () => {const [fieldList, setFieldList] = useState([] as IFieldData[]);const [dataList, setDataList] = useState([] as object[]);const BuildFieldList = () => {if (!fieldList || fieldList.length === 0) {let loFieldList: IFieldData[] = [{ Name: 'name', Text: '姓名', Type: 'Column' },{ Name: 'age', Text: '年龄', Type: 'Column' },{ Name: 'items', Text: '功能清单', Type: 'CheckBoxListColumn' },{ Name: 'sex', Text: '性别', Type: 'Column' },{ Name: 'address', Text: '地址', Type: 'Column' },];setFieldList(loFieldList);}};const BuildDataList = () => {if (!dataList || dataList.length === 0) {let loDataList: any[] = [{ name: '辛弃疾', age: 37, items: '新增;修改;复制;删除;', sex: '男', address: '南宋' },{ name: '苏洵', age: 62, items: '新增;修改;复制;删除;', sex: '男', address: '北宋' },{ name: '苏轼', age: 46, items: '新增;修改;复制;删除;', sex: '男', address: '北宋' },{ name: '苏辙', age: 43, items: '新增;修改;复制;删除;', sex: '男', address: '北宋' },{ name: '欧阳修', age: 78, items: '新增;修改;复制;删除;', sex: '男', address: '北宋' },{ name: '王维', age: 66, items: '新增;修改;复制;删除;', sex: '男', address: '大唐' },{ name: '杜甫', age: 48, items: '新增;修改;复制;删除;', sex: '男', address: '大唐' },{ name: '李白', age: 63, items: '新增;修改;复制;删除;', sex: '男', address: '大唐' },{ name: '李清照', age: 53, items: '新增;修改;复制;删除;', sex: '女', address: '大宋' },{ name: '施耐庵', age: 56, items: '新增;修改;复制;删除;', sex: '男', address: '大明' },{ name: '曹雪芹', age: 36, items: '新增;修改;复制;删除;', sex: '男', address: '大清' },{ name: '罗贯中', age: 68, items: '新增;修改;复制;删除;', sex: '男', address: '元末明初' },{ name: '辛弃疾', age: 37, items: '新增;修改;复制;删除;', sex: '男', address: '南宋' },{ name: '苏洵', age: 62, items: '新增;修改;复制;删除;', sex: '男', address: '北宋' },{ name: '苏轼', age: 46, items: '新增;修改;复制;删除;', sex: '男', address: '北宋' },{ name: '苏辙', age: 43, items: '新增;修改;复制;删除;', sex: '男', address: '北宋' },{ name: '欧阳修', age: 78, items: '新增;修改;复制;删除;', sex: '男', address: '北宋' },{ name: '王维', age: 66, items: '新增;修改;复制;删除;', sex: '男', address: '大唐' },{ name: '杜甫', age: 48, items: '新增;修改;复制;删除;', sex: '男', address: '大唐' },{ name: '李白', age: 63, items: '新增;修改;复制;删除;', sex: '男', address: '大唐' },{ name: '李清照', age: 53, items: '新增;修改;复制;删除;', sex: '女', address: '大宋' },{ name: '施耐庵', age: 56, items: '新增;修改;复制;删除;', sex: '男', address: '大明' },{ name: '曹雪芹', age: 36, items: '新增;修改;复制;删除;', sex: '男', address: '大清' },{ name: '罗贯中', age: 68, items: '新增;修改;复制;删除;', sex: '男', address: '元末明初' },{ name: '辛弃疾', age: 37, items: '新增;修改;复制;删除;', sex: '男', address: '南宋' },{ name: '苏洵', age: 62, items: '新增;修改;复制;删除;', sex: '男', address: '北宋' },{ name: '苏轼', age: 46, items: '新增;修改;复制;删除;', sex: '男', address: '北宋' },{ name: '苏辙', age: 43, items: '新增;修改;复制;删除;', sex: '男', address: '北宋' },{ name: '欧阳修', age: 78, items: '新增;修改;复制;删除;', sex: '男', address: '北宋' },{ name: '王维', age: 66, items: '新增;修改;复制;删除;', sex: '男', address: '大唐' },{ name: '杜甫', age: 48, items: '新增;修改;复制;删除;', sex: '男', address: '大唐' },{ name: '李白', age: 63, items: '新增;修改;复制;删除;', sex: '男', address: '大唐' },{ name: '李清照', age: 53, items: '新增;修改;复制;删除;', sex: '女', address: '大宋' },{ name: '施耐庵', age: 56, items: '新增;修改;复制;删除;', sex: '男', address: '大明' },{ name: '曹雪芹', age: 36, items: '新增;修改;复制;删除;', sex: '男', address: '大清' },{ name: '罗贯中', age: 68, items: '新增;修改;复制;删除;', sex: '男', address: '元末明初' },{ name: '辛弃疾', age: 37, items: '新增;修改;复制;删除;', sex: '男', address: '南宋' },{ name: '苏洵', age: 62, items: '新增;修改;复制;删除;', sex: '男', address: '北宋' },{ name: '苏轼', age: 46, items: '新增;修改;复制;删除;', sex: '男', address: '北宋' },{ name: '苏辙', age: 43, items: '新增;修改;复制;删除;', sex: '男', address: '北宋' },{ name: '欧阳修', age: 78, items: '新增;修改;复制;删除;', sex: '男', address: '北宋' },{ name: '王维', age: 66, items: '新增;修改;复制;删除;', sex: '男', address: '大唐' },{ name: '杜甫', age: 48, items: '新增;修改;复制;删除;', sex: '男', address: '大唐' },{ name: '李白', age: 63, items: '新增;修改;复制;删除;', sex: '男', address: '大唐' },{ name: '李清照', age: 53, items: '新增;修改;复制;删除;', sex: '女', address: '大宋' },{ name: '施耐庵', age: 56, items: '新增;修改;复制;删除;', sex: '男', address: '大明' },{ name: '曹雪芹', age: 36, items: '新增;修改;复制;删除;', sex: '男', address: '大清' },{ name: '罗贯中', age: 68, items: '新增;修改;复制;删除;', sex: '男', address: '元末明初' },{ name: '辛弃疾', age: 37, items: '新增;修改;复制;删除;', sex: '男', address: '南宋' },{ name: '苏洵', age: 62, items: '新增;修改;复制;删除;', sex: '男', address: '北宋' },{ name: '苏轼', age: 46, items: '新增;修改;复制;删除;', sex: '男', address: '北宋' },{ name: '苏辙', age: 43, items: '新增;修改;复制;删除;', sex: '男', address: '北宋' },{ name: '欧阳修', age: 78, items: '新增;修改;复制;删除;', sex: '男', address: '北宋' },{ name: '王维', age: 66, items: '新增;修改;复制;删除;', sex: '男', address: '大唐' },{ name: '杜甫', age: 48, items: '新增;修改;复制;删除;', sex: '男', address: '大唐' },{ name: '李白', age: 63, items: '新增;修改;复制;删除;', sex: '男', address: '大唐' },{ name: '李清照', age: 53, items: '新增;修改;复制;删除;', sex: '女', address: '大宋' },{ name: '施耐庵', age: 56, items: '新增;修改;复制;删除;', sex: '男', address: '大明' },{ name: '曹雪芹', age: 36, items: '新增;修改;复制;删除;', sex: '男', address: '大清' },{ name: '罗贯中', age: 68, items: '新增;修改;复制;删除;', sex: '男', address: '元末明初' },];setDataList(loDataList);}};useEffect(() => {BuildFieldList();BuildDataList();}, [fieldList, dataList]);const table_CellClick = (e: any) => {console.log('table_CellClick', e.Cell.Text);};const table_RowClick = (e: any) => {console.log('table_RowClick', e.Row);};const table_SelectionChanged = (e: any) => {console.log('table_SelectionChanged', e.Row);};const table_CheckStateChanged = (e: any) => {if (e.Cell) {console.log('勾选单元格', e.Cell);} else if (e.Row) {console.log('勾选行', e.Row);} else if (e.Column) {console.log('勾选列', e.Column);}};const table_ContextItemClick = (e: any) => {console.log('table_ContextMenuItemClick', e.Item);};const table_GotFocus = (e: any) => {console.log('table_GotFocus', '获得焦点');};const table_LostFocus = (e: any) => {console.log('table_LostFocus', '失去焦点');};return (<div style={{ width: '100%', height: '100%' }}><div><ToolStripView ItemStyle={'ImageBeforeText'}></ToolStripView></div><div style={{ width: '100%', height: 'calc(100% - 43px)' }}><TableWidth={'100%'}Height={'100%'}Properties={{AllowDragRow: true,ShowCheckBoxColumn: true,ShowSequenceColumn: true,ContextMenuVisible: true,CustomContextItems: [{ Name: 'CustomItem1', Text: '自定义选项1号' },{ Name: 'CustomItem2', Text: '自定义选项2号' },],}}DataSource={{ FieldList: fieldList, DataList: dataList }}Items={null}OnCellClick={table_CellClick}OnRowClick={table_RowClick}OnSelectionChanged={table_SelectionChanged}OnCheckStateChanged={table_CheckStateChanged}OnContextItemClick={table_ContextItemClick}OnGotFocus={table_GotFocus}OnLostFocus={table_LostFocus}></Table></div></div>);
};export default PageTableBindFields;

本人对GDI+、Canvas相当痴迷,并小有成就。欢迎咨询、洽谈,相互学习、互相进步。

基于Canvas+React的高性能Table表格相关推荐

  1. 基于iview2/3组件的Table表格树展开/折叠

    基本iview2/3组件的Table表格树折叠展开,其实就是展开的时候插入行,收缩的时候删除行 {title: '名称',key: 'name',minWidth: 200,ellipsis: tru ...

  2. React Table 表格组件使用教程 排序、分页、搜索过滤筛选功能实战开发

    React Table 表格组件使用教程 react-table 安装和使用 React Table 表格排序功能 React Table 表格搜索过滤筛选功能 React Table 表格分页功能 ...

  3. 基于HTTP浏览器缓存机制全面解析看Table表格的css样式代码详解

    文章来源: 学习通http://www.bdgxy.com/ 普学网http://www.boxinghulanban.cn/ 智学网http://www.jaxp.net/ 漂亮的table表格样式 ...

  4. vue渲染大量数据如何优化_Vue - Table表格渲染上千数据优化

    Vue - Table表格渲染上千数据优化 此次项目经验会谈谈常常在项目中,针对成千上万数据渲染优化的不断探索来谈谈本身的体会,其目的就是保证用户浏览上万条数据的时候,UI要很流畅,确保用户操做过程当 ...

  5. canvas换图时候会闪烁_基于Canvas实现的高斯模糊(上)「JS篇」

    作者:iNahoo 转发链接:https://mp.weixin.qq.com/s/5TxPjznpEBku_ybSMBdnfw 目录 基于Canvas实现的高斯模糊(上)「JS篇」本篇 基于Canv ...

  6. asp 设置table 间距_设置table表格

    <HTML.CSS.JavaScript 网页制作从入门到精通>--第6章 使用表格 本节书摘来自异步社区<HTML.CSS.JavaScript 网页制作从入门到精通>一书中 ...

  7. 1万条数据大概占多大空间_Vue - Table表格渲染上千数据优化

    这次项目经验会谈谈经常在项目中,针对成千上万数据渲染优化的不断探索来谈谈自己的体会,其目的就是保证用户浏览上万条数据的时候,UI要很流畅,确保用户操作过程中不会出现UI卡顿或者最糟糕的情况,直接浏览器 ...

  8. react-antd项目,一个多tab页面,共用一个title相同的table表格,并且在切换tab时实现数据更新

    一.前言 最近因为项目要求,开始学习并且使用React和Ant Design框架.在前端开发过程中,遇到这样一个页面:有多个tab,每个tab下都是一个table表格来进行数据展示.但,每个table ...

  9. 顶级好用的 5 款 Vue table 表格组件测评与推荐

    本文首发:<顶级好用的 5 款 Vue table 表格组件测评与推荐 - 卡拉云> Vue table 表格组件作为绝大多数项目需要内嵌的组件,可谓十分重要.表格看起来虽简单,实则坑很深 ...

  10. layui table 弹出层刷新_layui 关闭open弹出框 刷新table表格页面的方法

    layui 关闭open弹出框 刷新table表格页面的方法 如下所示: 保存后刷新table表格 源码 //弹出框 layer.open({ type: 2, shadeClose: true, s ...

最新文章

  1. centos中mysql重置密码
  2. hadoop自定义类型注意问题
  3. android 字符串相似度对比,Android中的OpenCV图像比较和相似度
  4. CentOS 使用 Docker 安装 Sentry
  5. 监听列表ListVIew的滑动状态
  6. 【2019浙江省赛 - A】Vertices in the Pocket(权值线段树下二分,图,思维)
  7. LeetCode 413 等差数列划分
  8. c语言标准课程方案,《C语言程序设计》课程标准方案.doc
  9. 认真去做,我会做得很棒!
  10. WPF-使用代码创建Grid行与列,并将控件添加到Grid中的指定行指定列
  11. 《线性代数及其应用》看完
  12. 一帆风顺幼儿园管理软件 v3.01 bt
  13. 开源项目-绩效管理系统
  14. 英语字母演变——wsdchong
  15. 冰镇西瓜文案:冰镇西瓜水果文案大全集,水果类冰镇西瓜推销文案
  16. python判断是否构成三角形并计算面积
  17. 西门子安装未找到ssf文件_西门子300软件安装出错处理方法
  18. crm系统部分功能截图
  19. 10-207 在订单表中查询运费在40元到60元之间的订单的全部信息
  20. 免费压缩解压软件eZip 1.7.3 Mac中文版

热门文章

  1. 汉洛塔hanoi递归问题
  2. Coloring Torus(Atcoder Grand Contest 030 C)
  3. Coursera machine learning week 6 excise
  4. putty linux上安装及使用
  5. 内存泄漏工具asan
  6. 启动修复 您想用系统还原还原计算机吗,sony笔记本电脑如何恢复系统
  7. 【名师大讲坛】叶俊受《金刚经》的启发创造“名非论”-火锅智烩节目组根据视频文字整理
  8. 文件服务器+快照恢复,删除vmware ESXi快照文件 – 以任何方式恢复?
  9. HTTP协议详解(一)
  10. goland 注释模板_论文写作标准格式模板