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

使用PhpSpreadsheet导入Excel到MySQL时补全缺失日期的实现问题

解决方案

实现逻辑如下:

  • 先收集Excel中已存在的所有日期,存入去重数组方便快速校验
  • 动态获取导入数据覆盖的月份起止范围,遍历该范围内的每一天
  • 判定当日为周日且不存在于已存在日期集合时,插入自定义的补全数据
  • 原有Excel数据的入库逻辑保持不变

修改后可直接运行的完整代码:

$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx();
$spreadsheet = $reader->load("uploads/temp.xlsx");
$worksheet = $spreadsheet->getActiveSheet();
$spreadSheetAry = $worksheet->toArray();
$sheetCount = count($spreadSheetAry);

$sql = "INSERT INTO tbl_tour (user_email,date,day,school_name,visit_status,reason) VALUES (?,?,?,?,?,?)";
$stmt=$mysqli->prepare($sql);

// 第一步:收集Excel中已存在的所有日期,同时处理原有数据入库
$existingDates = [];
// 原代码循环条件<=存在数组越界风险,已调整为<
for ($i = 1; $i < $sheetCount; $i ++) {
    $date ="";
    $day ="";
    $school_name ="";
    $visit_status = "";
    $reason = "";
    if (isset($spreadSheetAry[$i][1])) {
        $date = $spreadSheetAry[$i][1];
        // 存入已存在日期集合,自动去重
        if (!in_array($date, $existingDates)) {
            $existingDates[] = $date;
        }
    }
    if (isset($spreadSheetAry[$i][2])) {
        $day = $spreadSheetAry[$i][2];
    }
    if (isset($spreadSheetAry[$i][3])) {
        $school_name = $spreadSheetAry[$i][3];
    }
    if (isset($spreadSheetAry[$i][4])) {
        $visit_status = $spreadSheetAry[$i][4];
    }
    if (isset($spreadSheetAry[$i][5])) {
        $reason = $spreadSheetAry[$i][5];
    }

    $stmt->bind_param('ssssss',$email,$date,$day,$school_name,$visit_status,$reason);
    $stmt->execute();
}

// 第二步:补全缺失的周日数据
if (!empty($existingDates)) {
    // 从现有日期中获取月份范围
    $firstDate = DateTime::createFromFormat('d-m-Y', min($existingDates));
    $lastDate = DateTime::createFromFormat('d-m-Y', max($existingDates));
    // 重置到当月第一天和最后一天,覆盖整月所有日期
    $firstDate->modify('first day of this month');
    $lastDate->modify('last day of this month');

    $currentDate = clone $firstDate;
    while ($currentDate <= $lastDate) {
        $formattedDate = $currentDate->format('d-m-Y');
        // format('w')返回0代表周日
        if ($currentDate->format('w') == 0 && !in_array($formattedDate, $existingDates)) {
            // 以下补全字段内容可按需自行修改
            $fillDay = $currentDate->format('l');
            $fillSchool = '';
            $fillStatus = '公休';
            $fillReason = '周日休息';
            $stmt->bind_param('ssssss',$email,$formattedDate,$fillDay,$fillSchool,$fillStatus,$fillReason);
            $stmt->execute();
        }
        $currentDate->modify('+1 day');
    }
}

$stmt->close();

补充说明

  • 补全的字段值可以根据业务需求随意调整,包括day字段的输出格式、visit_status和reason的自定义内容
  • 如果需要固定处理指定月份,可直接手动赋值$firstDate和$lastDate,不需要从已有日期动态获取
  • 如果每个周日需要插入2条和其他日期格式一致的重复数据,在补全逻辑中重复执行一次bind_param和execute即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 04:30:01