Layui table.exportFile() 不支持表头合并,必须用 SheetJS 手动构建含 !merges 的 Excel;需通过 table.cache 获取数据、二维数组定义多级表头,并精确计算行列索引(r/c 从 0 开始),导出时指定 bookType: 'xlsx' 和正确 MIME 类型。
直接调用 table.exportfile() 导出的 excel,表头永远是扁平的一行,colspan 和 rowspan 在导出时被完全忽略——这不是你配置错了,是 layui 1.x 和 2.x 的导出逻辑本身就不解析表头结构。
真正能合并表头的,只有手动构造 Excel 文件这一个路子。别试 excel 参数加 mergeCells,那个字段只在部分第三方扩展里存在,Layui 官方没这个能力。
核心思路:不走 table.exportFile(),而是用 table.cache 拿数据 + 手动定义表头结构(含合并范围),再用 XLSX.utils.aoa_to_sheet() 构建 sheet。
table.init 的 id 查到对应表格实例,再取 table.cache['your-table-id'] 获取原始数据[['姓名', null, '成绩'], ['语文', '数学', '英语']] → 第一行“姓名”需 colspan=2,“成绩”colspan=3,但数组里用 null 占位只是示意,实际要靠 !merges 属性声明合并区域const ws = XLSX.utils.aoa_to_sheet([headerRow1, headerRow2, ...dataRows]);ws['!merges'] = [ { s: { r: 0, c: 0 }, e: { r: 1, c: 0 } }, // 合并第0行第0列到第1行第0列(跨两行) { s: { r: 0, c: 1 }, e: { r: 0, c: 2 } } // 合并第0行第1-2列(跨两列)];
Layui 表格渲染后 DOM 里的 <th colspan="2"> 看着直观,但导出时已经断开和 Excel 单元格的映射。你要导出几级表头、哪几列合并,得提前在 JS 里把每一块合并区域的起止行列(r/c)算清楚。
r 和 c 从 0 开始计数,且 s 和 e 都要包含在内(即 {r:0,c:0} 到 {r:0,c:2} 是 3 列)hide: true),它不参与数据列计数,但表头数组里仍要留空位或跳过,否则行列对不上用 XLSX.write(wb, {type: 'array', bookType: 'xlsx'}) 得到 Uint8Array 后,常见错误是用 new Blob([data], {type: 'text/csv;charset=utf-8'}) 包 —— 这会导致 Excel 打开报错或乱码。
bookType: 'xlsx',且 Blob 的 type 设为 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
.xlsx,写成 .xls 或 .csv 会触发 Excel 兼容模式,合并单元格直接丢弃location.href = URL.createObjectURL(...),某些浏览器对 Blob URL 的 Excel 解析不完整;老实用 saveAs(来自 file-saver)表头合并这事,难点不在代码多,而在要把视觉上的“树状表头”翻译成 Excel 要求的扁平坐标+合并指令。少算一行、错一个 c 值,整块就错位。动手前,先在纸上画格子标好 r/c,比对着改三次代码更快。