PHP遍历JSON数组生成HTML表格 同日期单元格值累加实现方案
PHP实现同日期工时累加的表格渲染方案
不需要全量重构现有代码,核心逻辑很简单:PHP是服务端逐行拼接输出HTML的,不存在“输出完成后再反向定位单元格修改值”的必要,只需要在输出单元格前先把同日期的工时做分组累加,再按表头的日期顺序输出对应值即可,你已经写好的静态<body>、<tbody>、表头生成、样式类名相关代码都可以完整保留。
第一步:补全有序日期列表
你现有代码已经在循环计算当月天数、周数,只需要在这个循环里顺手把当月所有日期按表头展示顺序存成数组,后续渲染单元格时直接按这个数组顺序输出,就能保证单元格和表头日期完全对齐:
// 在原有日期while循环前初始化数组 $monthDates = []; while ($date <= $endDate) { $weekNumber = intval(date("W", strtotime($date))); array_push($weekNumberList, $weekNumber); $date1 = new DateTime($date); // 新增:存储当前遍历到的标准格式日期 $currentDateStr = $date1->format('Y-m-d'); array_push($monthDates, $currentDateStr); $date=date('Y-m-d', strtotime($date . ' +1 day' )); $nextWeekNumber = intval($weekNumber) + 1; $wDayNumDayConcatenated .= '<th><p class="wday">' . strval($date1->format('D')) . '</p>' . '<p class="numday">' . strval(intval($date1->format('d'))) . '</p></th>'; }
第二步:员工数据预聚合
你现在的逻辑是直接遍历工时记录输出<td>,遇到同日期多条记录就会多生成多余单元格、数值也没做累加。这里只需要在渲染行之前,先把当前员工的所有工时按日期分组累加,生成「日期=>当日总工时」的映射数组:
foreach($echo2 as $item => $itemized){ $employeeName = $itemized['displayName']; echo '<tr>' . '<td>' . ($itemized['employeeNo']) . '<br>' . $employeeName . '</td>'; // 初始化当前员工的工时聚合容器 $dailyHours = []; $totalHours = 0; foreach($itemized['hours'] as $hoursEntry){ $entryDate = $hoursEntry['date']; $entryHour = floatval($hoursEntry['hour']); // 同日期值累加,无记录则初始化 if(!isset($dailyHours[$entryDate])){ $dailyHours[$entryDate] = 0; } $dailyHours[$entryDate] += $entryHour; $totalHours += $entryHour; }
第三步:按序输出单元格
拿到聚合后的工时数据后,按照第一步存的当月有序日期列表逐个输出单元格,当天无工时记录就填0,完全对齐表头结构:
// 按表头日期顺序输出每日工时单元格 foreach($monthDates as $cellDate){ $cellValue = isset($dailyHours[$cellDate]) ? $dailyHours[$cellDate] : 0; echo '<td>' . number_format($cellValue, 2) . '</td>'; } // 原有汇总列的嵌套表格结构完全保留,把硬编码的7.00替换为计算好的变量即可 echo '<td> <div id="container"> <table class="blueTable"> <tbody class="blueTable"> <tr class="blueTable"> <td class="iconsclass"> <i class="fa-solid fa-h"></i> </td> <td class="hoursclass">'. number_format($totalHours,2) .'</td> </tr> <tr class="blueTable"> <td class="iconsclass"> <i class="fa-solid fa-house-chimney"></i> </td> <td class="hoursclass">'. number_format($totalHours,2) .'</td> </tr> <tr> <td class="iconsclass"> <i class="fa-solid fa-table"></i> </td> <td class="hoursclass">'. number_format($totalHours,2) .'</td> </tr> <tr class="blueTable"> <td class="iconsclass"><i class="fa-solid fa-gears"></i> </td> <td class="hoursclass">'. number_format($totalHours,2) .' </td> </tr> <tr class="blueTable"> <td class="iconsclass">Total:</td> <td class="hoursclass">'. number_format($totalHours,2) .'</td> </tr> </tbody> </table> </div></td>'; echo '</tr>'; }
注意事项
- 你当前示例代码里表头起始日期写的是
2014-08-01,但JSON内的工时数据都是2022年1月的,运行前需要把$date初始值改成和工时数据匹配的月份1号,否则会因为日期不匹配全部显示0 - 全程不需要依赖MySQL查询、不需要引入前端JS做二次处理,所有累加逻辑都在服务端完成,没有额外性能开销
- 原有手动编写的表格结构、样式类、周数表头生成逻辑全部不需要改动,仅替换了原来直接遍历工时数组输出单元格的小段代码,不需要从零重构整个表格
内容的提问来源于stack exchange,提问作者apingaway
相关产品推荐
相关产品推荐

