首先是vue代码
<template>
<div id="body-container"
style="position: absolute">
<div class="box-container">
<div class="lsb-table-box" >
<div class="table-container" id="lsb-table">
</div>
</div>
</div>
</div>
</template>
然后是js方法
/**
* 渲染表格
*/
function tableRenderCs() {
const data=[{
"one": "测试1",
"two": "测试2",
"three": "测试3",
"four": "测试4",
"five": "测试5",
"six": "测试6",
"seven": "测试7",
"eight": "测试8",
"nine": "测试9"
},{
"one": "测试1",
"two": "测试2",
"three": "测试3",
"four": "测试4",
"five": "测试5",
"six": "测试6",
"seven": "测试7",
"eight": "测试8",
"nine": "测试9"
},{
"one": "测试1",
"two": "测试2",
"three": "测试3",
"four": "测试4",
"five": "测试5",
"six": "测试6",
"seven": "测试7",
"eight": "测试8",
"nine": "测试9"
}]
let html = '<table class="table-wj JZ-A" border="1" cellspacing="0">' +
'<thead>' +
'<tr>' +
'<th rowspan="2" colspan="3">第一列</th>' +
'<th rowspan="2" colspan="1" style="width: 50px;">第二列</th>' +
'<th rowspan="2" colspan="1" style="width: 100px;">第三列</th>' +
'<th rowspan="2" colspan="1" style="width: 50px;">第四列</th>' +
'<th rowspan="2" colspan="1" style="width: 80px;">第五列</th>' +
'<th rowspan="1" colspan="3">第六列</th>' +
'</tr>' +
'<tr>' +
'<th colspan="1" style="width: 50px;">第六列的第一列</th>' +
'<th colspan="1" style="width: 90px;">第六列的第二列</th>' +
'</tr>' +
'</thead>' +
'<tbody>';
for (let i = 0; i < data.length; i++) {
const item = data[i];
html +=
`<tr>` +
`<td>${item.one}</td>` +
`<td>${item.two}</td>` +
`<td>${item.three}</td>` +
`<td>${item.four}</td>` +
`<td>${item.five}</td>` +
`<td>${item.six}</td>` +
`<td>${item.seven}</td>` +
`<td>${item.eight}</td>` +
`<td>${item.nine}</td>` +
`</tr>`;
}
html += '</tbody></table>';
let _$ = $(".lsb-table-box .table-container");
_$.append(html);
//存储列名对应的字段值,方便后面计算
let rowName = {
'0': 'one',
'1': 'two',
'2': 'three',
'3': 'four',
'4': 'five',
'5': 'six',
'6': 'seven',
'7': 'eight',
'8': 'nine',
}
editInput(_$, data, "two", rowName);
mergeColumns(); //调用动态合并行的方法
}
/**
* 执行合并逻辑
*/
function mergeColumns() {
let $table = $('table.table-wj');
let $rows = $table.find('tbody tr');
const numCols = $rows.eq(0).find('td').length;//考虑全部列
//const numCols = Math.min(3, $rows.eq(0).find('td').length); // 仅考虑前三列
// 遍历每列
for (let col = 1; col <= numCols; col++) {
let $currentColumn = $table.find(`td:nth-child(${col})`);
let prevContent = null;
let rowspan = 1;
for (let i = 0; i < $currentColumn.length; i++) {
let $currentCell = $($currentColumn[i]);
let currentContent = $currentCell.text();
if (currentContent === prevContent) {
rowspan++;
$currentCell.addClass('hidden');
} else {
if (rowspan > 1) {
$currentColumn.eq(i - rowspan).attr('rowspan', rowspan);
}
prevContent = currentContent;
rowspan = 1;
}
}
if (rowspan > 1) {
$currentColumn.eq($currentColumn.length - rowspan).attr('rowspan', rowspan);
}
}
// 清除被隐藏的单元格
$table.find('.hidden').remove();
}
const numCols这里给出了两种合并表格的逻辑,第一个是只会对前三列执行合并逻辑,而第二个会对所有列执行合并逻辑。下面是两种逻辑的合并效果图。
接下来是使单元格可以被编辑,并且获取到编辑后的值,以及单元格位置
在上面的方法中调用即可
editInput(_$, data, "two", rowName); //这里的four是上面 `<td>${item.four}</td>` 对应的字段名,也就是列名
mergeColumns(); //这里一定要注意先调用editInput方法再调用mergeColumns,不然获取编辑单元格的列索引会有问题
/**
* 设置单元格可编辑
* @param _$ 表对象
* @param data 表数据
* @param fieldName 编辑后要获取的值对应的列名
* @param rowName 列的索引与数据库字段相对应的集合
*/
function editInput(_$, data, fieldName, rowName) {
// 获取所有表格单元格
let cells = _$.find('td');
// 为每个单元格添加点击事件
cells.each(function (index) {
let column = $(this).index();
let row = $(this).closest('tr').index();
let columnName = Object.keys(data[0])[column]; // 获取对应列的字段名
$(this).data('columnName', columnName); // 存储列名为数据属性
$(this).on('mousedown', function (event) {
// 如果是鼠标右键点击,不进行操作
if (event.which === 3) return;
let $input = $(this).find('input'); // 检查单元格内是否已有输入框
if ($input.length === 0) { // 如果没有输入框,则进行以下操作
let currentValue = $(this).text();
// 创建一个输入框元素,并将当前单元格内容设置为其值
$input = $('<input type="text">');
$input.val(currentValue);
// 设置输入框的样式
$input.css({
'background-color': 'transparent', // 设置背景色为透明
'color': 'white', // 设置文字颜色为白色
'border': 'none', // 移除边框
'outline': 'none', // 移除外边框
});
// 清空单元格并将输入框添加到单元格中
$(this).empty().append($input);
// 焦点定位到输入框
$input.focus();
// 阻止默认行为
event.preventDefault();
// 处理输入框失去焦点事件
$input.on('blur', function () {
let newValue = $input.val();
let valueName = rowName[column]; // 获取列索引对应的字段名称
let columnValue = data[row][fieldName]; // 获取对应字段的值
console.log('编辑后的内容:', newValue);
console.log('所在单元格位置:', '行:', row, '列:', column);
console.log('所在列字段名:', valueName);
console.log(fieldName + '列的值:', columnValue);
console.log(`更改了${fieldName}为${columnValue}的字段${valueName}的值为${newValue}`)
$(this).parent('td').text(newValue);
});
}
});
});
}
实现效果如下,同时还获取了当前单元格所在行里面指定的某一列的数据内容(比如可以获取当前行的id,以此来给后端修改数据库中的数据),注意行是从表头下面开始的,行和列的下标都是从0开始