spatie/simple-excel 安装与使用需满足 PHP ≥ 8.0、启用 zip 和 xml 扩展,确保 Composer 版本较新,写入 XLSX 时用绝对可写路径并正确设置响应头。

Composer 安装 spatie/simple-excel 失败?先确认 PHP 版本和扩展
spatie/simple-excel 要求 PHP ≥ 8.0,且必须启用 zip 和 xml 扩展(XLSX 依赖 ZIP 解压 + XML 解析)。常见报错如 Class 'ZipArchive' not found 或 Package spatie/simple-excel has a PHP requirement incompatible with your PHP version,基本都卡在这儿。
- 运行
php -v确认版本 ≥ 8.0 - 运行
php -m | grep -E "zip|xml"检查扩展是否加载 - Linux 下缺 zip 扩展:通常需
sudo apt install php-zip(Debian/Ubuntu)或sudo yum install php-pecl-zip(CentOS/RHEL),然后重启 PHP-FPM 或 Apache - Windows 用户注意:PHP.ini 中取消注释
extension=zip和extension=dom(dom 是 xml 的依赖)
composer require 报错“could not parse version constraint”?检查 Composer 版本
老版本 Composer(^1.16.0),会直接报解析错误。这不是包的问题,是工具太旧。
- 执行
composer --version,低于2.0.0就得升级 - 升级命令:
composer self-update(全局安装)或php composer.phar self-update(局部) - 升级后重试
composer require spatie/simple-excel,别加@dev或分支名——稳定版已足够覆盖 CSV/XLSX 基础读写
读取 XLSX 文件时内存爆掉或超时?别用 SimpleExcelReader::create() 直读大文件
SimpleExcelReader::create() 默认把整张表加载进内存,10MB 以上的 XLSX 很容易触发 Allowed memory size exhausted 或 Maximum execution time exceeded。它适合小数据(
- 大文件必须用流式读取:
SimpleExcelReader::create($path)->usingMemoryLimit(64 * 1024 * 1024)控制单次缓冲大小 - 更稳妥的做法是配合
->eachRow(……)迭代处理,避免全量载入:use SpatieSimpleExcelSimpleExcelReader; <p>SimpleExcelReader::create('data.xlsx')->eachRow(function (array $row) {// 每行单独处理,不存历史 processRow($row); }); - CSV 场景下,
->skipFirstRow()很常用,但 XLSX 不一定有表头——得看 Excel 实际结构,别无脑链式调用
写入 XLSX 报错“Could not open file for writing”?路径和权限比想象中敏感
SimpleExcelWriter::create($filename) 的 $filename 必须是 ** 可写的绝对路径 **,相对路径(如 exports/report.xlsx)在 CLI 和 Web 环境下行为不一致,Web 下常因工作目录是 /var/www/html 导致写入失败。
- 写入前务必用
is_writable(dirname($filename))检查父目录权限 - 推荐用
__DIR__ . '/exports/report-' . date('Ymd-His') . '.xlsx'构造绝对路径 - 注意:XLSX 写入不支持追加模式(
append),每次都是新建文件;若需多批次写入,得自己缓存数据再一次性输出 - 导出到浏览器时,别忘了设 header:
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');和header('Content-Disposition: attachment; filename="report.xlsx"');
实际用起来,最麻烦的从来不是语法,而是 PHP 环境扩展、Composer 工具链、文件系统权限这三块拼图没对齐。少一个,require 就卡住,create() 就崩掉,连 demo 都跑不起来。