
本文详解如何通过 PHP 预处理数据 + HTML rowspan 属性,将相同“Name Product”的多行记录智能合并,使表格结构更清晰、专业,避免重复显示冗余产品名。
本文详解如何通过 php 预处理数据 + html `rowspan` 属性,将相同“name product”的多行记录智能合并,使表格结构更清晰、专业,避免重复显示冗余产品名。
在实际 Web 开发中,直接逐行输出数据库结果常导致表格视觉混乱——尤其是当同一产品(如 ADA)对应多个 Type(如 B112、B253、K23)时,若每行都重复显示 ADA,既浪费空间又降低可读性。理想的解决方案是:仅首行显示产品名,并用 rowspan 跨越后续同产品行数。
这要求我们摒弃“边查边输出”的惯性思维,转而采用 数据预处理 → 结构分析 → 模板渲染 的三步法,严格遵循“关注点分离”原则。
✅ 正确实现步骤
1. 查询并分组原始数据
使用 GROUP BY \Name Product`, `Type`确保每种产品-类型组合独立成行;同时用GROUP_CONCAT汇总关联的Code Unit`(便于后续按钮传参):
SELECT `Name Product`, `Type`, COUNT(*) AS `NoU`, GROUP_CONCAT(`Code Unit`) AS `Kodeunit` FROM `stock goods` GROUP BY `Name Product`, `Type` ORDER BY `Name Product`, `Type`;
2. PHP 预处理:构建带 rowspan 逻辑的数据结构
核心思想:遍历结果集,统计每个产品名连续出现的行数,并标记哪些行需留空(即非首行):
<?php $records = [];
$currentProduct = null;
$rowIndex = 0;
while ($row = mysqli_fetch_assoc($result)) {
$productName = $row["Name Product"];
// 检测产品名变更:新组开始
if ($productName !== $currentProduct) {
$currentProduct = $productName;
// 记录该产品首次出现的位置
$records[] = [
'product' => $productName,
'rows' => [],
'rowspan' => 0 // 占位,后续填充
];
$lastGroupIndex = count($records) - 1;
}
// 将当前行加入最新分组
$records[$lastGroupIndex]['rows'][] = [
'no' => ++$rowIndex,
'type' => $row["Type"],
'units' => $row["NoU"] . " Pcs",
'codes' => explode(',', $row["Kodeunit"])
];
}
// 补充 rowspan 值(每组行数)
foreach ($records as &$group) {
$group['rowspan'] = count($group['rows']);
}
?>
3. 渲染 HTML 表格(关键:精准控制 输出)利用 rowspan 合并产品名列,其余列正常输出:
No
Name Product
Type
Num of Units
Button Click
$row): ?>
= $globalNo++ ?>
= htmlspecialchars($group['product']) ?>
= htmlspecialchars($row['type']) ?>
= htmlspecialchars($row['units']) ?>
⚠️ 注意事项与最佳实践
-
安全第一:始终对输出内容调用
htmlspecialchars() 防止 XSS;用 json_encode() 处理 JS 参数,避免引号冲突。
-
rowspan 逻辑验证:确保
rowspan 值 ≥ 1,且不跨 或 边界。 -
空值处理:若某产品无
Type 数据,需提前过滤或提供默认占位符(如 "N/A")。
-
性能优化:大数据量时,考虑在 SQL 层用窗口函数(如
ROW_NUMBER() OVER (PARTITION BY ...))辅助分组,减少 PHP 内存压力。
通过以上结构化处理,你将得到高度整洁的表格:ADA 仅在首行显示并纵向跨越 3 行,DUZK 独立占据 2 行,Naro 单独成组——语义清晰、维护性强,真正实现“所见即所需”。
利用 rowspan 合并产品名列,其余列正常输出:
| No | Name Product | Type | Num of Units | Button Click |
|---|---|---|---|---|
| = $globalNo++ ?> | = htmlspecialchars($group['product']) ?> | = htmlspecialchars($row['type']) ?> | = htmlspecialchars($row['units']) ?> |
⚠️ 注意事项与最佳实践
-
安全第一:始终对输出内容调用
htmlspecialchars()防止 XSS;用json_encode()处理 JS 参数,避免引号冲突。 -
rowspan 逻辑验证:确保
rowspan值 ≥ 1,且不跨或边界。- 空值处理:若某产品无
Type数据,需提前过滤或提供默认占位符(如"N/A")。- 性能优化:大数据量时,考虑在 SQL 层用窗口函数(如
ROW_NUMBER() OVER (PARTITION BY ...))辅助分组,减少 PHP 内存压力。通过以上结构化处理,你将得到高度整洁的表格:
ADA仅在首行显示并纵向跨越 3 行,DUZK独立占据 2 行,Naro单独成组——语义清晰、维护性强,真正实现“所见即所需”。 - 空值处理:若某产品无
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











