thinkphp大数据导出必须用cursor()+fputcsv()并加utf-8 bom头;禁用db::select()和fromarray()防内存溢出;中文文件名需rawurlencode();响应头缺charset或cache-control会导致乱码或下载失败。

ThinkPHP 后台数据导出不能靠“查完再塞给 Excel 库”就完事——5000 行以上大概率内存爆掉、中文显示方块、日期变数字、下载失败或乱码,都是因为没踩对关键动作节点。
大数据量导出 CSV 为什么必须用 cursor() + fputcsv()
直接 Db::select() 查 10 万行,PHP 进程内存瞬间吃满;而 cursor() 是游标查询,数据库逐行返回,PHP 内存始终只 hold 一行。搭配原生 fputcsv() 直写 php://output,不经过框架中间层,字段顺序、空值、逗号/换行转义全由函数自动处理,稳定又快。
- 表头中文乱码?开头必须
echo "\xEF\xBB\xBF";写 BOM 头 - 导出文件开头有空白或 HTML?导出前加
ob_end_clean(); - 字段含关联模型或获取器?先
toArray(),再用hidden()/append()过滤或补充 - 别用 ThinkPHP 封装的
exportCsv()方法——BOM、编码、缓冲区控制都不透明,出问题难定位
导出 Excel 必须避开 fromArray() 的三个原因
fromArray() 看起来省事,但它是把整个二维数组加载进 PhpSpreadsheet 内存,每个单元格都生成对象,5000 行起步就卡死。真实生产环境必须手动控制写入节奏。
- 用
setCellValueByColumnAndRow($col, $row, $value)替代setCellValue("A{$row}", $value),避免字符串解析开销 - 每写 1000 行调一次
gc_collect_cycles(),否则 PHP 垃圾回收不及时,内存只增不减 - 日期、金额等字段不能先
$row['created_at']->format('Y-m-d')再写入——Excel 会当纯文本,失去排序和公式能力;得用setValueExplicit($timestamp, DataType::TYPE_NUMERIC)+setFormatCode(NumberFormat::FORMAT_DATE_YYYYMMDD2)
中文显示为方块或 #VALUE! 怎么快速定位
不是字体文件没上传,也不是服务器缺字体,而是设置位置错了:必须设在 getDefaultStyle() 上,且响应头 Content-Type 必须带 charset=utf-8。
- 错:只给某列设字体 → 新插入行仍用默认 Arial,中文变方块
- 对:
$spreadsheet->getDefaultStyle()->getFont()->setName('SimSun');(Windows)或'Microsoft YaHei'(跨平台更稳) - 文件名含中文?
header('Content-Disposition: attachment; filename="'.rawurlencode('用户报表.xlsx').'";'); - Linux 服务器上测试正常但线上乱码?确认系统已安装对应中文字体,或改用
stsongstdlight(TCPDF 风格,兼容性更强)
导出接口响应头漏一项就会失败
浏览器对附件下载响应极其敏感,少一个头或格式不对,可能触发下载中断、缓存旧文件、甚至被安全策略拦截。
-
Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; charset=utf-8—— 缺charset=utf-8,Excel 打开列头就是方块 -
Content-Disposition: attachment; filename="data.xlsx"—— 中文名不rawurlencode(),Chrome 下载后文件名损坏 -
Cache-Control: max-age=0—— 不加这个,Nginx 或 CDN 可能缓存上次导出内容,用户下载到的是旧数据 - 导出前不能有任何
echo、var_dump或日志输出,否则响应体开头混入字符,Excel 打开报“文件格式错误”
真正卡住人的从来不是“怎么写”,而是「什么时候查数据」「什么时候设字体」「哪一行该触发 gc」——这些节点一旦错位,导出就变成玄学调试。尤其注意:模型对象必须先 toArray(),日期必须用 setValueExplicit() + 格式码双写,这两点漏掉,Excel 文件表面能打开,实际功能全废。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











