如何创建新数组存储phpspreadsheet中日期无效的ActivityStartDate数据
如何用PhpSpreadsheet验证Excel日期格式并分流数据?
问题描述
我用PhpSpreadsheet读取Excel数据,想通过foreach循环检查ActivityStartDate(对应Excel的A列)的日期格式是否合法。需求是:把格式无效的数据存入新数组用于展示,格式有效的数据导入数据库。目前我写了部分代码:
foreach ($data_arr as $row) { $ActivityStartDate = $row["A"]; $ActivityEndDate = $row["B"]; $date = $excelService-> excel_to_php_timestamp($ActivityStartDate); $ActivityStartDate = date("d/m,Y", $date);
请教怎么完成整个流程?
完整实现方案
1. 初始化分流数组
在循环外部先定义两个数组,分别存储有效数据和无效数据,方便后续处理:
$validData = []; // 用于存储可导入数据库的合法数据 $invalidData = []; // 用于存储日期格式错误的数据,方便展示
2. 完善循环内的日期验证逻辑
在循环中加入日期有效性判断,根据验证结果将数据分流。这里分两种情况处理:
情况1:依赖你的excel_to_php_timestamp方法
如果该方法在输入非法日期时返回false或无效值,可以直接基于返回值判断:
foreach ($data_arr as $rowIndex => $row) { $rawStartDate = $row["A"]; $rawEndDate = $row["B"]; $isValid = true; $formattedStartDate = ''; $formattedEndDate = ''; // 验证ActivityStartDate $startTimestamp = $excelService->excel_to_php_timestamp($rawStartDate); if ($startTimestamp === false || !date("d/m,Y", $startTimestamp)) { $isValid = false; } else { $formattedStartDate = date("d/m,Y", $startTimestamp); } // 可选:同时验证ActivityEndDate $endTimestamp = $excelService->excel_to_php_timestamp($rawEndDate); if ($endTimestamp === false || !date("d/m,Y", $endTimestamp)) { $isValid = false; } else { $formattedEndDate = date("d/m,Y", $endTimestamp); } // 数据分流 if ($isValid) { $validData[] = [ 'ActivityStartDate' => $formattedStartDate, 'ActivityEndDate' => $formattedEndDate // 补充其他需要导入数据库的字段 ]; } else { $invalidData[] = [ 'row' => $rowIndex + 1, // 记录Excel行号(从1开始) 'rawStartDate' => $rawStartDate, 'rawEndDate' => $rawEndDate, 'error' => '日期格式不符合要求' ]; } }
情况2:直接用DateTime类精确验证字符串日期
如果你的Excel日期是字符串格式(如dd/mm/yyyy),建议用DateTime类做精确格式验证,避免非法日期(如32/13/2024)被误判:
foreach ($data_arr as $rowIndex => $row) { $rawStartDate = $row["A"]; $rawEndDate = $row["B"]; $isValid = true; $formattedStartDate = ''; $formattedEndDate = ''; // 验证ActivityStartDate try { $startDate = DateTime::createFromFormat('d/m/Y', $rawStartDate); if (!$startDate || $startDate->format('d/m/Y') !== $rawStartDate) { $isValid = false; } else { $formattedStartDate = $startDate->format('d/m/Y'); } } catch (Exception $e) { $isValid = false; } // 可选:验证ActivityEndDate try { $endDate = DateTime::createFromFormat('d/m/Y', $rawEndDate); if (!$endDate || $endDate->format('d/m/Y') !== $rawEndDate) { $isValid = false; } else { $formattedEndDate = $endDate->format('d/m/Y'); } } catch (Exception $e) { $isValid = false; } // 数据分流逻辑同情况1 if ($isValid) { $validData[] = [ 'ActivityStartDate' => $formattedStartDate, 'ActivityEndDate' => $formattedEndDate ]; } else { $invalidData[] = [ 'row' => $rowIndex + 1, 'rawStartDate' => $rawStartDate, 'rawEndDate' => $rawEndDate, 'error' => '日期格式不符合dd/mm/yyyy要求' ]; } }
3. 有效数据导入数据库
拿到$validData后,用预处理语句批量或逐个导入数据库(以PDO为例):
// 假设已建立PDO连接$pdo if (!empty($validData)) { $stmt = $pdo->prepare("INSERT INTO your_table (ActivityStartDate, ActivityEndDate) VALUES (:start, :end)"); foreach ($validData as $data) { $stmt->execute([ ':start' => $data['ActivityStartDate'], ':end' => $data['ActivityEndDate'] ]); } }
4. 无效数据展示
$invalidData中存储了所有错误行的信息,你可以将其渲染成HTML表格、JSON或其他格式展示给用户:
if (!empty($invalidData)) { echo "<h3>无效数据列表</h3>"; echo "<table border='1' cellpadding='8'>"; echo "<tr><th>行号</th><th>原始开始日期</th><th>原始结束日期</th><th>错误信息</th></tr>"; foreach ($invalidData as $invalid) { echo "<tr>"; echo "<td>{$invalid['row']}</td>"; echo "<td>{$invalid['rawStartDate']}</td>"; echo "<td>{$invalid['rawEndDate']}</td>"; echo "<td>{$invalid['error']}</td>"; echo "</tr>"; } echo "</table>"; }
内容的提问来源于stack exchange,提问作者JC0203
相关产品推荐
相关产品推荐

