thinkphp导出excel核心是用phpspreadsheet(tp6推荐)、设simsun字体防乱码、分步处理日期为数值+格式码、响应头声明utf-8并url编码中文文件名,避免内存溢出与公式注入。

ThinkPHP 导出 Excel 的核心在于选对组件、设对字体、写对格式、发对响应头。TP6 推荐用 PhpSpreadsheet,TP3/5 可用 PHPExcel(已停止维护,但兼容性好)。关键不是“能不能导”,而是“导出来不乱码、日期不变成数字、中文能对齐、大文件不崩内存”。
确认环境与安装方式
不同版本对应不同组件:
- TP6.x:执行
composer require phpoffice/phpspreadsheet,PHP ≥ 7.4(低于会 DateTime 异常) - TP5.x:可用
phpoffice/phpspreadsheet或旧版phpoffice/phpexcel(注意命名空间差异) - TP3.2.x:需手动下载 PHPExcel 放入
Library/Vendor/PHPExcel,类名要改后缀为.class.php,调用时加反斜杠:new \PHPExcel()
导出时防中文乱码的关键操作
乱码主因是字体和编码未显式指定:
- 必须设置全局中文字体为 SimSun(宋体),不能用微软雅黑或黑体,否则 Excel 打开提示字体替换:
$spreadsheet->getDefaultStyle()->getFont()->setName('SimSun'); - 导出前 header 中明确声明 UTF-8 编码:
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; charset=utf-8'); - 文件名若含中文,用
rawurlencode()编码:header('Content-Disposition: attachment; filename="'.rawurlencode($fileName).'.xlsx"');
处理日期、数字等特殊类型数据
直接 setCellValue() 日期字段,Excel 会显示为 44562 这类序列号:
- 正确做法分两步:先设为数值类型,再套日期格式码:
$cell->setValueExplicit(strtotime($date), \PhpOffice\PhpSpreadsheet\Cell\DataType::TYPE_NUMERIC);$cell->getStyle()->getNumberFormat()->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_DATE_DATETIME); - 手机号、工号等带前导零的字段(如 00123),需设为文本类型避免自动转数字:
$cell->setValueExplicit('00123', \PhpOffice\PhpSpreadsheet\Cell\DataType::TYPE_STRING);
提升稳定性与用户体验的小技巧
避免导出中途失败或用户卡住:
- 大数据量时禁用
toArray()全量加载,改用逐行写入 +ob_flush()防内存溢出 - 导出前清空输出缓冲:
ob_end_clean();,防止 BOM 或 warning 干扰 Excel 结构 - 设置列宽、居中对齐、表头背景色可提升可读性,例如:
$sheet->getColumnDimension('C')->setWidth(40);$sheet->getStyle('A1:F1')->getFill()->setFillType(...); - 最后务必用
$writer->save('php://output');直接输出,不要先保存本地再读取(易权限失败)
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











