问题
I would like to offer an Excel-File for download with PhpSpreadsheet
Here is my code:
require 'vendor/autoload.php';
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet->setCellValue('A1', 'Hello World !');
$writer = new Xlsx($spreadsheet);
$writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Xlsx');
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment; filename="hello_world.xlsx"');
$writer->save("php://output");
I get the following error message:
PHP Warning: ZipArchive::close(): Failure to create temporary file: No such file or directory in /Users/sg/GitWorkingCopies/xxx1/xxx2/library/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx.php on line 374
PHP Fatal error: Uncaught exception 'PhpOffice\PhpSpreadsheet\Writer\Exception' with message 'Could not close zip file php://output.' in /Users/sg/GitWorkingCopies/xxx1/xxx2/library/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx.php:375
The dokumentation of PHPSpreadsheet says:
\PhpOffice\PhpSpreadsheet\Writer\Xlsx uses temporary storage when writing to php://output. By default, temporary files are stored in the script's working directory. When there is no access, it falls back to the operating system's temporary files location.
The upload_tmp_dir is: /Applications/XAMPP/xamppfiles/temp/
Which folder permissons do I have to check? Or what does cause the problem?
回答1:
General rules for a directory in PHP to write to it:
It must exist,
It is writable by PHP process,
It is allowed by open_basedir php.ini directive.
Therefore, set some file path as argument in the $writer->save()
method and check that these 3 rules are met.
If you want to use only php://output
or php://stdout
value in the $writer->save()
method, check these rules for:
1) The directory returned by the sys_get_temp_dir()
function. In Windows sys_get_temp_dir()
by default returns the temporary directory of the current OS user. The value can be changed by sys_temp_dir
php.ini directive.
or
2) The directory returned by the upload_tmp_dir php.ini directive. $useUploadTempDirectory
has false
value by default. To set it value to true
add this line in your code before saving the file:
\PhpOffice\PhpSpreadsheet\Shared\File::setUseUploadTempDirectory(true);
Here is the code that is responsible for selecting the save path:
From \PhpOffice\PhpSpreadsheet\Writer\Xlsx::save
method (source):
// If $pFilename is php://output or php://stdout, make it a temporary file...
$originalFilename = $pFilename;
if (strtolower($pFilename) == 'php://output' || strtolower($pFilename) == 'php://stdout') {
$pFilename = @tempnam(File::sysGetTempDir(), 'phpxltmp');
if ($pFilename == '') {
$pFilename = $originalFilename;
}
}
From \PhpOffice\PhpSpreadsheet\SharedFile::sysGetTempDir
method (source):
/**
* Get the systems temporary directory.
*
* @return string
*/
public static function sysGetTempDir()
{
if (self::$useUploadTempDirectory) {
// use upload-directory when defined to allow
// running on environments having very restricted open_basedir configs
if (ini_get('upload_tmp_dir') !== false) {
if ($temp = ini_get('upload_tmp_dir')) {
if (file_exists($temp)) {
return realpath($temp);
}
}
}
}
return realpath(sys_get_temp_dir());
}
回答2:
I don't know if your code is from an included file but I had a similar issue. I tried to use __DIR__
constant and it worked, my code looks like this:
$filepath = __DIR__ . "/reports/${filename}_".date("Ymd_Gis").".xlsx";
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
$writer->save($filepath);
回答3:
The issue was the tmp directory used by phpSpreadSheet and that was not writable by PHP process. I changed the tmp directory to upload tmp directory and now the issue is resolved. I solved the issue using
\PhpOffice\PhpSpreadsheet\Shared\File::setUseUploadTempDirectory(true);
来源:https://stackoverflow.com/questions/50470370/phpspreadsheet-permissions-ziparchiveclose-failure-to-create-temporary-f