handsontable是目前在前端界最接近excel的插件,可以執行編輯,復制粘貼,插入刪除行列,排序等復雜操作。擁有jQuery、react、ng和vue版本,功能強大,是復雜表格的不二之選。
下面介紹一下handsontable表格控件在vue項目中的使用方法:
1.安裝模塊包
npm install handsontable-pro @handsontable-pro/vue
npm install handsontable @handsontable/vue
這樣安裝完handsontable依賴的各模塊(moment、numbro、pikaday 、zeroclipboard)也一起安裝完了,不必再單獨安裝
頁面如果使用相關的模塊方法,可以直接import引入,例如使用moment中的格式化時間方法:
import moment from "moment"
formatTime(time){
return moment(time).format('YYYY-MM-DD HH:mm:ss')
}
formatTime(new Date())
- 引入模塊包
import { HotTable } from '@handsontable-pro/vue'
import '../../node_modules/handsontable-pro/dist/handsontable.full.css'
import Handsontable from 'handsontable-pro'
- 引入組件
<template>
<div>
<div id="hotTable" class="hotTable">
<HotTable ref="testHot" :settings="hotSettings"></HotTable>
</div>
</div>
</template>
- api參數說明
export default {
data: function () {
return {
root: 'test-hot',
hotSettings: {
data: [ //數據可以是二維數組,也可以是數組對象
['20080101', 10, 11, 12, 13,true],
['20090101', 20, 11, 14, 13,true],
['20010101', 30, 15, 12, 13,true],
['20010101', 32, 213, 21, 312,true],
['20010201', 32, 213, 21, 312,true],
['20010301', 32, 213, 21, 312,true],
['20010401', 32, 213, 21, 312,true],
['20010501', 32, 213, 21, 312,true],
['20010601', 32, 213, 21, 312,true]
],
startRows: 11,//行列范圍
startCols: 6,
minRows: 5, //最小行列
minCols: 5,
maxRows: 20, //最大行列
maxCols: 20,
rowHeaders: true,//行表頭,可以使布爾值(行序號),可以使字符串(左側行表頭相同顯示內容,可以解析html),也可以是數組(左側行表頭單獨顯示內容)。
colHeaders: [ '題目', 'A選項', 'B選項', 'C選項', 'D選項','答案'],//自定義列表頭or 布爾值
minSpareCols: 2, //列留白
minSpareRows: 2,//行留白
currentRowClassName: 'currentRow', //為選中行添加類名,可以更改樣式
currentColClassName: 'currentCol',//為選中列添加類名
autoWrapRow: true, //自動換行
contextMenu: { //自定義右鍵菜單,可漢化,默認布爾值
items: {
"row_above": {
name:'上方插入一行'
},
"row_below": {
name:'下方插入一行'
},
"col_left": {
name:'左方插入列'
},
"col_right": {
name:'右方插入列'
},
"hsep1": "---------", //提供分隔線
"remove_row": {
name: '刪除行',
},
"remove_col": {
name: '刪除列',
},
"make_read_only": {
name: '只讀',
},
"borders": {
name: '表格線',
},
"commentsAddEdit": {
name: '添加備注',
},
"commentsRemove": {
name: '取消備注',
},
"freeze_column": {
name: '固定列',
},
"unfreeze_column": {
name: '取消列固定',
},
"hsep2": "---------",
}
},//右鍵效果
fillHandle: true, //選中拖拽復制 possible values: true, false, "horizontal", "vertical"
fixedColumnsLeft: 0,//固定左邊列數
fixedRowsTop: 0,//固定上邊列數
mergeCells: [ //合并
{row: 1, col: 1, rowspan: 3, colspan: 3}, //指定合并,從(1,1)開始行3列3合并成一格
{row: 3, col: 4, rowspan: 2, colspan: 2}
],
columns: [ //添加每一列的數據類型和一些配置
{
//data: 'title', 此設置標識,數組對象數據格式時的列字段
type: 'date', //時間格式
dateFormat: 'YYYYMMDD',
correctFormat: true,
defaultDate: '19000101'
},
{
type: 'dropdown', //下拉選擇
source: ['BMW', 'Chrysler', 'Nissan', 'Suzuki', 'Toyota', 'Volvo'],
strict: false //是否嚴格匹配
},
{type: 'numeric'}, //數值
{type: 'numeric',
readOnly: true //設置只讀
},
{ type: 'numeric',
format: '$ 0,0.00'}, //指定的數據格式
{type: 'checkbox'}, //多選框
],
afterChange: function (changes, source) { //數據改變時觸發此方法
console.log(this.getData());
},
manualColumnFreeze: true, //手動固定列
manualColumnMove: true, //手動移動列
manualRowMove: true, //手動移動行
manualColumnResize: true,//手工更改列距
manualRowResize: true,//手動更改行距
comments: true, //添加注釋
cell: [
{row: 1, col: 1, comment: {value: 'this is test'}},
],
customBorders:[],//添加邊框
columnSorting: true,//排序
stretchH: 'all',//根據寬度橫向擴展,last:只擴展最后一列,none:默認不擴展
}
};
},
name: 'handsonTable',
components: {
HotTable
},
methods: {
saveData (){
var examData = this.$refs.testHot.table.getData(); //這里要注意,如果使用this.hotSettings.data 保存表格數據,拖拽完以后數據的順序將不會更新,因此使用 this.$refs.testHot.table.getData(); 來獲取數據,獲取的數據格式為二維數組。
console.log(examData );
}
}
}
- 完整示例
import { HotTable } from '@handsontable-pro/vue'
import '../../node_modules/handsontable-pro/dist/handsontable.full.css'
import Handsontable from 'handsontable-pro'
<template>
<div>
<div id="hotTable" class="hotTable">
<HotTable :root="root" ref="testHot" :settings="hotSettings"></HotTable>
</div>
</div>
</template>
<script>
export default {
data: function () {
return {
root: 'test-hot',
hotSettings: {
data: [ //數據可以是二維數組,也可以是數組對象
['20080101', 10, 11, 12, 13,true],
['20090101', 20, 11, 14, 13,true],
['20010101', 30, 15, 12, 13,true],
['20010101', 32, 213, 21, 312,true],
['20010201', 32, 213, 21, 312,true],
['20010301', 32, 213, 21, 312,true],
['20010401', 32, 213, 21, 312,true],
['20010501', 32, 213, 21, 312,true],
['20010601', 32, 213, 21, 312,true]
],
startRows: 11,//行列范圍
startCols: 6,
minRows: 5, //最小行列
minCols: 5,
maxRows: 20, //最大行列
maxCols: 20,
rowHeaders: true,//行表頭,可以使布爾值(行序號),可以使字符串(左側行表頭相同顯示內容,可以解析html),也可以是數組(左側行表頭單獨顯示內容)。
colHeaders: [ '題目', 'A選項', 'B選項', 'C選項', 'D選項','答案'],//自定義列表頭or 布爾值
minSpareCols: 2, //列留白
minSpareRows: 2,//行留白
currentRowClassName: 'currentRow', //為選中行添加類名,可以更改樣式
currentColClassName: 'currentCol',//為選中列添加類名
autoWrapRow: true, //自動換行
contextMenu: { //自定義右鍵菜單,可漢化,默認布爾值
items: {
"row_above": {
name:'上方插入一行'
},
"row_below": {
name:'下方插入一行'
},
"col_left": {
name:'左方插入列'
},
"col_right": {
name:'右方插入列'
},
"hsep1": "---------", //提供分隔線
"remove_row": {
name: '刪除行',
},
"remove_col": {
name: '刪除列',
},
"make_read_only": {
name: '只讀',
},
{ type: 'numeric',
format: '$ 0,0.00'}, //指定的數據格式
{type: 'checkbox'}, //多選框
],
afterChange: function (changes, source) { //數據改變時觸發此方法
console.log(this.getData());
},
manualColumnFreeze: true, //手動固定列
manualColumnMove: true, //手動移動列
manualRowMove: true, //手動移動行
manualColumnResize: true,//手工更改列距
manualRowResize: true,//手動更改行距
comments: true, //添加注釋
cell: [
{row: 1, col: 1, comment: {value: 'this is test'}},
],
customBorders:[],//添加邊框
columnSorting: true,//排序
stretchH: 'all',//根據寬度橫向擴展,last:只擴展最后一列,none:默認不擴展
}
};
},
name: 'handsonTable',
components: {
HotTable
},
methods: {
saveData (){
var examData = this.$refs.testHot.table.getData(); //這里要注意,如果使用this.hotSettings.data 保存表格數據,拖拽完以后數據的順序將不會更新,因此使用 this.$refs.testHot.table.getData(); 來獲取數據,獲取的數據格式為二維數組。
console.log(examData );
}
}
}
</script>
- handsontable 插件事件api
1)afterChange (changes: Array, source: String):1個或多個單元格的值被>改變后調用
changes:是一個2維數組包含row,prop,oldVal,newVal4個屬性。
source:其值為一個字符串,值可以為:alter,empty,>populateFromArray,loadData,autofill,paste
2)beforeChange (changes: Array, source: String):開始改變單元格前被>調用
changes:是一個2維數組,包括[row,prop,oldVal,newVal]這4個公共屬>性列
source是被改變的資源的名稱
3)afterCellMetaReset ():重置單元格后調用
4)afterColumnMove (oldIndex: Number, newIndex: Number):列順序被>>移動后觸發
5)afterRowMove (oldIndex: Number, newIndex: Number):行被移動后調>用
6)afterRowResize (col: Number, size: Number):行高改變后調用
7)afterRemoveCol (index: Number, amount: Number):當一列或多列被>移動后調用
其中,index為開始移動的列的索引,amount為移動的列的總數量
8)afterRemoveRow (index: Number, amount: Number):當一行或多行被>移動后調用
其中,index為被移動的行的索引,amount為被移動的行的總數量
9)beforeRemoveCol (index: Number, amount: Number):一列或多列被>>移動前調用beforeRemoveRow (index: Number, amount: Number):一行或>多行被移動前被調用
10)afterColumnSort (column: Number, order: Boolean):列排序后調用
11)beforeColumnSort (column: Number, order: Boolean):列排序前被調用
order:值為true時為升序,false時為降序
12)afterCreateCol (index: Number, amount: Number):添加行后被調用
index:新列的索引
amount:新列的數目
13)afterCreateRow (index: Number, amount: Number):添加行后被調用
index:新行的索引
amount:新行的數目
14)afterGetCellMeta (row: Number, col: Number, cellProperties: >Object):獲取單元格的配置信息后被調用
15)beforeGetCellMeta (row: Number, col: Number, cellProperties: >Object):獲取單元格屬性前被調用
16)afterSetCellMeta(row: Number, col: Number, key: String, value: *):單>元格樣式被改變后調用
其中,cellProperties是一個單元格的渲染對象,key是改變樣式的方式,例>如合并單元格(merge),水平對齊(align)等。
17)afterGetColHeader (col: Number, TH: DOM Node):獲取列頭信息后被>調用,TH是行頭節點
18)afterGetColWidth (col: Number, response: Object):獲取列寬后被調用
19)afterColumnResize (col: Number, size: Number):列寬度被手動修改后調用
20)afterCopyLimit (s-electedRowsCount: Number, s-electedColsCount: Number,copyRowsLimit: Number, copyColsLimit: Number)
當 copyRowsLimit 或者 copyColumnsLimit實現時被調用
21)afterDestroy ():銷毀Handsontable實例后被調用
22)afterInit ():Handsontable實例被初始化后調用
23)beforeInit ():Handsontable實例被初始化前調用
24)beforeInitWalkontable():Walkontable實例被初始化前調用
25)afterLoadData ():新的數據被加載到數據資源后被調用afterOnCellCornerMouseDown (event):鼠標點擊單元格邊角后被調用
26)afterOnCellMouseDown (event: Object, coords: Object, TD: Object):>點擊單元格或行頭/列頭后被調用
注意:點擊行頭或列頭后索引的坐標為負數。例如點擊列頭單元格(0,0),則>調用后的坐標為(0,-1)。
27)afterOnCellMouseOver (event: Object, coords: Object, TD: Object):鼠標>停懸在單元格或行頭/列頭后調用
注意:點擊行頭或列頭后索引的坐標為負數。例如點擊行頭單元格(0,0),>則調用后的坐標為(0,-1)。
28)afterRender (isForced: Boolean):渲染表格后被調用
isForced:當其值為true表示是通過改變配置或數據引起的渲染,當值為>false時表示通過滾動或移動、選中引起的渲染
29)beforeRender (isForced: Boolean):渲染前被調用
30)afterRenderer (TD: Object, row: Number, col: Number, prop: String, >value: String, cellProperties: Object):手動渲染后調用
31)beforeChangeRender ():渲染被改變前調用
32)afterDes-elect ():當前單元格被取消選中時調用
33)afterS-election (r: Number, c: Number, r2: Number, c2: Number):當>一個或多個單元格被選中后調用
其中,r:選中的單元格起始行,r2:選中單元格的終止行
c:選中的單元格的起始列,c2:選中的單元格的終止列
34)afterS-electionByProp (r: Number, p: String, r2: Number, p2: String):>通過屬性名選中單元格后調用afterS-electionEnd (r: Number, c: Number, r2: >Number, c2: Number):選中單元格鼠標抬起后調用
afterS-electionEndByProp (r: Number, p: String, r2: Number, p2: String):通>過屬性選中單元格鼠標抬起后調用
35)afterUpdateSettings ():配置參數配修改后調用
36)afterValidate (isValid: Boolean, value: Mixed, row: Number, prop: >String,source: String)
當有驗證器的時候調用驗證器時被調用,驗證結果作為第一個參數。
37)beforeValidate (value: Mixed, row: Number, prop: String, source: >String):驗證器被調用前調用該事件
38)beforeAutofill (start: Object, end: Object, data: Array):開始自動填充前調動
start:是一個第一個填充的單元格對象,例如:{row:4,col:3}
end:是最后一個填充的單元格對象,例如:{row:7,col:5}
data:是一個2維數組
39)beforeKeyDown (event: Object):按鍵按下前被調用
40)beforeSet (var: Object):單個配置值被設置前調用
41)beforeSetRangeEnd(coords: Array):設置范圍結束前被調用coords:是范圍坐標
42)modifyCol(col: Number):列被修改時調用
43)modifyRow( row: Number):行被修改時調用
44)modifyColWidth (width: Number, col: Number):列寬被修改時調用
45)modifyRowHeight (height: Number, row: Number):行高被修改時調用