Handsontable - 案例(Vue)

简介: Handsontable - 案例(Vue)
<templatexmlns:v-clipboard="http://www.w3.org/1999/xhtml"><divclass="batch-import"><divclass="header"><divclass="flex-left"><el-buttonsize="mini"class="shade add"@click="handleFAQ"><iclass="el-icon-key"/>新手指南</el-button></div><divclass="flex-right"><el-buttonsize="mini"class="shade add"@click="importExcel" :disabled="importExcelDsiable"><iclass="el-icon-upload2"/>开始导入</el-button><el-buttonsize="mini"class="shade add"@click="beforeCheckExcel"><iclass="el-icon-document-checked"/>检查数据</el-button><el-buttonsize="mini"class="shade add"@click="cutExcelData"v-clipboard:copy="copyContent"v-clipboard:success="onCopy"v-clipboard:error="onError"><iclass="el-icon-files"/>整理数据</el-button><el-buttonsize="mini"class="shade add"id="copyExcel"><iclass="el-icon-document-copy"/>复制全部</el-button><!--<el-buttonsize="mini"class="shade add"@click="handleTest"><iclass="el-icon-document-checked"/>测试按钮</el-button>--><el-buttonsize="mini"class="shade add reset"@click="clearExcel"><iclass="el-icon-refresh"/>重置</el-button></div></div><divclass="shade body"v-loading="loading"><!--下面两层嵌套div必须加上,解决excel表头跑到外面去--><divclass="overf"><divclass="wrapper"><HotTableref="ht" :settings="hotSettings"licenseKey="9c56f-fc083-95630-36851-db045"></HotTable></div></div></div><!--对话框--><NumRangerref="numranger"@afterCheckExcel="afterCheckExcel"></NumRanger><FAQref="faq"op="excel_othermoney"></FAQ></div></template><script>import { HotTable } from'@handsontable/vue'import'handsontable/dist/handsontable.full.css'importfinanceApifrom'@/api/finance'import'handsontable/languages/zh-CN'importNumRangerfrom'@/components/tool/NumRanger'importFAQfrom'@/components/tool/FAQ'importimportBGfrom'@/api/importBG'importmenufrom'@/data/menu'importuserfrom'@/api/userBG'letothermoneytype_id2lbl= {}, othermoneytype_lbl2id= {}
letpaytype_id2lbl= {}, paytype_lbl2id= {}
letoperator_id2lbl= {}, operator_lbl2id= {}
letuser_id2lbl= {}, user_lbl2id= {}
letuser_id2phone= {}, user_phone2id= {}
letthat=null, custom= {}, arr= [], result= {}
exportdefault {
name: 'BatchImport',
components: {
HotTable,
NumRanger,
FAQ    },
data() {
return {
/* common */loading: false,
copyContent: "",
importExcelDsiable: true,
/* excel */sourceData: null,
jsonData: [],
colHeaders: ["导入结果", "项目名称", "关联用户", "用户姓名", "手机号", "项目类型", "项目数量", "收支类型", "订单日期", "订单时间", "项目原价", "签约金额", "支付金额", "支付方式", "付款日期", "付款时间", "经办人", "备注"],
columns: [
          { // -1 导入结果data: "result",
type: 'text',
readOnly: true          },
          { // 0 项目名称data: "othermoneyorderName",
type: 'text', // defvalidator (val, callback) {
if(that.util.isEmpty(val)) returncallback(false)
letpattern=/^.{1,100}$/// console.log(pattern.test(val))if(pattern.test(val)) returncallback(true)
returncallback(false)
            },
          },
          { // 1 关联用户data: "othermoneyorderUseridUserFk",
type: 'dropdown',
source: [],
validator: 'Vdropdown_Tnull'          },
          { // 2 用户姓名data: "othermoneyorderUsername",
type: 'text',
validator (val, callback) {
if(that.util.isEmpty(val)) returncallback(false)
letpattern=/^.{1,20}$/// console.log(pattern.test(val))if(pattern.test(val)) returncallback(true)
returncallback(false)
            },
          },
          { // 3 手机号data: "othermoneyorderPhone",
type: 'text',
validator (val, callback) {
if(that.util.isEmpty(val)) returncallback(true)
letpattern=/^([0-9]{0}|1[0-9]{10})$/// console.log(pattern.test(val))if(pattern.test(val)) returncallback(true)
returncallback(false)
            },
          },
          { // 4 项目类型data: "othermoneyorderOthermoneytypeidOthermoneytypeFk",
type: 'dropdown',
source: [],
validator: 'Vdropdown_Fnull'          },
          { // 5 项目数量data: "othermoneyorderNum",
type: 'text',
validator (val, callback) {
if(that.util.isEmpty(val)) returncallback(false)
letpattern=/^[1-9][0-9]{0,10}$/// console.log(pattern.test(val))if(pattern.test(val)) returncallback(true)
returncallback(false)
            },
          },
          { // 6 收支类型data: "othermoneyorderBudgettype",
type: 'dropdown',
source: ["收入", "支出"],
validator: "Vdropdown_Fnull"          },
          { // 7 订单日期data: "othermoneyorderTime_date",
type: 'date',
width: 130,
dateFormat: 'YYYY-MM-DD',
correctFormat: true          },
          { // 8 订单时间data: "othermoneyorderTime_time",
type: 'time',
timeFormat: 'HH:mm:ss',
correctFormat: true          },
          { // 9 项目原价data: "othermoneyorderOriginaltotalprice",
type: 'numeric',
numericFormat: {
pattern: '0.00',
            },
validator: 'VFnull'          },
          { // 10 签约金额data: "othermoneyorderFacttotalprice",
type: 'numeric',
numericFormat: {
pattern: '0.00',
            },
validator: 'VFnull'          },
          { // 11 支付金额data: "othermoneyorderpayMoney",
type: 'numeric',
numericFormat: {
pattern: '0.00',
            },
validator: 'VFnull'          },
          { // 12 支付方式data: "othermoneyorderpayPaytype",
type: 'dropdown',
source: ["现金", "支付宝", "微信", "网银", "其它"],
validator: 'Vdropdown_Fnull'          },
          { // 13 付款日期data: "othermoneyorderpayTime_date",
type: 'date',
width: 130,
dateFormat: 'YYYY-MM-DD',
correctFormat: true          },
          { // 14 付款时间data: "othermoneyorderpayTime_time",
type: 'time',
timeFormat: 'HH:mm:ss',
correctFormat: true          },
          { // 15 经办人data: "othermoneyorderUseroperatoridUserFk",
type: 'dropdown',
source: [],
validator: 'Vdropdown_Fnull'          },
          { // 16 备注data: "othermoneyorderRemark",
type: 'text',
validator (val, callback) {
if(that.util.isEmpty(val)) returncallback(true)
letpattern=/^.{0,200}$/// console.log(pattern.test(val))if(pattern.test(val)) returncallback(true)
returncallback(false)
            }
          }
        ],
hotSettings: {
readOnlyCellClassName: 'is-readOnly',
language: 'zh-CN', // 声明用中文的语言包// invalidCellClassName: 'htInvalid',// startCols: 10, // 初始行列数// startRows: 20,// minRows: 4, // 最小行// minCols: 3,maxRows: this.const.data().PAGE_SIZE_BIG_PLUS, // 最大行// 数据在这个里面,由数据填充表。当 data 为 null 时,startRows/startCols 生效,否则 data 有数据、[[]],都不会生效,而且不能直接为 []/{},会报错data: null,
minRows: 50,  // 最少行列// minCols: 30,// minSpareCols: 2, // 列留白// minSpareRows: this.const.data().PAGE_SIZE_BIG_PLUS, // 推介和 maxRows 一样minSpareRows: 50,
rowHeaders: true,
// persistentState: true, // 开启本地缓存// colHeaders: true,colHeaders: [], // 自定义列表头autoWrapRow: true, // 自动换行,默认:true;TAB在最后一列中按或向右箭头将移动到下一行的第一列fillHandle: true, // 单元格内容拖拽复制,可选值:true、false、vertical、horizontal;默认:true,垂直/水平都支持fixedColumnsLeft: 2, // 固定左边列数,从0开始为第1列fixedRowsTop: 0,
manualColumnFreeze: true, // 开启手动固定(取消)列manualColumnMove: false, // 关闭手动移动列manualRowMove: true,   // 开启手动移动行manualColumnResize: true, // 开启手工更改列距manualRowResize: true, // 开启手动更改行距comments: true, // 开启添加注释columnSorting: true, // 排序undoRedo: true, // 开启撤销copyPaste: true, // 开启剪切、复制filters: true, // 开启过滤,必须在开启dropdownMenu前提下才有用// columns: this.columns, // 设置每一列的数据类型和配置// columns: [],// dropdownMenu: true, // 开启默认筛选和常用操作dropdownMenu: {
items: {
"filter_by_condition": {
name: '主要筛选',
              },
"filter_operators": {
name: '动作筛选',
              },
"filter_by_condition2": {
name: '次要筛选',
              },
"filter_by_value": {
name: '值筛选',
              },
"filter_action_bar": {
name: '栏筛选',
              }
            }
          },
contextMenu: { // 自定义右键菜单items: {
"row_above": {
name:'向上插一行'              },
"row_below": {
name:'向下插一行'              },
"col_left": {
name:'向左插一列'              },
"col_right": {
name:'向右插一列'              },
"hsep1": "---------", // 分隔线"remove_row": {
name: '删除当前行',
              },
"remove_col": {
name: '删除当前列',
              },
"clear_column": {
name: '清空当前列',
              },
"hsep2": "---------", // 必须和上次的变量名不一样"undo": {
name: '撤销',
              },
"cut": {
name: '剪切',
              },
"copy": {
name: '复制',
              },
"alignment": {
name: '对齐',
              },
"hsep3": "---------",
"commentsAddEdit": { // 必须开启 comments: truename: '添加备注',
              },
"commentsRemove": { // 必须开启 comments: truename: '删除备注',
              },
"freeze_column": { // 必须开启 manualColumnFreeze: truename: '固定列',
              },
"unfreeze_column": { // 必须开启 manualColumnFreeze: truename: '取消固定列',
              }
            }
          },
afterChange (changes, source) {
console.log("changes: ", changes) // row, prop, oldVal, newValconsole.log("source: ", source) // opif(that) { // 第一次加载没必要执行,避免报错that.importExcelDsiable=truethat.sourceData=this.getSourceData()
            }
if(source&& ("CopyPaste.paste"==source||"edit"==source)) {
for(letitemofchanges) {
if(item[1] =="othermoneyorderUseridUserFk") {
letnewName=item[3]
letnewPhone=user_id2phone[user_lbl2id[[newName]]]
this.setDataAtRowProp(item[0], 'othermoneyorderUsername', newName, that.sourceData)
this.setDataAtRowProp(item[0], 'othermoneyorderPhone', newPhone, that.sourceData)
                }
elseif (item[1] =="othermoneyorderOriginaltotalprice"||item[1] =="othermoneyorderFacttotalprice"||item[1] =="othermoneyorderpayMoney") {
letnewName=parseFloat(item[3])
if(newName<0) {
newName*=-1                  }
this.setDataAtRowProp(item[0], item[1], newName, that.sourceData)
                }
              }
            }
          }
        }
      }
    },
methods: {
handleFAQ() {
this.$refs.faq.$data.dialogFAQVisible=true      },
getExcelSourceData() {
letarr=this.$refs.ht.hotInstance.getSourceData(), obj=nullthis.sourceData= []
for(letitemofarr) {
obj= {
result: item['result'],
othermoneyorderName: item['othermoneyorderName'],
othermoneyorderUseridUserFk: item['othermoneyorderUseridUserFk'],
othermoneyorderUsername: item['othermoneyorderUsername'],
othermoneyorderPhone: item['othermoneyorderPhone'],
othermoneyorderOthermoneytypeidOthermoneytypeFk: item['othermoneyorderOthermoneytypeidOthermoneytypeFk'],
othermoneyorderNum: item['othermoneyorderNum'],
othermoneyorderBudgettype: item['othermoneyorderBudgettype'],
othermoneyorderTime_date: item['othermoneyorderTime_date'],
othermoneyorderTime_time: item['othermoneyorderTime_time'],
othermoneyorderOriginaltotalprice: item['othermoneyorderOriginaltotalprice'],
othermoneyorderFacttotalprice: item['othermoneyorderFacttotalprice'],
othermoneyorderpayMoney: item['othermoneyorderpayMoney'],
othermoneyorderpayPaytype: item['othermoneyorderpayPaytype'],
othermoneyorderpayTime_date: item['othermoneyorderpayTime_date'],
othermoneyorderpayTime_time: item['othermoneyorderpayTime_time'],
othermoneyorderUseroperatoridUserFk: item['othermoneyorderUseroperatoridUserFk'],
othermoneyorderRemark: item['othermoneyorderRemark']
          }
/*for(let jtem in custom) {obj[jtem] = item[jtem]}*/this.sourceData.push(obj)
        }
      },
onCopy(e) {
// console.log(e)      },
onError(e) {
// console.log(e)      },
cutExcelData() {
this.loading=truethis.util.blur()
this.getExcelSourceData()
letobj= {}, str='', idx=0lettmpSourceData=this.util.copy(this.sourceData)
letsucc=0for(letitemintmpSourceData) {
if(tmpSourceData[item].result=='导入成功') {
succ++obj=tmpSourceData[item]
str+=obj['othermoneyorderName'] +'\t'str+=obj['othermoneyorderUseridUserFk'] +'\t'str+=obj['othermoneyorderUsername'] +'\t'str+=obj['othermoneyorderPhone'] +'\t'str+=obj['othermoneyorderOthermoneytypeidOthermoneytypeFk'] +'\t'str+=obj['othermoneyorderNum'] +'\t'str+=obj['othermoneyorderBudgettype'] +'\t'str+=obj['othermoneyorderTime_date'] +'\t'str+=obj['othermoneyorderTime_time'] +'\t'str+=obj['othermoneyorderOriginaltotalprice'] +'\t'str+=obj['othermoneyorderFacttotalprice'] +'\t'str+=obj['othermoneyorderpayMoney'] +'\t'str+=obj['othermoneyorderpayPaytype'] +'\t'str+=obj['othermoneyorderpayTime_date'] +'\t'str+=obj['othermoneyorderpayTime_time'] +'\t'str+=obj['othermoneyorderUseroperatoridUserFk'] +'\t'str+=obj['othermoneyorderRemark']
// console.log(Object.keys(custom).length)letlen=Object.keys(custom).length, i=0for(letjtemincustom) {
if(i==0) str+='\t'if(i==len-1) {
str+=obj[jtem] +'\n'              }
else {
str+=obj[jtem] +'\t'              }
i++            }
if(i==0) str+='\n'// console.log("idx: ", idx)this.sourceData.splice(idx, 1)
          }
else {
idx++          }
// console.log(this.sourceData)        }
this.copyContent=strthis.$refs.ht.hotInstance.updateSettings({
data: this.sourceData        })
if(succ>0) {
this.$message({type: 'success', message: '已成功剪切 '+succ+' 条记录,请粘贴到本地 Excel 保存,并处理剩余错误记录'})
        }
elseif(succ==0) {
this.$message({type: 'warning', message: '暂无导入成功记录,请处理错误记录或新数据', duration: 0, showClose: true})
        }
this.loading=false      },
clearExcel() {
this.util.blur()
this.$confirm('此操作将永久清空该 Excel,是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'        }).then(() => {
this.$refs.ht.hotInstance.loadData(null)
        }).catch(() => {
        })
      },
beforeCheckExcel() {
this.util.blur()
this.$refs.numranger.$data.op="beforeCheckExcel"this.$refs.numranger.$data.dialogNumRangerVisible=true      },
afterCheckExcel(val) {
this.loading=true// console.log("class_afterCheckExcel: ", val)arr= []
if(val.from!=-1) {
for(leti=val.from-1; i<val.to; i++) {
arr.push(i)
          }
        }
else {
letdata=this.$refs.ht.hotInstance.getSourceData()
letlen=this.$refs.ht.hotInstance.countRows()
// console.log(data)for(leti=0; i<len; i++) {
letname=data[i]["othermoneyorderName"]
if(!this.util.isEmpty(name)) {
arr.push(i)
            }
          }
        }
// console.log(arr)this.$refs.ht.hotInstance.validateRows(arr, (valid) => {
// console.log("validateRows", valid)if (valid) {
this.$message({type: 'success', message: "检查通过,无格式异常数据"})
this.importExcelDsiable=false          }
else {
this.$message({type: 'error', message: "检查失败,请注意格式,修复“红色区域”数据", duration: 0, showClose: true})
this.importExcelDsiable=true          }
this.loading=false        })
      },
handleSourceData() {
this.sourceData=this.$refs.ht.hotInstance.getSourceData()
letdata= [], rows= []
for(letitemofarr) {
data.push(this.sourceData[item])
rows.push(item)
        }
// console.log(this.sourceData)// console.log(data)letjsonObj=nullletorderDate=null, orderTime=null, orderDatetime=nullletpayDate=null, payTime=null, payDatetime=nullthis.jsonData= []
letrowIdx=0for(letitemofdata) {
orderDate=this.util.getDateOrNow(item['othermoneyorderTime_date'])
orderTime=this.util.getTimeOrNow(item['othermoneyorderTime_time'])
orderDatetime=this.util.getDatetimeOrNow(orderDate, orderTime)
payDate=this.util.getDateOrNow(item['othermoneyorderpayTime_date'])
payTime=this.util.getTimeOrNow(item['othermoneyorderpayTime_time'])
payDatetime=this.util.getDatetimeOrNow(payDate, payTime)
// console.log('row: ', rows[rowIdx])// console.log('row val: ', orderDate)this.$refs.ht.hotInstance.setDataAtRowProp(rows[rowIdx], 'othermoneyorderTime_date', orderDate, this.sourceData)
this.$refs.ht.hotInstance.setDataAtRowProp(rows[rowIdx], 'othermoneyorderTime_time', orderTime, this.sourceData)
this.$refs.ht.hotInstance.setDataAtRowProp(rows[rowIdx], 'othermoneyorderpayTime_date', payDate, this.sourceData)
this.$refs.ht.hotInstance.setDataAtRowProp(rows[rowIdx], 'othermoneyorderpayTime_time', payTime, this.sourceData)
jsonObj= {
othermoneyorderName: item['othermoneyorderName'],
othermoneyorderUseridUserFk: user_lbl2id[item['othermoneyorderUseridUserFk']],
othermoneyorderUsername: item['othermoneyorderUsername'],
othermoneyorderPhone: item['othermoneyorderPhone'],
othermoneyorderOthermoneytypeidOthermoneytypeFk: othermoneytype_lbl2id[item['othermoneyorderOthermoneytypeidOthermoneytypeFk']],
othermoneyorderNum: item['othermoneyorderNum'],
othermoneyorderBudgettype: item['othermoneyorderBudgettype'] =='收入'?'0' : '1',
othermoneyorderTime: orderDatetime,
othermoneyorderOriginaltotalprice: item['othermoneyorderOriginaltotalprice'],
othermoneyorderFacttotalprice: item['othermoneyorderFacttotalprice'],
othermoneyorderpayMoney: item['othermoneyorderpayMoney'],
othermoneyorderpayPaytype: paytype_lbl2id[item['othermoneyorderpayPaytype']],
othermoneyorderpayTime: payDatetime,
othermoneyorderUseroperatoridUserFk: operator_lbl2id[item['othermoneyorderUseroperatoridUserFk']],
othermoneyorderRemark: item['othermoneyorderRemark']
          }
for(letjtemincustom) {
jsonObj[jtem] =item[jtem]
          }
this.jsonData.push(jsonObj)
rowIdx++        }
// console.log('jsonData: ', this.jsonData)      },
asyncimportExcel() {
this.loading=truethis.util.blur()
this.handleSourceData() // 获取最新数据if(this.jsonData.length==0) { // 判空处理this.$message({type: 'warning', message: '导入失败,数据为空', duration: 0, showClose:true})
this.loading=falsethis.importExcelDsiable=truereturnfalse        }
awaitimportBG.importOtherMoneyOrder({
otherMoneyOrderInfoList: this.jsonData        })
        .then(res=> {
console.log(res)
if (res.success) {
this.$message({type: 'success', message: res.msg})
          }
elseif (res.error) {
this.$message({type: 'warning', message: res.msg})
          }
else {
this.$message({type: 'error', message: '导入失败,原因未知'})
          }
this.sourceData=this.$refs.ht.hotInstance.getSourceData()
letrs=res.data, msg=''result= {}
for(letitemofrs) {
result[''+item.errIndex] =item          }
for(letitemofarr) {
if(this.util.isEmpty(result[''+item])) {
msg='导入成功'            }
else {
msg=result[''+item].errMsg            }
this.$refs.ht.hotInstance.setDataAtRowProp(item, 'result', msg, this.sourceData)
          }
        })
        .catch(function (error) {
console.log(error)
this.$message({type: 'error', message: '系统错误'})
        })
this.loading=false      },
asyncinitExcel() {
this.loading=truethat=this// 为下面闭包做准备awaitfinanceApi.getOthermoneytypeListByOrgId({
needDel: 'needDel'// 删除的不展示,只是为了修复显示ID的BUG        })
          .then(res=> {
console.log(res)
if(res.success){
letdata=res.data, src= []
for(letitemofdata) {
src.push(item.othermoneytypeName)
othermoneytype_id2lbl[item.othermoneytypeId] =item.othermoneytypeNameothermoneytype_lbl2id[item.othermoneytypeName] =item.othermoneytypeId              }
this.columns[5].source=src            }
elseif(res.nullwarn) {
            }
else {
this.$message({type: 'error', message: res.msg})
            }
          })
          .catch(function (error) {
console.log(error)
this.$message({type: 'error', message: '系统错误'})
          })
// 关联用户awaituser.getUserCheckList({})
          .then(res=> {
console.log(res)
if(res.success){
letdata=res.data.data, src= []
for(letitemofdata) {
src.push(item.userName)
user_id2lbl[item.userId] =item.userNameuser_lbl2id[item.userName] =item.userIduser_id2phone[item.userId] =item.userMobileuser_phone2id[item.userMobile] =item.userId              }
this.columns[2].source=src            }
elseif(res.nullwarn) {
            }
else {
this.$message({type: 'error', message: res.msg})
            }
          })
          .catch(function (error) {
console.log(error)
this.$message({type: 'error', message: '系统错误'})
          })
// 经办人awaituser.getTeacherCheckList({})
          .then(res=> {
// console.log(res)if(res.success){
letdata=res.data.data, src= []
for(letitemofdata) {
src.push(item.userName)
operator_id2lbl[item.userId] =item.userNameoperator_lbl2id[item.userName] =item.userId              }
this.columns[16].source=src            }
elseif(res.nullwarn) {
            }
else {
this.$message({type: 'error', message: res.msg})
            }
          })
          .catch(function (error) {
console.log(error)
this.$message({type: 'error', message: '系统错误'})
          })
/*await eduApi.getCustomparam({ userType: 1 }).then(res => {// console.log('custom', res)if(res.success){let arr = res.datafor(let item of arr) {this.colHeaders.push(item.customparamName)this.columns.push({data: item.customparamId,type: 'text',validator: /^.{0,200}$/})custom[item.customparamId] = item.customparamName}}else if(res.nullwarn) {}else {this.$message({type: 'error', message: res.msg})}}).catch(function (error) {console.log(error)this.$message({type: 'error', message: '系统错误'})})*/this.hotSettings.startCols=this.colHeaders.lengththis.hotSettings.colHeaders=this.colHeadersthis.hotSettings.columns=this.columns// 初始化必要信息paytype_id2lbl['0'] ='现金'; paytype_lbl2id['现金'] ='0'paytype_id2lbl['1'] ='支付宝'; paytype_lbl2id['支付宝'] ='1'paytype_id2lbl['2'] ='微信'; paytype_lbl2id['微信'] ='2'paytype_id2lbl['3'] ='网银'; paytype_lbl2id['网银'] ='3'paytype_id2lbl['4'] ='其它'; paytype_lbl2id['其它'] ='4'this.loading=false      },
initEvent () {
// 复制全部按钮letcopyBtn=document.getElementById("copyExcel")
this.Handsontable.dom.addEvent(copyBtn, 'click', () => {
this.util.blur()
letrow1=-1, col1=-1, row2=-1, col2=-1that.$confirm('是否复制“导入结果”该列?', '提示', {
confirmButtonText: '是',
cancelButtonText: '否',
type: 'warning'          }).then(() => {
row1=col1=0          }).catch(() => {
row1=0col1=1          }).finally(() => {
row2=that.$refs.ht.hotInstance.countRows() -1col2=that.$refs.ht.hotInstance.countCols() -1// console.log(row1, col1, row2, col2)that.$refs.ht.hotInstance.selectCells([[row1,col1,row2,col2]])
document.execCommand('copy')
that.$message({type: 'success', message: '复制成功,请尽快粘贴到本地 Excel 进行保存'})
          })
        })
      },
handleTest() {
console.log(this.$refs.ht.hotInstance.countRows())
console.log(this.$refs.ht.hotInstance.countCols())
      }
    },
mounted () {
if(this.$route.fullPath===menu.root.child.finance.child.income.child.batchAdd.fullPath||this.$route.fullPath===menu.root.child.finance.child.spending.child.batchAdd.fullPath) {
this.initExcel()
this.initEvent()
      }
    }
  }
</script><stylelang="stylus"scoped>@import'~@/assets/styles/varibles.styl'>>> .is-readOnlyfont-weight: boldcolor: redfont-size: 14px>>> .handsontable    .changeTypebackground: transparentborder: nonecolor: #616161theadtr:first-childthborder-top: noneth:first-childborder-left: nonethcolor: #616161font-weight: normalbackground-color: #fff  .batch-importmargin-bottom: 30px    .headerdisplay: flexflex-wrap: nowrapflex-direction: rowjustify-content: space-betweenpadding: 0010px      .addmargin-right: 5pxmargin-left: 0border: 0pxheight: 28pxletter-spacing: 1px      .resetmargin-right: 0    .bodyheight: 1000px      .overfwidth: 100%height: 100%overflow: hidden        .wrapperwidth: 100%height: 100%overflow: auto</style>
目录
相关文章
|
容器
Handsontable - 配置属性(下)
Handsontable - 配置属性(下)
1292 0
Handsontable - 配置属性(下)
|
存储 Java API
Android 浅度解析:mk预置AAR、SO文件、APP包和签名
Android 浅度解析:mk预置AAR、SO文件、APP包和签名
1652 0
|
数据格式
使用小技巧实现el-table组件的合并行功能,ElementUI和ElementPlus都适用
本文介绍了在ElementUI和ElementPlus中使用`el-table`组件实现合并行功能的技巧,包括多列合并和单列合并的方法,并提供了相应的示例代码和运行效果。
8784 1
使用小技巧实现el-table组件的合并行功能,ElementUI和ElementPlus都适用
|
10月前
|
Oracle Cloud Native 关系型数据库
Oracle Linux 9.5 正式版发布 - Oracle 提供支持 RHEL 兼容发行版
Oracle Linux 9.5 正式版发布 - Oracle 提供支持 RHEL 兼容发行版
194 10
Oracle Linux 9.5 正式版发布 - Oracle 提供支持 RHEL 兼容发行版
|
10月前
|
机器学习/深度学习 数据采集 运维
使用 Python 实现深度学习模型:智能食品生产线优化
使用 Python 实现深度学习模型:智能食品生产线优化
177 13
|
JavaScript
vue + d3.js(v6) 绘制【树状图/思维导图】可折叠/展开,可点击跳转,可带标签
vue + d3.js(v6) 绘制【树状图/思维导图】可折叠/展开,可点击跳转,可带标签
1181 1
|
算法 数据处理 数据库
生物学经典Blast序列比对算法原理,如何在R语言和Python中实现序列的比对分析?
生物学经典Blast序列比对算法原理,如何在R语言和Python中实现序列的比对分析?
|
Web App开发 缓存 JavaScript
如何排查 Electron V8 引发的内存 OOM 问题(中)
如何排查 Electron V8 引发的内存 OOM 问题(中)
1683 0
|
移动开发 前端开发
ruoyi-nbcio-plus基于vue3的flowable为了适配文件上传改造VForm3的代码记录
ruoyi-nbcio-plus基于vue3的flowable为了适配文件上传改造VForm3的代码记录
334 1
EMQ
|
消息中间件 物联网 网络安全
2023 年最适用于工业物联网领域的三款开源 MQTT Broker
本文对比分析了 2023 年工业物联网领域最优秀的三款 MQTT Broker,介绍了它们的优点、缺点和应用场景。
EMQ
1685 0
2023 年最适用于工业物联网领域的三款开源 MQTT Broker