<template xmlns:v-clipboard="http://www.w3.org/1999/xhtml">
<div class="batch-import">
<div class="header">
<div class="flex-left">
<el-button size="mini" class="shade add" @click="handleFAQ">
<i class="el-icon-key"/>
新手指南
</el-button>
</div>
<div class="flex-right">
<el-button size="mini" class="shade add" @click="importExcel" :disabled="importExcelDsiable">
<i class="el-icon-upload2"/>
开始导入
</el-button>
<el-button size="mini" class="shade add" @click="beforeCheckExcel">
<i class="el-icon-document-checked"/>
检查数据
</el-button>
<el-button size="mini" class="shade add" @click="cutExcelData"
v-clipboard:copy="copyContent"
v-clipboard:success="onCopy"
v-clipboard:error="onError">
<i class="el-icon-files"/>
整理数据
</el-button>
<el-button size="mini" class="shade add" id="copyExcel">
<i class="el-icon-document-copy"/>
复制全部
</el-button>
<!--<el-button size="mini" class="shade add" @click="handleTest">
<i class="el-icon-document-checked"/>
测试按钮
</el-button>-->
<el-button size="mini" class="shade add reset" @click="clearExcel">
<i class="el-icon-refresh"/>
重置
</el-button>
</div>
</div>
<div class="shade body" v-loading="loading">
<!-- 下面两层嵌套div必须加上,解决excel表头跑到外面去 -->
<div class="overf">
<div class="wrapper">
<HotTable ref="ht" :settings="hotSettings" licenseKey="9c56f-fc083-95630-36851-db045"></HotTable>
</div>
</div>
</div>
<!-- 对话框 -->
<NumRanger ref="numranger" @afterCheckExcel="afterCheckExcel"></NumRanger>
<FAQ ref="faq" op="excel_othermoney"></FAQ>
</div>
</template>
<script>
import { HotTable } from '@handsontable/vue'
import 'handsontable/dist/handsontable.full.css'
import financeApi from '@/api/finance'
import 'handsontable/languages/zh-CN'
import NumRanger from '@/components/tool/NumRanger'
import FAQ from '@/components/tool/FAQ'
import importBG from '@/api/importBG'
import menu from '@/data/menu'
import user from '@/api/userBG'
let othermoneytype_id2lbl = {}, othermoneytype_lbl2id = {}
let paytype_id2lbl = {}, paytype_lbl2id = {}
let operator_id2lbl = {}, operator_lbl2id = {}
let user_id2lbl = {}, user_lbl2id = {}
let user_id2phone = {}, user_phone2id = {}
let that = null, custom = {}, arr = [], result = {}
export default {
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', // def
validator (val, callback) {
if(that.util.isEmpty(val)) return callback(false)
let pattern = /^.{1,100}$/
// console.log(pattern.test(val))
if(pattern.test(val)) return callback(true)
return callback(false)
},
},
{ // 1 关联用户
data: "othermoneyorderUseridUserFk",
type: 'dropdown',
source: [],
validator: 'Vdropdown_Tnull'
},
{ // 2 用户姓名
data: "othermoneyorderUsername",
type: 'text',
validator (val, callback) {
if(that.util.isEmpty(val)) return callback(false)
let pattern = /^.{1,20}$/
// console.log(pattern.test(val))
if(pattern.test(val)) return callback(true)
return callback(false)
},
},
{ // 3 手机号
data: "othermoneyorderPhone",
type: 'text',
validator (val, callback) {
if(that.util.isEmpty(val)) return callback(true)
let pattern = /^([0-9]{0}|1[0-9]{10})$/
// console.log(pattern.test(val))
if(pattern.test(val)) return callback(true)
return callback(false)
},
},
{ // 4 项目类型
data: "othermoneyorderOthermoneytypeidOthermoneytypeFk",
type: 'dropdown',
source: [],
validator: 'Vdropdown_Fnull'
},
{ // 5 项目数量
data: "othermoneyorderNum",
type: 'text',
validator (val, callback) {
if(that.util.isEmpty(val)) return callback(false)
let pattern = /^[1-9][0-9]{0,10}$/
// console.log(pattern.test(val))
if(pattern.test(val)) return callback(true)
return callback(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)) return callback(true)
let pattern = /^.{0,200}$/
// console.log(pattern.test(val))
if(pattern.test(val)) return callback(true)
return callback(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: true
name: '添加备注',
},
"commentsRemove": { // 必须开启 comments: true
name: '删除备注',
},
"freeze_column": { // 必须开启 manualColumnFreeze: true
name: '固定列',
},
"unfreeze_column": { // 必须开启 manualColumnFreeze: true
name: '取消固定列',
}
}
},
afterChange (changes, source) {
console.log("changes: ", changes) // row, prop, oldVal, newVal
console.log("source: ", source) // op
if(that) { // 第一次加载没必要执行,避免报错
that.importExcelDsiable = true
that.sourceData = this.getSourceData()
}
if(source && ("CopyPaste.paste" == source || "edit" == source)) {
for(let item of changes) {
if(item[1] == "othermoneyorderUseridUserFk") {
let newName = item[3]
let newPhone = user_id2phone[user_lbl2id[[newName]]]
this.setDataAtRowProp(item[0], 'othermoneyorderUsername', newName, that.sourceData)
this.setDataAtRowProp(item[0], 'othermoneyorderPhone', newPhone, that.sourceData)
}
else if (item[1] == "othermoneyorderOriginaltotalprice" || item[1] == "othermoneyorderFacttotalprice" || item[1] == "othermoneyorderpayMoney") {
let newName = 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() {
let arr = this.$refs.ht.hotInstance.getSourceData(), obj = null
this.sourceData = []
for(let item of arr) {
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 = true
this.util.blur()
this.getExcelSourceData()
let obj = {}, str = '', idx = 0
let tmpSourceData = this.util.copy(this.sourceData)
let succ = 0
for(let item in tmpSourceData) {
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)
let len = Object.keys(custom).length, i = 0
for(let jtem in custom) {
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 = str
this.$refs.ht.hotInstance.updateSettings({
data: this.sourceData
})
if(succ > 0) {
this.$message({type: 'success', message: '已成功剪切 ' + succ + ' 条记录,请粘贴到本地 Excel 保存,并处理剩余错误记录'})
}
else if(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(let i=val.from-1; i<val.to; i++) {
arr.push(i)
}
}
else {
let data = this.$refs.ht.hotInstance.getSourceData()
let len = this.$refs.ht.hotInstance.countRows()
// console.log(data)
for(let i=0; i<len; i++) {
let name = 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()
let data = [], rows = []
for(let item of arr) {
data.push(this.sourceData[item])
rows.push(item)
}
// console.log(this.sourceData)
// console.log(data)
let jsonObj = null
let orderDate = null, orderTime = null, orderDatetime = null
let payDate = null, payTime = null, payDatetime = null
this.jsonData = []
let rowIdx = 0
for(let item of data) {
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(let jtem in custom) {
jsonObj[jtem] = item[jtem]
}
this.jsonData.push(jsonObj)
rowIdx++
}
// console.log('jsonData: ', this.jsonData)
},
async importExcel() {
this.loading = true
this.util.blur()
this.handleSourceData() // 获取最新数据
if(this.jsonData.length == 0) { // 判空处理
this.$message({type: 'warning', message: '导入失败,数据为空', duration: 0, showClose:true})
this.loading = false
this.importExcelDsiable = true
return false
}
await importBG.importOtherMoneyOrder({
otherMoneyOrderInfoList: this.jsonData
})
.then(res => {
console.log(res)
if (res.success) {
this.$message({type: 'success', message: res.msg})
}
else if (res.error) {
this.$message({type: 'warning', message: res.msg})
}
else {
this.$message({type: 'error', message: '导入失败,原因未知'})
}
this.sourceData = this.$refs.ht.hotInstance.getSourceData()
let rs = res.data, msg = ''
result = {}
for(let item of rs) {
result['' + item.errIndex] = item
}
for(let item of arr) {
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
},
async initExcel() {
this.loading = true
that = this // 为下面闭包做准备
await financeApi.getOthermoneytypeListByOrgId({
needDel: 'needDel' // 删除的不展示,只是为了修复显示ID的BUG
})
.then(res => {
console.log(res)
if(res.success){
let data = res.data, src = []
for(let item of data) {
src.push(item.othermoneytypeName)
othermoneytype_id2lbl[item.othermoneytypeId] = item.othermoneytypeName
othermoneytype_lbl2id[item.othermoneytypeName] = item.othermoneytypeId
}
this.columns[5].source = src
}
else if(res.nullwarn) {
}
else {
this.$message({type: 'error', message: res.msg})
}
})
.catch(function (error) {
console.log(error)
this.$message({type: 'error', message: '系统错误'})
})
// 关联用户
await user.getUserCheckList({})
.then(res => {
console.log(res)
if(res.success){
let data = res.data.data, src = []
for(let item of data) {
src.push(item.userName)
user_id2lbl[item.userId] = item.userName
user_lbl2id[item.userName] = item.userId
user_id2phone[item.userId] = item.userMobile
user_phone2id[item.userMobile] = item.userId
}
this.columns[2].source = src
}
else if(res.nullwarn) {
}
else {
this.$message({type: 'error', message: res.msg})
}
})
.catch(function (error) {
console.log(error)
this.$message({type: 'error', message: '系统错误'})
})
// 经办人
await user.getTeacherCheckList({})
.then(res => {
// console.log(res)
if(res.success){
let data = res.data.data, src = []
for(let item of data) {
src.push(item.userName)
operator_id2lbl[item.userId] = item.userName
operator_lbl2id[item.userName] = item.userId
}
this.columns[16].source = src
}
else if(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.data
for(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.length
this.hotSettings.colHeaders = this.colHeaders
this.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 () {
// 复制全部按钮
let copyBtn = document.getElementById("copyExcel")
this.Handsontable.dom.addEvent(copyBtn, 'click', () => {
this.util.blur()
let row1 = -1, col1 = -1, row2 = -1, col2 = -1
that.$confirm('是否复制“导入结果”该列?', '提示', {
confirmButtonText: '是',
cancelButtonText: '否',
type: 'warning'
}).then(() => {
row1 = col1 = 0
}).catch(() => {
row1 = 0
col1 = 1
}).finally(() => {
row2 = that.$refs.ht.hotInstance.countRows() - 1
col2 = 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>
<style lang="stylus" scoped>
@import '~@/assets/styles/varibles.styl'
>>> .is-readOnly
font-weight: bold
color: red
font-size: 14px
>>> .handsontable
.changeType
background: transparent
border: none
color: #616161
thead tr:first-child th
border-top: none
th:first-child
border-left: none
th
color: #616161
font-weight: normal
background-color: #fff
.batch-import
margin-bottom: 30px
.header
display: flex
flex-wrap: nowrap
flex-direction: row
justify-content: space-between
padding: 0 0 10px
.add
margin-right: 5px
margin-left: 0
border: 0px
height: 28px
letter-spacing: 1px
.reset
margin-right: 0
.body
height: 1000px
.overf
width: 100%
height: 100%
overflow: hidden
.wrapper
width: 100%
height: 100%
overflow: auto
</style>
Handsontable - 案例(Vue)
于 2019-09-13 00:25:36 首次发布