使用PHP+TCPDF基于JSON数据生成员工年假排班计划表的实现咨询
年假排班规划器TCPDF实现方案
核心逻辑
- 提前将假期数据按用户ID分组,减少后续循环比对的性能消耗
- 逐行遍历员工、逐列遍历当月日期,判断当前日期是否落在员工的假期区间内,匹配则输出标记
完整可运行代码
<?php include('library/tcpdf.php'); // 实例化TCPDF,指定UTF-8编码避免中文乱码 $pdf = new TCPDF('P','mm','A4', true, 'UTF-8', false); $pdf->setPrintHeader(false); $pdf->setPrintFooter(false); $pdf->AddPage(); // -------------------------- 1. 读取并预处理数据 -------------------------- // 读取用户数据 $userFile = file_get_contents('MOCK_DATA-100.json'); $users = json_decode($userFile, true); // 读取假期数据,请替换为你的假期JSON文件路径 $leaveFile = file_get_contents('leave_events.json'); $leaves = json_decode($leaveFile, true); // 按用户ID分组假期数据,提前转换为时间戳方便后续比对 $userLeaveMap = []; foreach ($leaves as $leave) { $userId = $leave['resource']; // 仅取日期部分转换时间戳,忽略具体时分 $startTimestamp = strtotime(substr($leave['start'], 0, 10)); $endTimestamp = strtotime(substr($leave['end'], 0, 10)); if (!isset($userLeaveMap[$userId])) { $userLeaveMap[$userId] = []; } $userLeaveMap[$userId][] = [ 'start' => $startTimestamp, 'end' => $endTimestamp ]; } // -------------------------- 2. 处理月份参数 -------------------------- $month = date('m'); $year = date('Y'); if (isset($_GET['month'])) { $month = (int)$_GET['month']; } if (isset($_GET['year'])) { $year = (int)$_GET['year']; } $daysInMonth = cal_days_in_month(CAL_GREGORIAN, $month, $year); // -------------------------- 3. 生成排班表HTML -------------------------- $html = '<table border="1" cellpadding="2" cellspacing="0" width="100%">'; // 生成表头 $html .= '<tr>'; $html .= '<th width="18%">员工姓名</th>'; for ($day = 1; $day <= $daysInMonth; $day++) { $colWidth = (82 / $daysInMonth). '%'; $html .= "<th width=\"{$colWidth}\">{$day}</th>"; } $html .= '</tr>'; // 生成员工行 foreach ($users as $user) { $userId = $user['id']; $html .= '<tr>'; $html .= "<td>{$user['name']}</td>"; // 逐列遍历日期 for ($day = 1; $day <= $daysInMonth; $day++) { $currentTimestamp = strtotime("{$year}-{$month}-{$day}"); $mark = ''; // 比对当前日期是否在用户的假期区间内 if (isset($userLeaveMap[$userId])) { foreach ($userLeaveMap[$userId] as $leavePeriod) { if ($currentTimestamp >= $leavePeriod['start'] && $currentTimestamp <= $leavePeriod['end']) { $mark = 'X'; // 匹配到假期直接跳出循环,无需继续比对 break; } } } $html .= "<td align=\"center\">{$mark}</td>"; } $html .= '</tr>'; } $html .= '</table>'; // -------------------------- 4. 输出PDF -------------------------- $pdf->WriteHTMLCell(192,0,9,'',$html,0); $pdf->Output();
自定义调整说明
- 如果需要用背景色代替「X」标记,可将标记部分的代码替换为给td加背景样式:
<td align="center" style="background-color:#ffebee"> - 可根据实际需求调整表格的边框、内边距、列宽占比参数,适配A4纸打印需求
内容的提问来源于stack exchange,提问作者Fynn
相关产品推荐
相关产品推荐

