我有一个特定格式的 CSV 数据集
key=value,key2=value,key3=value
key=value,key2=value,key4=value,key3=value
我想将其转换为
key,key2,key3,key4
value,value,value,null
value,value,value,value
但是输出 csv 中的数组不匹配
我已经尝试过下面的代码
if (($handle = fopen("sheet4.csv", "r")) !== FALSE) {
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
$cols = explode(",", $data[0]);
$num = count($cols);
for ($c = 0; $c < $num; $c++) {
$colData = explode("=", $cols[$c]);
$outputHeaders[$row][$colData[0]] = $colData[0];
$output[$row][$colData[0]] = $colData[1];
}
$csvOutput[$row] = array_combine($outputHeaders[$row], $output[$row]);
$row++;
}
fclose($handle);
}
foreach ($csvOutput as $row => $rowData) {
$extractHeaders[] = array_keys($rowData);
}
$mergedHeaders = array_unique(call_user_func_array('array_merge', $extractHeaders));
$fp = fopen('sheet4out.csv', 'wa');
fputcsv($fp, $mergedHeaders);
foreach ($csvOutput as $key => $fields) {
$rowKeys = array_keys($fields);
if (count($mergedHeaders) == count($rowKeys)) {
} else {
$differntKeys = array_diff($mergedHeaders, $rowKeys);
$fields = array_merge($fields, array_fill_keys($differntKeys, 'banana'));
}
fputcsv($fp, $fields);
}
你不应该打电话给
explode(',', $data[0])
。 fgetcsv()
已经分解了该行,因此 $data[0]
只是第一个字段。
在读取输入 CSV 时,只需将每个字段名称添加到 headers 数组中即可。您可以通过在每行之后调用
array_unique()
来保持较小的值。
创建输出行时,您可以使用空合并运算符提供
null
作为行中缺失键的默认值。
$headers = [];
$rows = [];
if ($handle = fopen("sheet4.csv", "r")) {
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
$row = [];
foreach ($data as $field) {
[$key, $value] = explode('=', $field);
$row[$key] = $value;
}
$headers = array_unique(array_merge($headers, array_keys($row)));
$rows[] = $row;
}
fclose($handle);
}
array_sort($headers);
if ($fp = fopen('sheet4out.csv', 'w')) {
fputcsv($fp, $headers);
foreach ($rows as $row) {
$outrow = array_map(fn($field) => $row[$field] ?? 'null', $headers)
fputcsv($fp, $outrow);
}
}