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