效果如下:
<template>
<t-card>
<t-form>
<div>
<div class="category">一:项目基本信息</div>
<rn-form ref="form" ref-value="form" colon :data="formData" style="padding: 1% 3%" :form-item-config="formItemConfig" :rules="rules"></rn-form>
</div>
<div>
<t-button @click="getDataSource">获取数据源</t-button>
<t-button @click="setDataSource">回显数据</t-button>
<t-button @click="setTreeDataSource">回显多层级树形结构数据</t-button>
<t-button @click="setMergeCells">合并单元格</t-button>
<div class="category">二:建设内容</div>
<hot-table ref="hotTableComponent" width="100%" height="auto" :settings="settings"></hot-table>
</div>
</t-form>
</t-card>
</template>
<script lang='ts'>
import { HotTable } from '@handsontable/vue3'
import HyperFormula from 'hyperformula'
import RnForm from '@/components/form/RnForm.vue'
const data = [{ id: 1, xh: '(一)', content: '建安工程', isEdit: false, remark: '=(G1+H1)', price: '=SUM(G2:G11)', invest: '=SUM(H2:H11)', action: '', pid: '' }, { id: 1710405265802, xh: '(一)', content: '测试', isEdit: true, pid: 1, remark: '=(G2+H2)', price: 2, invest: 1, type: '弹窗成功', scale: '新建文本文档 (2).txt', unit: '平方米' }, { id: 1710405266212, xh: '(一)', content: '测试', isEdit: true, pid: 1, remark: '=(G3+H3)', price: 3, invest: 2, type: '弹窗成功', scale: '新建文本文档 (2).txt', unit: '平方米' }, { id: 1710405266699, xh: '(一)', content: '测试', isEdit: true, remark: '=(G4+H4)', price: 4, invest: 3, pid: 1, type: '弹窗成功', scale: '新建文本文档 (2).txt', unit: '平方米' }, { id: 1710405273518, xh: '(一)', content: '测试', isEdit: true, remark: '=(G5+H5)', price: 2, invest: 2, action: null, pid: 1, type: '弹窗成功', scale: '新建文本文档 (2).txt', unit: '平方米' }, { id: 1710405278959, xh: '(一)', content: '测试', isEdit: true, remark: '=(G6+H6)', price: 1, invest: 3, action: null, pid: 1, type: '弹窗成功', scale: '新建文本文档 (2).txt', unit: '平方米' }, { id: 1710405934462, xh: '(一)', content: '测试', isEdit: true, remark: '=(G7+H7)', price: 4, invest: 4, action: null, pid: 1, type: '弹窗成功', scale: '新建文本文档 (2).txt', unit: '平方米' }, { id: 1710405934644, xh: '(一)', content: '测试', isEdit: true, remark: '=(G8+H8)', price: 432, invest: 343, action: null, pid: 1, type: '弹窗成功', scale: '新建文本文档 (2).txt', unit: '平方米' }, { id: 1710405934823, xh: '(一)', content: '测试', isEdit: true, remark: '=(G9+H9)', price: 4, invest: 234, action: null, pid: 1, type: '弹窗成功', scale: '新建文本文档 (2).txt', unit: '平方米' }, { id: 1710405935029, xh: '(一)', content: '测试', isEdit: true, remark: '=(G10+H10)', price: 34, invest: 324, action: null, pid: 1, type: '弹窗成功', scale: '新建文本文档 (2).txt', unit: '平方米' }, { id: 1710405935221, xh: null, content: '测试', isEdit: true, remark: '=(G11+H11)', price: 32, invest: 32, action: null, pid: 1, type: '弹窗成功', scale: '新建文本文档 (2).txt', unit: '平方米' }, { id: 2, xh: '(二)', content: '田间工程', isEdit: false, remark: '=(G12+H12)', price: '=SUM(G13:G14)', invest: '=SUM(H13:H14)' }, { id: 1710405969779, xh: '(二)', content: '田间工程', isEdit: true, remark: '=(G13+H13)', price: 44, invest: 432, action: null, pid: 2, type: '弹窗成功', scale: '工作.txt' }, { id: 1710405970575, xh: '(二)', content: '田间工程', isEdit: true, remark: '=(G14+H14)', price: 32, invest: 432, action: null, pid: 2, scale: '工作.txt' }, { id: 3, xh: '(三)', content: '仪器设备购置', isEdit: false }, { id: 4, xh: '(四)', content: '其他', isEdit: false }, { id: 5, xh: '合计', isEdit: false }]
let _this = null
const FORM_ITEM_CONFIG = [
{ hidden: false, name: 'projectName', label: '项目编号', componentType: 't-input', dataType: '', colProps: { span: 6 }, componentProps: { type: 'text', placeholder: '请输入项目名称' }, formItemProps: { labelWidth: '120px' } },
{ hidden: false, name: 'declareFileName', label: '项目名称', componentType: 't-input', dataType: '', colProps: { span: 6 }, componentProps: { type: 'text', placeholder: '请输入申报文件名称' }, formItemProps: { labelWidth: '120px' } },
{ hidden: false, name: 'declareFileName', label: '申报单位', componentType: 't-input', dataType: '', colProps: { span: 6 }, componentProps: { type: 'text', placeholder: '请输入申报文件名称' }, formItemProps: { labelWidth: '120px' } },
{ hidden: false, name: 'declareFileName', label: '申报文件', componentType: 't-input', dataType: '', colProps: { span: 6 }, componentProps: { type: 'text', placeholder: '请输入申报文件名称' }, formItemProps: { labelWidth: '120px' } },
{ hidden: false, name: 'declareFileName', label: '建设性质', componentType: 't-input', dataType: '', colProps: { span: 6 }, componentProps: { type: 'text', placeholder: '请输入申报文件名称' }, formItemProps: { labelWidth: '120px' } },
{ hidden: false, name: 'declareFileName', label: '建设单位', componentType: 't-input', dataType: '', colProps: { span: 6 }, componentProps: { type: 'text', placeholder: '请输入申报文件名称' }, formItemProps: { labelWidth: '120px' } },
{ hidden: false, name: 'declareFileName', label: '建设年限', componentType: 't-input', dataType: '', colProps: { span: 6 }, componentProps: { type: 'text', placeholder: '请输入申报文件名称' }, formItemProps: { labelWidth: '120px' } },
{ hidden: false, name: 'declareFileName', label: '建设地点(省、市、县、镇)', componentType: 't-input', dataType: '', colProps: { span: 6 }, componentProps: { type: 'text', placeholder: '请输入申报文件名称' }, formItemProps: { labelWidth: '120px' } },
{ hidden: false, name: 'declareFileName', label: '主要建设内容 及规模', componentType: 't-input', dataType: '', colProps: { span: 6 }, componentProps: { type: 'text', placeholder: '请输入申报文件名称' }, formItemProps: { labelWidth: '120px' } },
]
export default {
name: 'DeclareGuide',
components: { RnForm, HotTable },
// eslint-disable-next-line max-lines-per-function
data() {
return {
settings: {
language: 'zh-CN', // 官方汉化
licenseKey: 'non-commercial-and-evaluation', // 去除底部非商用声明
colHeaders: ['A', 'B', '建设内容C', '建筑形式D', '规模(数量)E', '单位F', '单价(元)G', '投资估算(万元)H', '备注I'],
columns: [
{ data: 'action',
type: 'text',
renderer(instance, td, row, col, prop, value, cellProperties) {
if (!instance.getSourceDataAtRow (row)?.isEdit && instance.getSourceDataAtRow (row).content !== '合计') {
td.innerHTML = `<img src="/src/assets/button-img/btn-add.svg" style="width: 20px;height: 20px;cursor: pointer;margin-top: 3px" title="添加" οnclick="addRow(${row},${col})">`
} else {
td.innerHTML = `<img src="/src/assets/button-img/btn-add.svg" style="width: 20px;height: 20px;cursor: pointer;margin-top: 3px" title="添加" οnclick="addRow(${row},${col})"> `
td.innerHTML += `<img src="/src/assets/button-img/btn-cut.svg" style="width: 20px;height: 20px;cursor: pointer;margin-top: 3px" title="删除" οnclick="deleteRow(${row})">`
}
td.style.height = '100%'
td.style.textAlign = 'center'
td.style.verticalAlign = 'middle'
cellProperties.readOnly = true
return td
} },
{ data: 'xh',
type: 'text',
renderer(instance, td, row, col, prop, value, cellProperties) {
if (!instance.getSourceDataAtRow (row)?.isEdit) {
td.style.verticalAlign = 'middle'
} else {
}
td.innerHTML = value
return td
} },
{ data: 'content',
type: 'text',
renderer(instance, td, row, col, prop, value, cellProperties) {
if (!instance.getSourceDataAtRow (row)?.isEdit) {
td.style.verticalAlign = 'middle'
cellProperties.readOnly = true
} else {
}
if (_this) {
// 是否显示toggle图标
const showToggleIcon = _this.filterChildrenLength(instance.getSourceDataAtRow(row).id)
const { pid } = instance.getSourceDataAtRow(row)
const spaceIndex = _this.filterParent(pid, 0)
let paddingElement = ''
if (spaceIndex > 0) {
paddingElement = `${5 * spaceIndex}px`
}
if (showToggleIcon) {
const toggle = _this.filterToggleStatus(row)
if (toggle) {
td.innerHTML = `<div style="cursor: pointer;height: 100%;display: flex" οnclick="toggoleRow(${instance.getSourceDataAtRow(row).id},${row},this)"><img src="/src/assets/button-img/up.svg" style="width: 12px;height: 100%;margin-right:5px;padding-left: ${paddingElement};" title="展开" ><div style="height: 100%;word-break: break-all;display:flex;align-items:center;">${value}</div></div>`
} else {
td.innerHTML = `<div style="cursor: pointer;height: 100%;display: flex" οnclick="toggoleRow(${instance.getSourceDataAtRow(row).id},${row},this)"><img src="/src/assets/button-img/down.svg" style="width: 12px;height: 100%;margin-right:5px;padding-left: ${paddingElement}; " title="收缩"><div style="height: 100%;word-break: break-all;display:flex;align-items:center;">${value}</div></div>`
}
} else {
paddingElement = `${7 * spaceIndex}px`
td.innerHTML = `<div style="height: 100%;word-break: break-all;display:flex;align-items:center;padding-left: ${paddingElement};">${value || ''}</div>`
}
} else {
td.innerHTML = value
}
// eslint-disable-next-line no-bitwise
return td & cellProperties & value
} },
{ data: 'type',
type: 'text',
renderer(instance, td, row, col, prop, value, cellProperties) {
if (!instance.getSourceDataAtRow (row)?.isEdit) {
td.innerHTML = value || ''
} else {
td.innerHTML = `<div class="htAutocompleteArrow" aria-hidden="true"><img src="/src/assets/button-img/open-window.svg" style="width: 20px;height: 20px;margin-top: 3px"></div><div style="cursor: pointer;height: 100%;width: 100%" οnclick="showModals(${row}, ${col})">${value || ''}</div>`
}
return td
} },
{ data: 'scale',
type: 'text',
renderer(instance, td, row, col, prop, value, cellProperties) {
if (!instance.getSourceDataAtRow (row)?.isEdit) {
td.innerHTML = `${value || ''}`
} else if (value) {
td.innerHTML = `<div class="htAutocompleteArrow" ><img src="/src/assets/button-img/upload.svg" style="width: 15px;height: 15px;margin-top: 3px"></div><div style="cursor: pointer;width: 100%;height: 100%" οnclick="selectFile(${row},${col})"><input type="file" id="myFile_${row}_${col}" hidden οnchange="beforeUpload(this)">${value || ''} <img src="/src/assets/button-img/delete.svg" style="cursor:pointer;width: 10px;height: 10px;" title="删除" οnclick="deleteFile(${row},${col})"></div>`
} else {
td.innerHTML = `<div class="htAutocompleteArrow" ><img src="/src/assets/button-img/upload.svg" style="width: 15px;height: 15px;margin-top: 3px"></div><div style="cursor: pointer;width: 100%;height: 100%" οnclick="selectFile(${row},${col})"><input type="file" id="myFile_${row}_${col}" hidden οnchange="beforeUpload(this)">${value || ''}</div>`
}
return td
} },
{ data: 'unit',
type: 'dropdown',
source: ['处', '个', '口', '立方米', '米', '亩', '平方米', '台', '套', '项', '株', '座'],
renderer(instance, td, row, col, prop, value, cellProperties) {
if (!instance.getSourceDataAtRow (row)?.isEdit) {
td.innerHTML = `${value || ''}`
} else {
td.innerHTML = `<div class="htAutocompleteArrow" >▼</div>${value || ''}`
}
return td
} },
{ data: 'price',
type: 'numeric',
renderer(instance, td, row, col, prop, value, cellProperties) {
if (!instance.getSourceDataAtRow (row)?.isEdit) {
td.style.color = 'red'
td.style.fontWeight = 'bold'
if (value && typeof (value) === 'string' && value.indexOf('=') !== -1) {
instance.setDataAtCell(row, col, value)
td.innerHTML = 0
} else {
td.innerHTML = `${value === '#REF!' ? 0 : value || 0}`
}
} else {
td.innerHTML = `<div style="height:100%;width: 0%;float: right;display: flex;align-items: center;font-weight: bold">$</div>${value || ''}`
}
td.style.paddingRight = '20px'
td.style.wordBreak = 'break-all'
return td
} },
{ data: 'invest',
type: 'numeric',
renderer(instance, td, row, col, prop, value, cellProperties) {
if (!instance.getSourceDataAtRow (row)?.isEdit) {
td.style.color = 'red'
td.style.fontWeight = 'bold'
if (value && typeof (value) === 'string' && value.indexOf('=') !== -1) {
instance.setDataAtCell(row, col, value)
td.innerHTML = 0
} else {
td.innerHTML = `${value === '#REF!' ? 0 : value || 0}`
}
} else {
td.innerHTML = `<div style="height:100%;width: 0%;float: right;display: flex;align-items: center;font-weight: bold">¥</div>${value || ''}`
}
td.style.paddingRight = '20px'
td.style.wordBreak = 'break-all'
return td
} },
{ data: 'remark',
type: 'text',
renderer(instance, td, row, col, prop, value, cellProperties) {
td.style.color = 'red'
td.style.fontWeight = 'bold'
//
if (value && typeof (value) === 'string' && value.indexOf('=') !== -1) {
instance.setDataAtCell(row, col, value)
td.innerHTML = 0
} else {
td.innerHTML = `${value === '#REF!' ? 0 : value || 0}`
}
td.style.paddingRight = '20px'
td.style.wordBreak = 'break-all'
return td
} },
],
data: [
{ id: 1, xh: '(一)', content: '建安工程', isEdit: false },
{ id: 2, xh: '(二)', content: '田间工程', isEdit: false },
{ id: 3, xh: '(三)', content: '仪器设备购置', isEdit: false },
{ id: 4, xh: '(四)', content: '其他', isEdit: false },
{ id: 5, xh: '合计', isEdit: false },
],
currentRowClassName: 'currentRow', // 突出显示行
currentColClassName: 'currentCol', // 突出显示列
autoWrapRow: false, // 自动换行
trimWhitespace: false, // 去除空格
colWidths: [30, 40, 100, 150, 150, 80, 80, 100, 100, 150],
stretchH: 'all',
renderAllRows: false,
rowHeaders: false, // 列序号
formulas: {
engine: HyperFormula, // 引入excel公式
},
copyable: true, // 允许键盘复制
copyPaste: true, // 复制粘贴
fixedColumnsLeft: 0, // 固定左边列数
fixedRowsTop: 0, // 固定上边列数
manualColumnResize: true,
hiddenRows: {
rows: [],
},
mergeCells: [
],
},
formItemConfig: [],
}
},
computed: {
},
mounted() {
// eslint-disable-next-line @typescript-eslint/no-this-alias
_this = this
_this.initFormItemConfig()
window.addRow = _this.addRow
window.deleteRow = _this.deleteRow
window.toggoleRow = _this.toggoleRow
window.showModals = _this.showModals
window.selectFile = _this.selectFile
window.beforeUpload = _this.beforeUpload
window.deleteFile = _this.deleteFile
},
methods: {
filterChildrenLength(id) {
const sourceData = _this.$refs.hotTableComponent.hotInstance.getSourceData()
const filterChild = sourceData.filter((item) => item.pid === id)
return filterChild.length > 0
},
filterToggleStatus(row) {
const rows = _this.$refs.hotTableComponent.hotInstance.getPlugin('hiddenRows').getHiddenRows()
const filter = rows.filter((item) => item === row + 1)
return filter.length > 0
},
initFormItemConfig() {
_this.formItemConfig = FORM_ITEM_CONFIG
},
addRow(row, col) {
// 获取表格源数据
// _this.settings.maxRows = _this.settings.maxRows + 1
// _this.$refs.hotTableComponent.hotInstance.updateSettings({ maxRows: Number(_this.settings.maxRows), })
// _this.$refs.hotTableComponent.hotInstance.getPlugin('formulas').engine.updateConfig({ maxRows: Number(_this.settings.maxRows) })
const sourceData = _this.$refs.hotTableComponent.hotInstance.getSourceData()
// 获取add父节点行数据
const { id } = _this.$refs.hotTableComponent.hotInstance.getSourceDataAtRow(row)
const filterChild = sourceData.filter((item) => item.pid === id)
let alertRowIndex = row
// 如果有子节点,就插入到子节点后面,没有的话,插入父节点后面
if (filterChild.length > 0) {
alertRowIndex = row + filterChild.length
}
// 添加一行空白的数据
_this.$refs.hotTableComponent.hotInstance.alter('insert_row_below', alertRowIndex)
// 拿到刚才新增的数据,赋值
const alertRow = _this.$refs.hotTableComponent.hotInstance.getSourceDataAtRow(alertRowIndex + 1)
alertRow.id = new Date().getTime()
alertRow.pid = id
alertRow.isEdit = true
// 赋值后,将新数据替换handsontable源数据
const newSourceData = _this.$refs.hotTableComponent.hotInstance.getSourceData()
newSourceData.splice(alertRowIndex + 1, 1, alertRow)
// 更新handsontable源数据
_this.$refs.hotTableComponent.hotInstance.loadData(newSourceData)
setTimeout(() => {
_this.$refs.hotTableComponent.hotInstance.setDataAtCell(row, 6, `=SUM(g${row + 2}:g${alertRowIndex + 2})`)
_this.$refs.hotTableComponent.hotInstance.setDataAtCell(row, 7, `=SUM(h${row + 2}:h${alertRowIndex + 2})`)
_this.$refs.hotTableComponent.hotInstance.setDataAtCell(row, 8, `=(G${row + 1}+H${row + 1})`)
_this.$refs.hotTableComponent.hotInstance.setDataAtCell(alertRowIndex + 1, 8, `=(G${alertRowIndex + 2}+H${alertRowIndex + 2})`)
}, 100)
},
deleteRow(row) {
_this.$refs.hotTableComponent.hotInstance.alter('remove_row', row)
// 获取表格源数据
// const afterMaxRows = _this.settings.maxRows - 1
// _this.$refs.hotTableComponent.hotInstance.updateSettings({ maxRows: afterMaxRows, })
},
toggoleRow(selfId, row, e) {
const hideArr = []
const plugin = _this.$refs.hotTableComponent.hotInstance.getPlugin('hiddenRows')
const sourceData = _this.$refs.hotTableComponent.hotInstance.getSourceData()
const filterSelfChild = []
const loopFilterParent = function (id) {
const filterNextChild = sourceData.filter((item) => item.pid === id)
if (filterNextChild.length > 0) {
for (const filterChildElement of filterNextChild) {
filterSelfChild.push(filterChildElement)
loopFilterParent(filterChildElement.id)
}
}
}
loopFilterParent(selfId)
for (let i = row + 1; i <= row + filterSelfChild.length; i++) {
hideArr.push(i)
}
if (e.children[0].src.indexOf('down') !== -1) {
e.src = e.children[0].src.replace('down', 'up')
plugin.hideRows(hideArr)
} else {
e.src = e.children[0].src.replace('up', 'down')
plugin.showRows(hideArr)
}
_this.$refs.hotTableComponent.hotInstance.render()
},
showModals(row, col) {
const $dialog = this.$dialog({
header: 'Dialog-Plugin',
body: 'Plugin 方式创建新弹窗',
className: 't-dialog-new-class1 t-dialog-new-class2',
style: 'color: rgba(0, 0, 0, 0.6)',
onConfirm: () => {
_this.$refs.hotTableComponent.hotInstance.setDataAtCell(row, col, '弹窗成功')
$dialog.hide()
},
})
},
selectFile(row, col) {
const element = document.getElementById(`myFile_${row}_${col}`)
element.click()
},
beforeUpload(event) {
const file = event.files[0]
const arr = event.id.split('_')
_this.$refs.hotTableComponent.hotInstance.setDataAtCell(Number(arr[1]), Number(arr[2]), file.name)
},
deleteFile(row, col) {
_this.$refs.hotTableComponent.hotInstance.setDataAtCell(row, col, null)
},
getDataSource() {
console.log(_this.$refs.hotTableComponent.hotInstance.getSourceData())
},
setDataSource() {
const data = [{ id: 1, xh: '(一)', content: '建安工程', isEdit: false, remark: '=(G1+H1)', price: '=SUM(G2:G11)', invest: '=SUM(H2:H11)', action: '', pid: '' }, { id: 1710405265802, xh: '(一)', content: '测试', isEdit: true, pid: 1, remark: '=(G2+H2)', price: 2, invest: 1, type: '弹窗成功', scale: '新建文本文档 (2).txt', unit: '平方米' }, { id: 1710405266212, xh: '(一)', content: '测试', isEdit: true, pid: 1, remark: '=(G3+H3)', price: 3, invest: 2, type: '弹窗成功', scale: '新建文本文档 (2).txt', unit: '平方米' }, { id: 1710405266699, xh: '(一)', content: '测试', isEdit: true, remark: '=(G4+H4)', price: 4, invest: 3, pid: 1, type: '弹窗成功', scale: '新建文本文档 (2).txt', unit: '平方米' }, { id: 1710405273518, xh: '(一)', content: '测试', isEdit: true, remark: '=(G5+H5)', price: 2, invest: 2, action: null, pid: 1, type: '弹窗成功', scale: '新建文本文档 (2).txt', unit: '平方米' }, { id: 1710405278959, xh: '(一)', content: '测试', isEdit: true, remark: '=(G6+H6)', price: 1, invest: 3, action: null, pid: 1, type: '弹窗成功', scale: '新建文本文档 (2).txt', unit: '平方米' }, { id: 1710405934462, xh: '(一)', content: '测试', isEdit: true, remark: '=(G7+H7)', price: 4, invest: 4, action: null, pid: 1, type: '弹窗成功', scale: '新建文本文档 (2).txt', unit: '平方米' }, { id: 1710405934644, xh: '(一)', content: '测试', isEdit: true, remark: '=(G8+H8)', price: 432, invest: 343, action: null, pid: 1, type: '弹窗成功', scale: '新建文本文档 (2).txt', unit: '平方米' }, { id: 1710405934823, xh: '(一)', content: '测试', isEdit: true, remark: '=(G9+H9)', price: 4, invest: 234, action: null, pid: 1, type: '弹窗成功', scale: '新建文本文档 (2).txt', unit: '平方米' }, { id: 1710405935029, xh: '(一)', content: '测试', isEdit: true, remark: '=(G10+H10)', price: 34, invest: 324, action: null, pid: 1, type: '弹窗成功', scale: '新建文本文档 (2).txt', unit: '平方米' }, { id: 1710405935221, xh: null, content: '测试', isEdit: true, remark: '=(G11+H11)', price: 32, invest: 32, action: null, pid: 1, type: '弹窗成功', scale: '新建文本文档 (2).txt', unit: '平方米' }, { id: 2, xh: '(二)', content: '田间工程', isEdit: false, remark: '=(G12+H12)', price: '=SUM(G13:G14)', invest: '=SUM(H13:H14)' }, { id: 1710405969779, xh: '(二)', content: '田间工程', isEdit: true, remark: '=(G13+H13)', price: 44, invest: 432, action: null, pid: 2, type: '弹窗成功', scale: '工作.txt' }, { id: 1710405970575, xh: '(二)', content: '田间工程', isEdit: true, remark: '=(G14+H14)', price: 32, invest: 432, action: null, pid: 2, scale: '工作.txt' }, { id: 3, xh: '(三)', content: '仪器设备购置', isEdit: false }, { id: 4, xh: '(四)', content: '其他', isEdit: false }, { id: 5, xh: '合计', isEdit: false }]
_this.$refs.hotTableComponent.hotInstance.loadData(data)
window.ht = _this.$refs.hotTableComponent.hotInstance
setTimeout(() => {
_this.$refs.hotTableComponent.hotInstance.render()
}, 100)
},
setTreeDataSource() {
const data = [{ id: 1, xh: '(一)', content: '建安工程', isEdit: false, remark: '=(G1+H1)', price: '=SUM(G2:G11)', invest: '=SUM(H2:H11)', action: '', pid: '' }, { id: 1710488757149, xh: null, content: '二级建安工程', isEdit: true, pid: 1, remark: '=(G2+H2)', price: '=SUM(G3:G3)', invest: '=SUM(H3:H3)' }, { id: 1710488770271, xh: null, content: '三级建安工程', isEdit: true, remark: '=(G3+H3)', price: '=SUM(G4:G4)', invest: '=SUM(H4:H4)', pid: 1710488757149 }, { id: 1710488779144, xh: null, content: '四级建安工程', isEdit: true, remark: '=(G4+H4)', price: '=SUM(G5:G5)', invest: '=SUM(H5:H5)', pid: 1710488770271 }, { id: 1710488784815, xh: null, content: '五级建安工程', isEdit: true, remark: '=(G5+H5)', price: '=SUM(G6:G6)', invest: '=SUM(H6:H6)', pid: 1710488779144 }, { id: 1710488790893, xh: null, content: '六级建安工程', isEdit: true, remark: '=(G6+H6)', price: '=SUM(G7:G7)', invest: '=SUM(H7:H7)', pid: 1710488784815 }, { id: 1710488796686, xh: null, content: '七级建安工程', isEdit: true, remark: '=(G7+H7)', price: '=SUM(G8:G8)', invest: '=SUM(H8:H8)', pid: 1710488790893 }, { id: 1710488803610, xh: null, content: '八级建安工程', isEdit: true, remark: '=(G8+H8)', price: '=SUM(G9:G9)', invest: '=SUM(H9:H9)', pid: 1710488796686 }, { id: 1710488811848, xh: null, content: '九级建安工程', isEdit: true, remark: '=(G9+H9)', price: '=SUM(G10:G10)', invest: '=SUM(H10:H10)', pid: 1710488803610 }, { id: 1710488820012, xh: null, content: '十级建安工程', isEdit: true, remark: '=(G10+H10)', price: null, invest: null, pid: 1710488811848 }, { id: 1710488763836, xh: null, content: '二级建安工程', isEdit: true, pid: 1, remark: '=(G11+H11)' }, { id: 2, xh: '(二)', content: '田间工程', isEdit: false }, { id: 3, xh: '(三)', content: '仪器设备购置', isEdit: false }, { id: 4, xh: '(四)', content: '其他', isEdit: false }, { id: 5, xh: '合计', isEdit: false }]
_this.$refs.hotTableComponent.hotInstance.loadData(data)
window.ht = _this.$refs.hotTableComponent.hotInstance
setTimeout(() => {
_this.$refs.hotTableComponent.hotInstance.render()
}, 100)
},
setMergeCells() {
_this.settings.mergeCells.push({ row: 1, col: 1, rowspan: 1, colspan: 3 }, { row: 2, col: 2, rowspan: 2, colspan: 1 })
},
filterParent(pid, spaceIndex) {
let resultIndex = spaceIndex
if (!pid) {
return resultIndex
}
const loopFilterParent = function (pid, spaceIndex) {
const sourceData = _this.$refs.hotTableComponent.hotInstance.getSourceData()
const filterChild = sourceData.filter((item) => item.id === pid)
if (filterChild.length > 0) {
loopFilterParent(filterChild[0].pid, spaceIndex + filterChild.length)
} else {
resultIndex = spaceIndex
}
}
loopFilterParent(pid, resultIndex)
return resultIndex
},
},
}
</script>
<style lang="less" scoped>
.category{
font-weight: bold;
font-size: large;
}
</style>