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

PHP fputcsv导出CSV时数据全部显示在单列的问题及解决方法

PHP动态表CSV导出列拆分异常修复

问题背景

应用开发过程中会生成大量动态数据表,需要将这些动态表的列数据导出为.csv格式文件。

初始实现方案与故障排查

最初的实现逻辑如下:

  • 编写PDO预处理语句查询目标数据,以PDO::FETCH_OBJ模式获取全部结果集
  • 对结果集执行json_encode编码再json_decode解码,遍历解码后的数据提取CSV表头
  • 将每行数据的字段值通过implode拼接为逗号分隔字符串,封装为单元素数组存入$csvData数组
  • 通过fputcsv依次写入表头和每行数据到内存文件流,输出为CSV下载

该方案导出的CSV文件存在明显异常:所有行的全部数据都仅显示在第一列,未按字段拆分到对应列。
打印$csvHeader和$csvData数组后定位到问题根源:每行数据被提前拼接为单个字符串传入fputcsv,函数会将整个字符串识别为单个单元格内容,因此无法实现按列拆分。同时原逻辑做了大量冗余的JSON编解码、字符串拼接操作,执行效率低。

修正方案

调整实现逻辑,去掉冗余操作:执行查询后先取一行PDO::FETCH_ASSOC格式的结果,提取其键名作为CSV表头字段,再获取全部PDO::FETCH_ASSOC格式的结果集,逐行直接将字段数组传入fputcsv写入,最终实现数据按列正常拆分导出。

错误实现代码

$secondsql = "SELECT * FROM ".$reslt->dname." WHERE userid=:userid AND eventid=:eventid";
$querysec = $dbh -> prepare($secondsql); 
$querysec-> bindParam(':userid', $usrid, PDO::PARAM_STR);  
$querysec-> bindParam(':eventid', $exporteventid, PDO::PARAM_STR);                                     
$querysec-> execute();
$ressec = $querysec -> fetchAll(PDO::FETCH_OBJ);

$jsonString = json_encode($ressec);
$jsonDecoded = json_decode($jsonString, true);
$keys = array_keys(json_decode($jsonString, true));
$csvHeader=array();
$csvData=array();
foreach($jsonDecoded as $key => $val) {
    if (!$val) {
    }else{
        if(!$csvHeader){
            $csvHeader = array_keys($val);
        }
   }
}
$kcnt = count($csvHeader);
$tempstring = "";
foreach($jsonDecoded as $val2) {
    $arrvals = array_values($val2);
    $resultStringValues = implode(",", $arrvals);
    $temparray=array();
    array_push($temparray,$resultStringValues);
    array_push($csvData,$temparray);
}
$tempstring = rtrim($tempstring, ",");
$delimiter = ","; 
$filename = $reslt->eventname. date('Y-m-d') . ".csv"; 
$f = fopen('php://memory', 'w'); 
fputcsv($f, $csvHeader, $delimiter);
foreach($csvData as $fields){
    fputcsv($f,$fields,$delimiter);
}
fseek($f, 0); 
header('Content-Type: text/csv'); 
header('Content-Disposition: attachment; filename="' . $filename . '";');
fpassthru($f); 

错误逻辑下的数组结构

  • $csvHeader:包含id、eventid、userid、fullname、email、mobile、reg_date的索引数组
  • $csvData:二维数组,每个子数组仅包含1个逗号拼接的完整行数据字符串元素

正确实现代码

$secondsql = "SELECT * FROM ".$reslt->dname." WHERE userid=:userid AND eventid=:eventid";
$querysec = $dbh -> prepare($secondsql); 
$querysec-> bindParam(':userid', $usrid, PDO::PARAM_STR);  
$querysec-> bindParam(':eventid', $exporteventid, PDO::PARAM_STR);                                     
$querysec-> execute();
$table_fields = array_keys($querysec->fetch(PDO::FETCH_ASSOC));
$ressec = $querysec -> fetchAll(PDO::FETCH_ASSOC);
$delimiter = ","; 
$filename = $reslt->eventname. date('Y-m-d') . ".csv"; 
$f = fopen('php://memory', 'w'); 
fputcsv($f, $table_fields, $delimiter);
foreach($ressec as $fields){
    fputcsv($f,$fields,$delimiter);
}
fseek($f, 0); 
header('Content-Type: text/csv'); 
header('Content-Disposition: attachment; filename="' . $filename . '";'); 
fpassthru($f);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 07:54:32