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

使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 07:48:04