You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JS+HTML创建跨单元格矩阵表格:解决溢出与Pareto列显示问题

问题修正:带跨单元格的矩阵表格内容溢出与Pareto列分行显示

问题1:表格右侧内容溢出

通过CSS设置单元格文本自动换行,配合固定表格布局,确保内容自适应容器宽度,避免超出边界。

问题2:Pareto列数据分行显示

原代码将同一Process+DATE下的Pareto值合并为逗号分隔字符串,现改为根据实际数据条目数动态生成行,同时调整跨单元格(rowspan)的数量,让每个Pareto值单独占一行。

修正后的完整代码

HTML/JavaScript

var data = [{
    Process: 'PCAL',
    DATE: '29 Nov 2023',
    FPY: '0.0',
    QTY: '1',
    RTY: '0.0',
    Pareto: 'Client BER META 1 Serdes 142',
    Fail: '1'
  },
  {
    Process: 'CAL',
    DATE: '28 Nov 2023',
    FPY: '100.0',
    QTY: '2',
    RTY: '100.0',
    Pareto: 'None',
    Fail: 'None'
  },
  {
    Process: 'FVT',
    DATE: '28 Nov 2023',
    FPY: '50.0',
    QTY: '2',
    RTY: '50.0',
    Pareto: 'Client BER Lane 12',
    Fail: '3'
  },
  {
    Process: 'FVT',
    DATE: '28 Nov 2023',
    FPY: '50.0',
    QTY: '2',
    RTY: '50.0',
    Pareto: 'Client BER',
    Fail: '1'
  },
  {
    Process: 'ESS',
    DATE: '28 Nov 2023',
    FPY: '100.0',
    QTY: '1',
    RTY: '100.0',
    Pareto: 'None',
    Fail: 'None'
  },
  {
    Process: 'ESS',
    DATE: '29 Nov 2023',
    FPY: '0.0',
    QTY: '1',
    RTY: '0.0',
    Pareto: 'Module Power',
    Fail: '4'
  },
  {
    Process: 'ESS',
    DATE: '29 Nov 2023',
    FPY: '0.0',
    QTY: '1',
    RTY: '0.0',
    Pareto: 'Module A Power',
    Fail: '14'
  },
  {
    Process: 'EXS',
    DATE: '30 Nov 2023',
    FPY: '100.0',
    QTY: '3',
    RTY: '100.0',
    Pareto: 'None',
    Fail: 'None'
  }
];

// 提取并排序唯一日期
var uniqueDates = [...new Set(data.map(item => item.DATE))].sort();

// 预计算每个Process对应的最大行数(各日期下的条目数最大值)
var processRowCounts = {};
var uniqueProcesses = [...new Set(data.map(item => item.Process))];
uniqueProcesses.forEach(process => {
  var maxRows = 0;
  uniqueDates.forEach(date => {
    var count = data.filter(item => item.Process === process && item.DATE === date).length;
    if (count > maxRows) maxRows = count;
  });
  processRowCounts[process] = maxRows || 1; // 至少保留1行
});

// 创建表格
document.write('<table>');
document.write('<tr><th rowspan="2">Process</th>');

// 日期表头
uniqueDates.forEach(date => {
  document.write(`<th colspan="5">${date}</th>`);
});
document.write('</tr>');

// 子列表头
document.write('<tr>');
uniqueDates.forEach(() => {
  document.write('<th>Qty</th><th>FPY</th><th>RTY</th><th>Pareto</th><th>Fail</th>');
});
document.write('</tr>');

// 填充数据
uniqueProcesses.forEach(process => {
  const totalRows = processRowCounts[process];
  // 第一行:Process跨totalRows行,各日期的基础数据跨对应行数
  document.write(`<tr><td rowspan="${totalRows}">${process}</td>`);
  
  // 存储每个日期下的数据,方便后续行填充
  const dateDataMap = {};
  uniqueDates.forEach(date => {
    const rowData = data.filter(item => item.Process === process && item.DATE === date);
    dateDataMap[date] = rowData;
    const rowCount = rowData.length;
    
    if (rowCount > 0) {
      // QTY/FPY/RTY跨当前日期的条目数
      document.write(`
        <td rowspan="${rowCount}">${rowData[0].QTY}</td>
        <td rowspan="${rowCount}">${rowData[0].FPY}</td>
        <td rowspan="${rowCount}">${rowData[0].RTY}</td>
        <td>${rowData[0].Pareto}</td>
        <td>${rowData[0].Fail}</td>
      `);
    } else {
      // 无数据时跨Process的总行数
      document.write(`
        <td rowspan="${totalRows}"></td>
        <td rowspan="${totalRows}"></td>
        <td rowspan="${totalRows}"></td>
        <td></td>
        <td></td>
      `);
    }
  });
  document.write('</tr>');
  
  // 后续行:填充剩余的Pareto和Fail值
  for (let rowIdx = 1; rowIdx < totalRows; rowIdx++) {
    document.write('<tr>');
    uniqueDates.forEach(date => {
      const rowData = dateDataMap[date];
      if (rowData && rowData[rowIdx]) {
        document.write('<td></td><td></td><td></td>'); // QTY/FPY/RTY已跨行,留空
        document.write(`<td>${rowData[rowIdx].Pareto}</td>`);
        document.write(`<td>${rowData[rowIdx].Fail}</td>`);
      } else {
        // 无数据或超出当前日期条目数,填充空单元格
        document.write('<td></td><td></td><td></td><td></td><td></td>');
      }
    });
    document.write('</tr>');
  }
});

document.write('</table>');

CSS

table {
  border-collapse: collapse;
  width: 100%;
  table-layout: fixed; /* 固定布局,防止列宽失衡 */
}

table, th, td {
  border: 1px solid black;
}

th, td {
  padding: 10px;
  text-align: left;
  word-break: break-word; /* 长文本自动换行 */
  overflow-wrap: break-word;
}

th {
  background-color: #f0f0f0; /* 表头背景色,可选优化 */
}

关键修改说明

  1. 修复表头错误:原代码第一列表头误写为DATE,修正为Process,匹配数据逻辑。
  2. 动态跨行计算:不再固定设置rowspan=5,而是根据每个Process下各日期的实际数据量,动态计算跨行行数,确保内容完全显示。
  3. Pareto分行处理:遍历Process的后续行,逐个填充剩余的Pareto和Fail值,避免合并为逗号分隔字符串。
  4. 解决内容溢出:通过word-break: break-word实现长文本自动换行,table-layout: fixed保证表格布局稳定,防止超出容器宽度。

内容的提问来源于stack exchange,提问作者EAF

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 06:00:04