import { addClass, hasClass, query, queryAll } from '@/utils/frontend/dom'; // 表头分组 export default function useGroupingHeaders(tableWrapper: HTMLElement, cellGrid: number[][], fixedColumnsLeft = 0) { const generateGroupHeaders = () => { const heighten = ($th: Element, count: number) => { addClass($th, 'real-th'); const $relative = query($th, '.relative') as HTMLElement; $relative.style.height = `${count * 26 - 1}px`; $relative.style.lineHeight = `${count * 26}px`; }; const grouping = ($thead: HTMLElement, rowNums: number, colNums: number) => { const $trList = Array.from(queryAll($thead, 'tr')); if ($trList.length <= 1) return; const $thList = [] as Element[][]; $trList.forEach($tr => { const $rowThList = Array.from(queryAll($tr, 'th')); // 去掉左上角的 th $rowThList.shift(); $thList.push($rowThList); }); // 二维数组,记录每个 th 是否已被它正下方的 th 覆盖,初始化为 false 代表没有被覆盖 const coveredGrid = new Array(rowNums).fill(null).map(() => new Array(colNums).fill(false)); for (let i = rowNums - 1; i >= 0; i--) { for (let j = 0; j < colNums; j++) { const $th = $thList[i][j]; if (!$th) return; // coveredGrid[i][j] 为 true 说明这个单元格被它下面的单元格覆盖了,不用再考虑了 if (coveredGrid[i][j] || hasClass($th, 'hiddenHeader')) continue; coveredGrid[i][j] = true; // 将当前单元格上面的拥有相同 id 的单元格(这些单元格属于同一个合并单元格)标记为已覆盖:coveredGrid[k][j] = true let k; for (k = i - 1; k >= 0; k--) { if (cellGrid[k][j] !== cellGrid[i][j]) break; coveredGrid[k][j] = true; } // 从当前单元格开始往上数,有几个单元格属于同一个合并单元格 const count = i - k; if (count > 1) { heighten($th, count); } } } }; // handsontable clone top 部分 const $thead = query(tableWrapper, '.ht_clone_top .wtHolder .htCore thead') as HTMLElement; grouping($thead, cellGrid.length, cellGrid[0].length); // handsontable clone top left corner 部分 const $topLeftHead = query(tableWrapper, '.ht_clone_top_left_corner .wtHolder .htCore thead') as HTMLElement; grouping($topLeftHead, cellGrid.length, fixedColumnsLeft); // 设置左上角的单元格合并为一个单元格 const $topLeftLastTr = Array.from(queryAll($topLeftHead, 'tr')).pop() as HTMLElement; const $topLeftLastTh = query($topLeftLastTr, 'th') as HTMLElement; heighten($topLeftLastTh, cellGrid.length); }; return { generateGroupHeaders, }; }