应直接安装 PhpSpreadsheet 而非已停更且不兼容 PHP 8.x 的 PHPExcel;使用 IOFactory::load() 时需确保文件扩展名与实际格式一致并推荐绝对路径;写入大数据优先用 fromArray() 而非 setCellValue() 循环;中文乱码需检查 mbstring 扩展及 CSV 文件 BOM。

直接装 PhpSpreadsheet,别碰 PHPExcel
PhpSpreadsheet 是 PHPExcel 的官方继任者,PHP 7.2+ 唯一维护的 Excel 库。如果你还在查 PHPExcel 安装方式,说明你踩进了过期文档的坑——它早在 2019 年就停止更新,且不兼容 PHP 8.x。
执行这行命令就能装好最新稳定版:
composer require phpoffice/phpspreadsheet不需要额外加
--dev 或指定版本,除非你明确要锁死旧版(比如项目还卡在 PHP 7.1)。
IOFactory::load() 读 Excel 时路径和扩展名必须匹配
常见报错是 Could not open file for reading 或 Invalid file type,多数不是权限问题,而是文件扩展名和实际内容不符,或者路径没写对。
实操注意点:
-
IOFactory::load()会根据文件后缀自动选读取器(.xlsx→Xlsx,.xls→Xls),但如果你把一个.xlsx文件重命名为.xls,它就会尝试用老式Xls解析器打开,直接报错 - 路径推荐用绝对路径,避免相对路径在 CLI 和 Web 环境下行为不一致;可用
__DIR__ . '/data/report.xlsx' - 如果读的是上传临时文件,确保
$_FILES['file']['tmp_name']没被 move 或销毁
写入大文件时别用 setCellValue() 逐单元格循环
往 1000 行 × 50 列的表格里填数据,如果用 $sheet->setCellValue('A1', $val) 循环 5 万次,内存暴涨、速度极慢——这是最常被忽略的性能雷区。
更合理的方式:
- 用
fromArray()一次性写入二维数组:$sheet->fromArray($data, null, 'A1') - 若需格式控制(比如某列设为日期),先写数据,再批量设置样式:
$sheet->getStyle('B1:B1000')->getNumberFormat()->setFormatCode(...) - 导出超大数据(>5 万行)考虑用
Writer\Xlsx的分块写入模式,或改用Spout这类流式库
中文乱码?重点检查 mbstring 扩展和 BOM
Excel 里中文显示成方块、问号或空格,通常不是 PhpSpreadsheet 的锅,而是环境或源数据问题。
排查顺序:
- 确认 PHP 已启用
mbstring扩展(php -m | grep mbstring),否则部分字符串操作会截断 UTF-8 字节 - 读取 CSV 导入的数据时,检查原始文件是否带 BOM;有 BOM 的 UTF-8 CSV 会导致第一列字段名前多出不可见字符,
var_dump()能看到"name"这种开头 - 写入时不用手动编码转换,PhpSpreadsheet 内部全走 UTF-8;但如果你从数据库读出的数据本身是 GBK 编码,得先用
mb_convert_encoding($str, 'UTF-8', 'GBK')
立即学习“PHP免费学习笔记(深入)”;
事情说清了就结束









