fputcsv()是php导出csv最稳方案,自动处理逗号、换行、引号转义;需用二维索引数组,写入前加bom头(\xef\xbb\xbf)防中文乱码,禁用手动拼接字符串。

导出 CSV 时 array 直接用 fputcsv() 最稳
PHP 数组导出为 Excel 可读格式,最常用也最可靠的是 CSV。别自己拼字符串,fputcsv() 专为此设计,自动处理逗号、换行、引号转义。
常见错误是手动 implode() + str_replace(),结果遇到含逗号的地址、带换行的备注就崩——CSV 格式要求字段含特殊字符时必须加双引号包裹,fputcsv() 自动判断并处理。
- 确保数组是「二维索引数组」,每项是「一维索引数组」,例如:
[["张三", "北京", "25"], ["李四", "上海\n浦东", "30"]] - 打开文件用
fopen($filename, 'w'),注意权限和路径可写;导出完记得fclose() - 如需 UTF-8 编码(中文不乱码),在写入前加 BOM 头:
fputs($fp, "\xEF\xBB\xBF"); - 字段含中文但 Excel 打开仍是乱码?不是编码问题,是 Excel 默认用系统编码读 CSV——加 BOM 是唯一通用解法
要导出 Excel(.xlsx)就得用 phpspreadsheet
原生 PHP 不支持生成 .xlsx 文件。phpspreadsheet 是当前事实标准,Composer 安装后就能把 array 映射成单元格。
性能上,千行以内没问题;万行以上建议分批写入或改用 CSV;内存占用比 CSV 高得多,大数组容易 Fatal error: Allowed memory size exhausted。
- 安装:
composer require phpoffice/phpspreadsheet - 核心写法:用
$sheet->fromArray($data),其中$data是二维关联或索引数组 - 如果数组是关联的(如
['name' => '张三', 'age' => 25]),先用array_values()提取值,或手动指定列名再循环写入 - 导出前务必设响应头:
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');和Content-Disposition
json_encode() 导出只适合前端解析,不是「导出文件」
有人把 array 用 json_encode() 输出当导出,这是误解。浏览器收到 JSON 响应,只是显示一串文本,不会触发下载,也不被 Excel 识别。
真要给前端提供数据让其自行导出(比如用 SheetJS),那可以返回 JSON,但服务端不负责生成文件;若用户点「导出 Excel」按钮却只返回 JSON,体验就断了。
- 返回 JSON 的典型场景:前后端分离项目,前端调 API 拿到
array后用XLSX.write()生成 blob 下载 - 服务端直接导出文件,就必须生成二进制内容(.xlsx)或纯文本(.csv),不能只吐 JSON 字符串
- 调试时误用
echo json_encode($arr)看结构?可以;但上线时把它当导出逻辑,必出问题
关联数组导出 CSV 时列顺序容易错
PHP 关联数组本身无序,fputcsv() 只认索引顺序。如果原始数据是 ['email' => 'a@b.com', 'name' => '张三'],直接传进去,列会变成 email 在前、name 在后——但你可能想要 name 在前。
解决办法不是靠 ksort(),而是显式定义列名顺序,再按顺序提取值:
$columns = ['name', 'email', 'phone'];
foreach ($data as $row) {
fputcsv($fp, array_map(fn($k) => $row[$k] ?? '', $columns));
}
漏掉 ?? '' 会导致键不存在时报 notice;用 array_key_exists() 判断也可以,但更啰嗦。这个步骤看似多一步,实则避免导出文件列错位、业务方反复找你确认字段含义。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











