Handsontable 类似 excel 表格编辑器
HandsonTable 简介
- Handsontable 是一个类似 excel 表格编辑器,支持丰富的展现和交互,以及多样的单元格展现和配置
- 核心由原生 js (es6) 编写,通过webpack打包
- 同类 Jspreadsheets 项目中,点赞最多,Jspreadsheets列表
- 官网地址
HandsonTable 支持的特征
Handsontable 的一些主要功能:
- edit
- Context menu
- Drag-down
- Dropdown
- Freezing
- Merge cells
- Comments
- Data validation
- Custom HTML
- sortingtable
这里只列出主要功能,想了解更多更能,可以查询官方文档。这里附一张官方demo图:
如何实现一个handsontable
Handsontable 的核心可以分为配置,事件,方法三个方面:
配置
- 引入handsontable包,
- new 一个 Handsontable 实例
// 新建Hansontable实例
var container = document.getElementById('dataGrid');
var hot = new Handsontable(container, options); // options 如下
// Handsontable 的一些主要配置
var options = {
data: Array || Object, // data 是整个表格的数据源,可以接收一个二维数组,或者一个对象
rowHeaders: Boolean || Array || function,
colHeaders: Boolean || Array || function,
cells: function, // row, col, prop
stretchH: String, // 'all', 'none', 'last',
columns: Array || function,
columnSorting: Boolean || Object,
manualColumnResize: true,
renderer: function,
}
然后说一下上面每一个配置项的用法:
data data 是整个表格的数据源,可以接收一个二维数组,或者一个对象
// 作为数组
data = [
['', 'Kia', 'Nissan', 'Toyota', 'Honda', 'Mazda', 'Ford'],
['2012', 10, 11, 12, 13, 15, 16],
['2013', 10, 11, 12, 13, 15, 16],
['2014', 10, 11, 12, 13, 15, 16],
['2015', 10, 11, 12, 13, 15, 16],
['2016', 10, 11, 12, 13, 15, 16]
];
// 相应配置(每一列显示哪些数据由columns决定)
new Handsontable(container, {
data: data,
colHeaders: true,
columns: [
{data: 0},
{data: 2},
{data: 3},
{data: 4},
{data: 5},
{data: 6}
]
});
// 作为对象数据
data = [
{id: 1, name: 'Ted Right', address: ''},
{id: 2, name: 'Frank Honest', address: ''},
{id: 3, name: 'Joan Well', address: ''},
{id: 4, name: 'Gail Polite', address: ''},
{id: 5, name: 'Michael Fair', address: ''},
];
new Handsontable(container5, {
data: data,
colHeaders: true,
columns: [
{data: 'id'},
{data: 'name'},
{data: 'address'}
],
});
rowHeaders rowHeaders属性用来设置表格每一行的标题,有三种形式:
// 若为 true, 则行标题从1开始,依次往后
{
rowHeaders: true,
}
// 设置为数组, 则按数组内容显示
{
rowHeader: [1, 2, 3, 4, 5]
}
// 函数,接收一个index参数,更加灵活
{
rowHeader: function(index) {
return index + 'AB';
}
}
cells
cells
属性用来设置每个单元格的属性
// 设置第一列只读
{
cells: function (row, col, prop) {
var cellProperties = {};
if (col === 0) {
cellProperties.readOnly = true;
}
return cellProperties;
}
}
stretchH
stretchH
属性用来设置表格的展开方式,all
全列按最大宽度展开; none
紧缩的表格; last
最后一列展开
{
stretchH: 'all' // all 全列按最大宽度展开; none 紧缩的表格; last 最后一列展开
}
columns
columns
属性,用来定义列属性,也就是每一列需要显示数据源的哪个属性。除此之外,也可以定义每一列的数据属性,
{
columns: [
{data: 'id'}, // 第一列显示 id 属性
{data: 'name'}, // 第二列显示 name 属性
{data: 'age', type: 'numeric'}, // 第三列显示 age 属性,并且只能填数字
{data: 'address'} // 第四列显示 address 属性
],
}
columnSorting
columnSorting
用来设置表格的列是否可排序,
renderer
renderer
属性可以自定义单元格的各种属性
// 第三行有数据的单元格涂色
{
renderer: function (instance, td, row, col, prop, value, cellProperties) {
// 渲染为text类型,可选的有TimeRenderer、PasswordRenderer等不同的类型
Handsontable.renderers.TextRenderer.apply(this, arguments);
// 判断条件
if (value && row === 2) {
td.style.backgroundColor = '#e0ecff';
}
}
}
事件
生成 Handsontable 实例之后,一张表格就显示好了,如果想加入更多交互效果,就需要注册监听事件。
// 实例对象
var hot = new Handsontable(container, options);
// 用实例方法addHook注册事件
hot.addHook(key, callback); // key 为事件名
// 除了addHook 方法之外,也可以将事件名,写入配置中
{
afterChange: function (change) {}
}
常用事件
afterChange
afterChange
在单元格改变时触发,如编辑单元格之后,接收两个参数changeData
, source
hot.addHook('afterChange', function (changeData, source) {
// changeData 是一个数组,第一个元素(数组),记录所有修改信息
if (!changeData) return;
var change = changeData[0],
row = change[0],
colProp = change[1],
preData = change[2],
newData = change[3];
})
afterOnCellMouseDown
afterOnCellMouseDown
在鼠标点击单元格之后触发
// afterOnCellMouseDown 在鼠标点击单元格之后触发,接收两个参数 event cellCoords
// event 标准鼠标点击事件
// cellCoords 对象,保存row,col信息
hot.addHook('afterOnCellMouseDown ', function (event, cellCoords) {
var row = cellCoords.row,
col = cellCoords.col;
})
afterBeginEditing
afterBeginEditing
在单元格开始编辑时触发
hot.addHook('afterBeginEditing', function (row, col) {})
方法
getCell
getCell(row, col)
获取指定单元格
alter
alter(action, index, amount, source, keepEmptyRows)
alter方法用于改变表格结构,即插入或删除行列数据。
action
可用改变表格结构操作insert_row、insert_col、remove_row、remove_col
index
行列索引值,从0开始,insert操作将插入到该索引值的前一行/列
amount
(可选,默认1):将要插入/删除的行列数
source
(可选):行或列对象
keepEmptyRows
(可选):防止删除空行,true/false
setDataAtCell
setDataAtCell(row, col, value, source)
设置某个单元格的数据
row
行号索引
col
列号索引
value
将要设置的单元格数据
source
(可选)字符串标识中描述这一变化将如何改变数组(用于onAfterChange或onBeforeChange回调)
生成的html结构
如下代码所示,生成的表格主体在ht_master
中,rowHeader
、colHeader
和freezingCol
会clone主体部分内容,放在其兄弟节点。同时,edit时的input会生成唯一一个textarea。
<div id="handsonTable">
<div class="ht_master"></div> <!-- table 主体 -->
<div class="ht_clone_top"></div> <!-- column header clone -->
<div class="ht_clone_left"></div> <!-- freezing left clone -->
<div class="ht_clone_top_left_corner"></div> <!-- freezing column top clone -->
<div class="handsontableInputHolder"></div> <!-- edit textarea -->
</div>