PHP生成CSV文件时如何正确分隔表头与列数据
问题原因
CSV内容全部挤在同一单元格,核心是两个问题:
- PHP内置
fputcsv函数默认使用半角逗号作为字段分隔符,但简体中文环境下的Windows Excel默认使用半角分号;作为CSV列分隔符,分隔规则不匹配导致Excel无法识别分栏位置。 - 代码存在逻辑位置错误:
fpassthru($f)被错误写在数据遍历的while循环内部,会导致文件指针提前偏移、写入内容错乱。
实际运行效果

预期实现效果

修正方案
两种方案可按需选择:
方案1:修改代码适配Excel默认规则(推荐)
调用fputcsv时显式指定分号作为分隔符,同时修正循环内的逻辑错误,把文件输出、关闭操作移到循环外部,额外补充BOM头解决中文乱码问题。
修正后的完整可运行代码:
<?php // 加载数据库配置文件 require_once('db/connect_db.php'); $dteTimetamp = date('Y-m-d'); // 从数据库查询数据 $find = $conn->prepare("SELECT School, SchoolAddress, School_Email, Principle_Name, Reception_Number, QuantityFingerPrintScanner, InvoiceNumber from School"); $find->execute(); $udonr = "$dteTimetamp" . "Request"; // 创建文件指针 $f = fopen(dirname(__FILE__).'/testfolder/'.$udonr.'.csv', 'w'); // 写入UTF-8 BOM头,解决Excel打开中文乱码问题 fwrite($f, chr(0xEF).chr(0xBB).chr(0xBF)); // 设置表头 $header = array('School Name', 'Contact Person', 'Contact Number', 'School Address', 'Number of scanners to deliver', 'Invoice Nuber'); // 显式指定分隔符为分号,适配Windows Excel默认识别规则 fputcsv($f, $header, ';'); // 遍历数据逐行写入CSV while($row = $find->fetch(PDO::FETCH_ASSOC)){ $lineData = array( $row['School'], $row['Principle_Name'], $row['Reception_Number'], $row['SchoolAddress'], $row['QuantityFingerPrintScanner'], $row['InvoiceNumber'] ); fputcsv($f, $lineData, ';'); } // 如果需要触发浏览器下载文件,取消下面几行的注释即可 // header('Content-Type: text/csv'); // header('Content-Disposition: attachment; filename="' . $udonr.'.csv' . '";'); // rewind($f); // fpassthru($f); // 关闭文件指针 fclose($f);
方案2:不修改代码,手动指定Excel导入规则
如果不想调整代码分隔符,可以在打开CSV时手动指定识别规则:
- 打开Excel,点击「数据」选项卡,选择「自文本/CSV」
- 选中生成的CSV文件,在导入配置页将分隔符设置为「逗号」
- 确认导入即可自动完成分栏。
额外注意事项
- 写入UTF-8编码的CSV必须在文件开头加BOM头,否则Excel打开会出现中文乱码
- 文件操作类函数(
fpassthru/fclose等)不要写在数据遍历循环内部,否则会导致文件提前终止写入、内容缺失 - 现有SQL查询了
School_Email字段,但表头和写入逻辑都没有用到该字段,不需要的话可以从SQL语句中删除,减少无效查询。
内容的提问来源于stack exchange,提问作者CharlieT
相关产品推荐
相关产品推荐

