thinkphp 8.0 导出 excel 必须使用 phpoffice/phpspreadsheet,phpexcel 已废弃且不兼容 php 8.0+;需 composer require phpoffice/phpspreadsheet,封装 excelexport 服务类,显式设置中文字体、样式及合并单元格,导出前 ob_end_clean() 并设置正确 header 与文件名编码。

ThinkPHP 8.0 导出 Excel 必须使用 phpoffice/phpspreadsheet,PHPExcel 已彻底废弃,不兼容 PHP 8.0+,硬用会直接报 Class 'PHPExcel' not found 或方法签名冲突错误。
安装 phpspreadsheet
在项目根目录执行:
-
composer require phpoffice/phpspreadsheet(注意不要加--dev,导出是运行时依赖) - 安装后无需手动引入,Composer 自动加载
封装导出服务类(推荐做法)
避免在控制器里写大量 Excel 逻辑。建议新建一个服务类,例如 app\common\service\ExcelExport.php:
- 构造函数接收
\PhpOffice\PhpSpreadsheet\Spreadsheet实例和可选 sheet 索引 - 提供
setHeader()设置表头(如[['key'=>'name','title'=>'姓名']]) - 提供
setContent($data, $header)写入数据,按列 key 映射值 - 导出前调用
$spreadsheet->getActiveSheet(),不是getSheet(0)
处理中文与样式关键点
导出后中文乱码、字体缺失、样式丢失,往往不是编码问题,而是未显式声明:
- 每个单元格需设置中文字体:
$cell->getStyle()->getFont()->setName('SimSun')(Windows)或'Noto Sans CJK SC'(Linux/macOS) - 避免依赖默认 fallback 字体 DejaVu(无中文支持)
- 设置居中、边框、背景色等样式,需对单元格范围调用
getStyle()链式操作 - 合并单元格用
mergeCells('A1:C1'),不能只设单个单元格值
响应输出与常见避坑
导出到浏览器下载,必须确保干净输出:
- 导出前执行
ob_end_clean(),清除所有输出缓冲,否则返回空文件或乱码 - 设置正确 header:
Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet - 文件名用 UTF-8 编码,推荐用
rawurlencode($filename . '.xlsx')防止中文名截断 - 大数据量避免用
toArray()反向生成表格,应逐行循环setCellValue(),控制内存占用
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











