PhpSpreadsheet导出Excel报错:ZipArchive创建临时文件失败
从你给出的错误信息和文档说明来看,这个问题的核心是:PhpSpreadsheet生成Xlsx格式文件并输出到php://output时,需要先在临时目录创建Zip压缩文件,但当前PHP运行进程没有权限访问对应的临时目录,导致ZipArchive无法完成操作。
你需要重点检查以下几个目录的权限,同时可以通过手动指定临时目录来快速解决问题:
1. 脚本的当前工作目录
根据PhpSpreadsheet文档,写入php://output时默认会使用脚本的工作目录作为临时存储位置。你可以在代码中添加一行echo getcwd();来确认当前脚本的工作路径,然后检查该目录是否允许PHP运行进程(比如XAMPP的Apache用户)进行读写操作。
如果这个目录权限不足,PhpSpreadsheet会尝试回退到系统临时目录,但如果回退过程中也出现权限问题,就会触发你遇到的错误。
2. PHP的系统临时目录
注意:PHP配置中的upload_tmp_dir不一定等于系统默认的临时目录。你可以通过执行echo sys_get_temp_dir();来获取PhpSpreadsheet实际会回退到的系统临时目录路径,确认该目录对PHP进程有读写权限。
比如在macOS环境下,系统默认临时目录通常是/private/tmp/,你需要确保Apache或PHP-FPM用户能对这个目录进行操作。
3. 配置的upload_tmp_dir目录
虽然文档说明默认优先使用脚本工作目录,但你当前配置的upload_tmp_dir(/Applications/XAMPP/xamppfiles/temp/)也需要检查权限:确认该目录存在,且PHP运行用户拥有读写权限。
快速解决办法:手动指定临时目录
如果不想逐一排查权限,你可以直接在代码中手动指定一个你确认有权限的临时目录,通过PhpSpreadsheet的Settings类来设置:
require 'vendor/autoload.php'; use PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Writer\Xlsx; use PhpOffice\PhpSpreadsheet\Settings; // 手动指定有读写权限的临时目录 Settings::setTempDir('/Applications/XAMPP/xamppfiles/temp/'); $spreadsheet = new Spreadsheet(); $sheet = $spreadsheet->getActiveSheet(); $sheet->setCellValue('A1', 'Hello World !'); // 注意:Xlsx格式对应的Content-Type更准确的是下面这个 header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'); header('Content-Disposition: attachment; filename="hello_world.xlsx"'); $writer->save("php://output");
另外补充一个小细节:你原来使用的Content-Type: application/vnd.ms-excel更适合旧版的Xls格式,Xlsx格式推荐使用application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,这样浏览器能更准确识别文件类型。
内容的提问来源于stack exchange,提问作者Phantom

