如何用纯JavaScript将含rowspan/colspan的复杂HTML表格转JSON?
解决方案:复杂HTML表格转指定格式JSON的纯JavaScript实现
核心思路
- 先区分表头行与数据行,分别解析两类行的单元格信息,包括文本内容、
rowspan和colspan属性 - 通过维护待填充队列,将跨行列的单元格内容自动填充到对应位置,生成完整的二维网格
- 为每个数据单元格匹配对应列的所有表头文本,用
/拼接成JSON键,最终生成目标格式的JSON
实现代码
function tableToJson(tableElement) { const rows = Array.from(tableElement.querySelectorAll('tr')); const headerRows = []; const dataRows = []; const result = {}; // 分离表头行和数据行 rows.forEach(row => { row.querySelector('th') ? headerRows.push(row) : dataRows.push(row); }); // 生成展开后的表头网格和数据网格 const headerGrid = buildFullGrid(headerRows, true); const dataGrid = buildFullGrid(dataRows, false); // 为每个数据单元格生成表头拼接键并组装JSON dataGrid.forEach((row, rowIdx) => { row.forEach((cellText, colIdx) => { if (!cellText || cellText.trim() === '') return; // 收集当前列的所有有效表头文本 const headerSegments = headerGrid .map(headerRow => headerRow[colIdx]?.trim()) .filter(Boolean); const key = headerSegments.join('/'); result[key] = cellText.trim(); }); }); return result; } // 处理rowspan/colspan,生成完整的二维单元格网格 function buildFullGrid(rows, isHeader) { const grid = []; // 存储待向下填充的跨行列单元格信息 const pendingCells = []; rows.forEach((row, rowIdx) => { const currentRow = []; let colIdx = 0; // 先处理从上一行遗留的待填充单元格 while (pendingCells.length > 0) { const pending = pendingCells[0]; if (pending.targetRow !== rowIdx || pending.targetCol > colIdx) break; currentRow[colIdx] = pending.content; pending.remainingRows--; pending.remainingCols--; if (pending.remainingRows <= 0 && pending.remainingCols <= 0) { pendingCells.shift(); } else if (pending.remainingCols <= 0) { pending.targetCol = colIdx + 1; pending.remainingCols = pending.originalColspan - 1; } colIdx++; } // 处理当前行的原始单元格 const cells = Array.from(row.querySelectorAll(isHeader ? 'th' : 'td')); cells.forEach(cell => { const content = cell.textContent.trim(); const rowspan = parseInt(cell.getAttribute('rowspan')) || 1; const colspan = parseInt(cell.getAttribute('colspan')) || 1; // 填充当前单元格占据的所有列 for (let c = 0; c < colspan; c++) { currentRow[colIdx + c] = content; } // 如果需要跨多行/列,添加到待填充队列 if (rowspan > 1 || colspan > 1) { pendingCells.push({ targetRow: rowIdx + 1, targetCol: colIdx, content, remainingRows: rowspan - 1, remainingCols: colspan - 1, originalColspan: colspan }); } colIdx += colspan; }); // 补全行内空缺的单元格,保证每行列数一致 while (colIndex < currentRow.length) { currentRow[colIdx] = ''; colIdx++; } grid.push(currentRow); }); // 统一所有行的列数,避免列数不一致的问题 const maxColCount = Math.max(...grid.map(row => row.length)); return grid.map(row => { while (row.length < maxColCount) row.push(''); return row; }); } // 使用示例 // const targetTable = document.querySelector('table'); // const jsonOutput = tableToJson(targetTable); // console.log(jsonOutput);
关键说明
- 网格构建逻辑:核心是
buildFullGrid函数,通过待填充队列自动处理跨行列的内容传播,将不规则的表格结构展开成规整的二维网格,解决rowspan/colspan的适配问题 - 表头拼接规则:每个数据单元格对应表头网格同一列的所有非空文本,用
/拼接成唯一键,完美匹配多级表头的需求 - 通用性:不依赖特定表格结构,只要是标准HTML表格标签(
<table>/<tr>/<th>/<td>),就能处理任意组合的跨行列场景
内容的提问来源于stack exchange,提问作者Lance Pollard
相关产品推荐
相关产品推荐

