分享最近工作中遇到的一个场景:导出表格,需要准备好表格的html代码,此表格支持最上面的表头合并且居中展示表格标题,如果上下行数据有相同的,则要上下合并单元格
封装了一个如下的方法
const configToTable = (config)=> {
const { columns = [], data = [], mergeColumns = [], title = '' } = config
let html = '<table border><thead>'
if (title) {
const colSpan = columns.length
html += `<tr><th colspan="${colSpan}">${title}</th></tr>`
}
html += '<tr>'
columns.forEach((column) => {
html += `<th>${column.text}</th>`
})
html += '</tr></thead><tbody>'
if (!data.length) {
html += `<tr><td colspan="${columns.length}">暂无数据</td></tr>`
} else {
data.forEach((item) => {
html += '<tr>'
columns.forEach((column) => {
html += `<td class=${column.className} style=${column.style}>${item[column.prop]}</td>`
})
html += '</tr>'
})
}
html += `</tbody></table>`
if (!mergeColumns.length) return html
// 如果无需合并单元格,就不用进行以下的操作
const tempDiv = document.createElement('div')
tempDiv.innerHTML = html
const table = tempDiv.querySelector('table')
const tbody = table.querySelector('tbody')
mergeColumns.forEach((column) => {
const colIndex = columns.findIndex((item) => item.prop === column)
let lastValue = ''
let lastTd= {}
let spanCount = 1
Array.from(tbody.rows).forEach((row) => {
const cell = row.cells[colIndex]
if(cell.textContent === lastValue) {
spanCount++
lastTd.rowSpan = spanCount
cell.setAttribute('data-remove', 'true')
}else {
lastValue = cell.textContent
lastTd = cell
spanCount = 1
}
})
})
Array.from(tbody.rows).forEach(row => {
Array.from(row.cells).forEach(cell => {
if(cell.getAttribute('data-remove') === 'true') {
cell.parentNode?.removeChild(cell)
}
})
})
return tempDiv.innerHTML
}
示例:
准备好参数:
const tableConfig = {
columns: [
{
text: '姓名',
prop: 'name',
className: 'name',
style: 'width: 200px'
},
{
text: '年龄',
prop: 'age',
className: 'age',
style: 'width: 200px'
},
{
text: '性别',
prop:'sex',
className:'sex',
style: 'width: 200px'
},
{
text: '地址',
prop: 'address',
className: 'address',
style: 'width: 200px'
}
],
data: [
{
name: '张三',
age: 18,
sex: '男',
address: '深圳'
},
{
name: '李四',
age: 18,
sex: '女',
address: '深圳'
},
{
name: '王五',
age: 20,
sex: '男',
address: '深圳'
}
],
title: '测试',
mergeColumns: ['address', 'age']
}
调用方法
configToTable(tableConfig)
最终效果
表格样式需要自己调整一下,否则样式偏丑