PHP实现JSON转CSV 以键名为列头解决数据覆盖问题
PHP实现嵌套JSON转CSV(含字段拆分、嵌套扁平化)
原有代码的核心问题是没有提前统一做字段扁平化和全量列头收集,边遍历边输出的逻辑会导致列头缺失、行数据错位覆盖,以下是可直接运行的可靠实现:
实现逻辑
- 先遍历全量数据做扁平化处理,自动收集所有出现过的键名作为CSV列头,支持嵌套子字段提为顶层列
- 针对
Classification字段做逗号拆分,拆分为独立多列展示 - 表头仅写入一次,后续所有数据行严格按表头顺序对齐写入,从根源避免覆盖问题
- 内置空值处理、CSV转义、Excel乱码兼容
完整代码
<?php // 替换为你自己的JSON读取逻辑 $json_stream = file_get_contents('data.json'); $all_data = json_decode($json_stream, true); $contestants = $all_data['Contestants'] ?? []; if (empty($contestants)) { exit("无有效可导出数据"); } $flatRows = []; $headerCollect = []; foreach ($contestants as $person) { $row = []; // 处理顶层普通字段 foreach ($person as $key => $val) { if (in_array($key, ['Classification', 'Clubs'])) { continue; } $row[$key] = $val ?? ''; $headerCollect[$key] = true; } // 拆分Classification字段为多列,按实际分段数调整array_pad第二个参数即可 $classSegments = array_pad(explode(',', $person['Classification'] ?? ''), 3, ''); for ($i = 0; $i < count($classSegments); $i++) { $colName = 'Classification_' . ($i + 1); $row[$colName] = trim($classSegments[$i]); $headerCollect[$colName] = true; } // 处理嵌套的Clubs数组,兼容单人绑定多个俱乐部的场景 if (!empty($person['Clubs'])) { $clubCount = count($person['Clubs']); foreach ($person['Clubs'] as $idx => $club) { $suffix = $clubCount > 1 ? '_' . ($idx + 1) : ''; foreach ($club as $clubKey => $clubVal) { $colName = $clubKey . $suffix; $row[$colName] = $clubVal ?? ''; $headerCollect[$colName] = true; } } } $flatRows[] = $row; } // 整理最终表头顺序 $headers = array_keys($headerCollect); // 写入CSV文件 $fp = fopen('contestants_export.csv', 'w'); // 写入UTF-8 BOM,解决Excel打开乱码 fwrite($fp, chr(0xEF) . chr(0xBB) . chr(0xBF)); // 写入表头 fputcsv($fp, $headers); // 逐行写入数据,缺失列自动补空 foreach ($flatRows as $row) { $line = []; foreach ($headers as $col) { $line[] = $row[$col] ?? ''; } fputcsv($fp, $line); } fclose($fp); echo "CSV导出完成,文件保存为 contestants_export.csv"; ?>
注意事项
- 如果
Classification字段实际拆分后的段数不是3段,修改array_pad的第二个参数为实际段数即可 - 如果单个参赛人关联多个俱乐部,代码会自动给俱乐部相关列加序号后缀(比如
Clubname_1、Clubname_2),不会出现数据覆盖 - 采用PHP原生
fputcsv函数做写入,自动处理字段内含逗号、引号的转义问题,不会出现列错位 - 所有null值会自动转为空字符串,避免CSV格式错误
内容的提问来源于stack exchange,提问作者answerSeeker
相关产品推荐
相关产品推荐

