import React, { Component } from 'react'; import HotTable from 'react-handsontable'; import HandsontablePro from 'handsontable-pro'; // 这个对象下有handsontable的下不少方法 class ExampleHandsontable extends Component { constructor(...reset) { super(...reset); this.state = { settings: {}, // ? 不要引用这个,不生效的,不懂为何 }; this.settings = { data: this.objectData, // data: HandsontablePro.helper.createSpreadsheetData(100, 50), // data: this.getDate(), width: 800, // 宽 height: 350, // 高 // 标题操做 rowHeaders: ['ID', 'Name', 'Address'], // 每列的标题,若是不够,则用大写字母补充 colHeaders: ['ID', 'Name', 'Address', 'Another long label'], // 每列的标题,若是不够,则用大写字母补充 rowHeaders: false, // 生效 colHeader: true, // 显示顶标题, 经测试。并不生效 rowHeader: true, // 显示左标题, 经测试。并不生效 colWidths: 100, // 单元格宽 rowHeights: 23, // 单元格高 colWidths: [45, 100, 160, 60, 80, 80, 80], // 能够批量设置 rowHeights: [50, 40, 100], // 批量设置 colWidths: (col) => { console.log(`colWidths的回调:第几列${col}`); if (col === 2) return 100 }, nestedHeaders: [ ['A', { label: 'B', colspan: 8 }, 'C'], ['D', { label: 'E', colspan: 4 }, { label: 'F', colspan: 4 }, 'G'], ['H', { label: 'I', colspan: 2 }, { label: 'J', colspan: 2 }, { label: 'K', colspan: 2 }, { label: 'L', colspan: 2 }, 'M'], ['N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W'] ], collapsibleColumns: [ { row: -4, col: 1, collapsible: true }, { row: -3, col: 1, collapsible: true }, { row: -2, col: 1, collapsible: true }, { row: -2, col: 3, collapsible: true } ], // ! 行操做 fixedRowsTop: 2, // 固定的行 fixedColumnsLeft: 3, // 固定的列 fixedRowsBottom: 2, // 固定底行 stretchH: "all", // 拉伸行,可选值为,all 拉伸全部,none 不拉伸,last 拉伸最后一行 manualColumnResize: true, // 列拉伸,调整大小 manualRowResize: true, // 行拉伸,调整大小 manualColumnMove: true, // 拖动交换列 manualRowMove: true, // 拖动交换行 hiddenRows: { // 隐藏行 rows: [0, 1], indicators: false, // 官网说必须为true 才会隐藏,然而实际上并非 copyPasteEnabled: false // 为false 时跳过复制 }, hiddenColumns: { // 隐藏列 columns: [3, 5, 9], indicators: true }, headerTooltips: true, // 提示 headerTooltips: { // 提示 rows: true, columns: true, onlyTrimmed: true }, startRows: 5, startCols: 5, minSpareRows: 1, // 下方老是空一行 minSpareCols: 1, // 右方老是空一行 stretchH: 'all', // 行相关事件 beforeColumnMove: this.beforeColumnMove, // 列被移动以前触发 afterColumnMove: this.afterColumnMove, // 列顺序被移动后触发 afterRowMove: this.afterRowMove, // 行被移动后触发 beforeRowResize: this.beforeRowResize, // 行拉伸以前触发 afterRowResize: this.afterRowResize, // 行拉伸后触发 beforeColumnResize: this.beforeColumnResize, // 列拉伸以前触发 afterColumnResize: this.afterColumnResize, // 列拉伸以后触发 beforeRemoveCol: this.beforeRemoveCol, // 列被移动前触发 beforeRemoveRow: this.beforeRemoveRow, // 行被移动前被触发 afterRemoveCol: this.afterRemoveCol, // 列被移动后触发 afterRemoveRow: this.afterRemoveRow, // 行被移动后触发 beforeCut: this.beforeCut, // 剪切以前触发 afterCut: this.afterCut, // 剪切以后触发 beforeCopy: this.beforeCopy, // 复制以前触发 afterCopy: this.afterCopy, // 复制以后触发 beforePaste: this.beforePaste, // 粘贴以前触发 afterPaste: this.afterPaste, // 粘贴以后触发 afterCreateCol: this.afterCreateCol, // 插入列后触发,向上和向下插入都是这个参数1是新行索引,参数2 是旧行索引, afterCreateRow: this.afterCreateRow, // 插入行后触发,向上和向下插入都是这个参数1是新行索引,参数2 是旧行索引, afterDestroy: this.afterDestroy, // 销毁Handsontable实例后被调用 afterInit: this.afterInit, // Handsontable实例被初始化后调用 beforeInit: this.beforeInit, // Handsontable实例被初始化前调用 beforeRender: this.beforeRender, // 渲染前触发 afterRender: this.afterRende.bind(this, isForced), // 表格渲染后触发 isForced:当其值为true表示是经过改变配置或数据引发的渲染,当值为false时表示经过滚动或移动、选中引发的渲染 afterRenderer: this.afterRenderer, // 手动调用渲染后触发 afterOnCellCornerMouseDown: this.afterOnCellCornerMouseDown, // 鼠标点击单元格边角后被调用 afterOnCellCornerDblClick: this.afterOnCellCornerDblClick, // 鼠标双击击单元格边角后被调用 afterOnCellMouseDown: this.afterOnCellMouseDown, // 点击单元格后触发 afterOnCellMouseOver: this.afterOnCellMouseOver, // 移入单元格触发 afterDocumentKeyDown: this.afterDocumentKeyDown, // 输入单元格键盘按下以后触发 beforeKeyDown: this.beforeKeyDown, // 输入单元格键盘按下以前触发 afterContextMenuShow: this.afterContextMenuShow, // 点击右键,显示右键菜单以后触发 afterContextMenuHide: this.afterContextMenuHide, // 右键菜单隐藏后触发 afterCellMetaReset: this.afterCellMetaReset, // 重置单元格后触发 beforeChange: this.beforeChange, // 单元格改变前触发 afterChange: this.afterChange, // 单元格改变后触发 afterDeselect: this.afterDeselect, // 当前单元格被取消时触发 afterSelection: this.afterSelection.bind(this, a, b, c, d), // 选中单元格后触发 // a 选中的单元格起始行 b 选中的单元格的起始列 c 选中单元格的终止行 d 选中的单元格的终止列 afterSelectionEnd: this.afterSelectionEnd, // 选中单元格鼠标抬起后调用 afterSelectionByProp: this.afterSelectionByProp, // 经过属性名选中单元格后调用 afterSelectionEndByProp: this.afterSelectionEndByProp, // 经过属性选中单元格鼠标抬起后调用 beforeAutofill: this.beforeAutofill, // 开始自动填充前调动 dataSchema: { id: null, name: { first: null, last: null }, address: null }, // 数据若是开始为空,那么根据这个数据结构来造数据 afterChange: (change, source) => { console.log("afterChange:数据改变, change 是所改变单元格的属性,第一个是列的索引,第二个是数据的键,第三个是以前的值,最后一个是值", change, source) }, columns: [ // 用某一列覆盖某一列 此时 minSpareCols 不生效 { data: 0 }, //0 用第一列复制第一列 { data: 1 }, //1 用第2列复制第2列 { data: 2 }, //2 用第3列复制第3列 { data: 3 }, //3 用第4列复制第4列 { data: 4 }, //4 用第5列复制第5列 { data: 4 }, //5 用第5列复制第6列 { data: 4 }, //5 用第5列复制第6列 { data: 4 }, //5 用第5列复制第6列 ], columns: function (column) { // column 为当前列的索引 var columnMeta = {}; if (column === 0) { columnMeta.data = 'id'; } else if (column === 1) { columnMeta.data = 'name.first'; } else if (column === 2) { columnMeta.data = 'name.last'; } else if (column === 3) { columnMeta.data = 'address'; } else { columnMeta = null; } return columnMeta; }, columns: [ { data: "email", validator: this.emailValidator, allowInvalid: true, // 是否启用验证 }, ], persistentState: true, // 本地数据保存 readOnly: true, // 禁用,不可编辑 cell: [ // 对单元格的一些操做 // { row: 0, col: 1, readOnly: true }, // 第一行,第二列的单元格禁用 ], cells: (row, col, prop) => { console.log("cells:") console.log(row, col, prop); // 行 , 列 , 键 return }, // ! 下拉式菜单 dropdownMenu: true, // 下拉式菜单 dropdownMenu: ['remove_col', '---------', 'make_read_only', '---------', 'alignment'], comments: true, // 添加注释 // 自定义右键菜单 contextMenu: true, contextMenu: ['row_above', 'row_below', 'remove_row'], contextMenu: { callback: function (key, options) { console.log(key); console.log(options); if (key === 'about') { setTimeout(function () { // timeout is used to make sure the menu collapsed before alert is shown // alert("This is a context menu with default and custom options mixed"); }, 100); } }, items: { "row_above": { disabled: function () { // if first row, disable this option return true; } }, "row_below": {}, "hsep1": "---------", "remove_row": { name: 'Remove this row, ok?', disabled: function () { // if first row, disable this option return true } }, "hsep2": "---------", "about": { name: 'About this menu' } } }, beforeCopy: () => { }, beforeCut: () => { }, beforePaste: () => { }, afterCopy: function (changes) { // this.clipboardCache = sheetclip.stringify(changes); // changes : ["A5"] // var sheetclip = new SheetClip(); console.log(this); // console.log("afterCopy", sheetclip.stringify(changes)); console.log(changes); this.state.clipboardCache = ""; }, afterCut: function (changes) { this.clipboardCache = sheetclip.stringify(changes); }, afterPaste: function (changes) { // we want to be sure that our cache is up to date, even if someone pastes data from another source than our tables. this.clipboardCache = sheetclip.stringify(changes); }, currentRowClassName: 'currentRow', // 突出显示行 currentColClassName: 'currentCol', // 突出显示列 copyPaste: true, // 容许粘贴 mergeCells: true, // 合并单元格 或者提早合并 mergeCells: [{row: 1, col: 1, rowspan: 2, colspan: 2}] contextMenu: { callback: function (key, options) { }, items: { "row_above": { name: "向上插入一行" }, "row_below": { name: "向下插入一行" }, "remove_row": { name: "删除一行" }, "remove_col": { name: "删除一列", disabled: () => { } }, "col_left": { name: "向左添加一列" }, "col_right": { name: "向右添加一列" }, "hsep1": "---------", "hsep2": "---------", "hsep3": "---------", "undo": { name: "撤销" }, "redo": { name: "恢复" }, "copy": { name: "复制" }, "cut": { name: "剪切" }, "commentsAddEdit": { name: "添加注释" }, "commentsRemove": { name: "删除注释" }, "make_read_only": { name: "只读" }, "alignment": { name: "对齐" }, "paste": { name: '粘贴', // disabled: function () { // return clipboardCache.length === 0; // }, callback: function () { // var plugin = this.getPlugin('copyPaste'); // this.listen(); // plugin.paste(clipboardCache); var plugin = this.getPlugin('copyPaste'); this.listen(); plugin.paste(11); // console.log(this); console.log("paste回调") console.log(this) } } }, }, customBorders: [ { range: { from: { row: 1, col: 1 }, to: { row: 3, col: 4 } }, top: { width: 2, color: '#5292F7' }, left: { width: 2, color: 'orange' }, bottom: { width: 2, color: 'red' }, right: { width: 2, color: 'magenta' } }, { row: 2, col: 2, left: { width: 2, color: 'pink' }, right: { width: 1, color: 'green' } }], // sortIndicator: true columnSorting: true, // 排序功能 columns: [ { data: 'car' // 普通的字符串 // 1nd column is simple text, no special options here }, { type: 'numeric', // 数字 132132 }, { type: 'numeric', format: '格式化 0,0.00' // 格式化操做 }, { data: 'year', // 年 2017年 type: 'numeric' }, { data: 'price_usd', // $ 美圆格式化 type: 'numeric', format: '$0,0.00', language: 'en-US' // this is the default locale, set up for USD }, { data: 'price_eur', // 欧元 格式化 type: 'numeric', format: '0,0.00 $', language: 'de-DE' // i18n: use this for EUR (German) // more locales available on http://numbrojs.com/languages.html }, { type: 'checkbox', // 复选框 data: 'available' }, { editor: 'select', // 向下选择框 selectOptions: ['Kia', 'Nissan', 'Toyota', 'Honda'] }, { type: 'dropdown', // 向下列表 source: ['yellow', 'red', 'orange', 'green', 'blue', 'gray', 'black', 'white'] }, { type: 'autocomplete', // 自动完成 source: ['yellow', 'red', 'orange and another color', 'green', 'blue', 'gray', 'black', 'white', 'purple', 'lime', 'olive', 'cyan'], strict: false, trimDropdown: false }, { type: 'time', // 时间 timeFormat: 'h:mm:ss a', correctFormat: true // 让不正确的也变成正确 为false时,填写错误会样式会变红 }, { data: 'password', type: 'password' }, { type: 'date', dateFormat: 'MM/DD/YYYY', correctFormat: true, defaultDate: '01/01/1900', // datePicker additional options (see https://github.com/dbushell/Pikaday#configuration) datePickerConfig: { // First day of the week (0: Sunday, 1: Monday, etc) firstDay: 0, showWeekNumber: true, numberOfMonths: 3, disableDayFn: function (date) { // Disable Sunday and Saturday return date.getDay() === 0 || date.getDay() === 6; } } } ] } } rander() { return ( <HotTable root="hot" licenseKey={"00000-00000-00000-00000-00000"} settings={this.settings} /> ) } }
待续。。。html