
使用 phpspreadsheet 库遍历指定目录下的所有 .xlsx 文件,逐行提取 a 列(name)和 b 列(price)数据,统一存入一个扁平化的一维关联数组,避免嵌套导致的重复计数或索引错乱。
在 PHP 中批量处理 Excel 文件时,一个常见误区是将每个文件的数据存为子数组(如 $myarr[] = $array),这会导致最终结果为二维结构(如 [[row1, row2], [row3, row4], ...]),不仅增加后续处理复杂度,还可能因 $array 变量未重置而引发数据叠加——正如你遇到的“500–600 条实际数据却得到 1200 条”的问题:内层循环反复向同一个 $array 写入,且每次外层循环都将其整体追加进 $myarr,造成重复累积。
正确做法是跳过中间临时数组,直接将每行解析结果推入顶层 $myarr。以下是优化后的完整实现:
setReadDataOnly(true); // 仅读取值,忽略样式/公式
try {
$spreadsheet = $reader->load($file);
$worksheet = $spreadsheet->getSheet(0); // 默认读取第一个工作表
$highestRow = $worksheet->getHighestRow();
// 从第2行开始读取(假设第1行为标题)
for ($row = 2; $row <= $highestRow; $row++) {
$name = $worksheet->getCell('A' . $row)->getValue() ?: '';
$price = $worksheet->getCell('B' . $row)->getValue() ?: '';
// 直接追加关联数组元素(非嵌套!)
$myarr[] = [
'name' => trim((string)$name),
'price' => is_numeric($price) ? (float)$price : 0.0
];
}
} catch (Exception $e) {
error_log("Failed to read {$file}: " . $e->getMessage());
continue;
}
}
// 输出验证(生产环境建议用 json_encode 或分页处理)
echo '';
print_r($myarr);
echo '
';
?>✅ 关键改进点说明:
- 取消 $array 中间变量:避免因作用域不清或未重置导致的数据污染;
- 直接操作 $myarr[]:确保所有行数据线性追加,最终得到纯净的一维数组(共 N 条记录);
- 使用 getCell() 替代 getCellCollection():更直观、性能更好,且避免 getCellCollection() 在空单元格时返回 null 引发的潜在警告;
- 增加异常捕获:单个文件损坏不影响整体流程;
- 类型安全处理:对 name 强制转字符串并去空格,对 price 做数值校验与默认值兜底。
⚠️ 注意事项:
- 确保 prices/ 目录存在且 PHP 进程有读取权限;
- 若 Excel 表头不在第1行或数据列非 A/B,请同步调整 $row 起始值及单元格坐标;
- 大量文件(如 >100 个)或超大表格(>10k 行)时,建议启用 readFilter 或改用流式读取(Xlsx::readFilter)以降低内存占用;
- 生产环境请勿直接 print_r 敏感数据,应结合日志、API 响应或数据库持久化处理。
至此,你将获得一个结构统一、无冗余、可直接用于导出、统计或 API 返回的标准 PHP 关联数组。










