Исключение PHPExcel Writer с сообщением " не удалось закрыть zip-файл php: / / output."
Я использую PHPExcel для экспорта некоторых данных пользователю в файл excel. Я хотел бы, чтобы скрипт отправил файл excel пользователю сразу после его создания. Вот мой тестовый код:
try{
/* Some test data */
$data = array(
array(1, 10 , 2 ,),
array(3, 'qqq', 'some string' ,),
);
$objPHPExcel = new PHPExcel();
$objPHPExcel->setActiveSheetIndex(0);
/* Fill the excel sheet with the data */
$rowI = 0;
foreach($data as $row){
$colI = 0;
foreach($row as $v){
$colChar = PHPExcel_Cell::stringFromColumnIndex($colI++);
$cellId = $colChar.($rowI+1);
$objPHPExcel->getActiveSheet()->SetCellValue($cellId, $v);
}
$rowI++;
}
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment;filename="export.xlsx"');
header('Cache-Control: max-age=0');
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
$objWriter->save('php://output');
}catch(Exception $e){
echo $e->__toString();
}
на моем локальном сервере (Windows 7 x64, Php 5.3.8, Apache 2.2.21)
Я получаю действительный файл xlsx. Ошибок нет.
Но есть проблема на сервере (Linux 2.6.32-5-amd64, PHP 5.3.3-7+squeeze13, Apache 2.2.16)
. Скрипт позволяет браузеру скачать "export.xlsx " файл с таким содержанием:
exception 'PHPExcel_Writer_Exception' with message 'Could not close zip file php://output.' in /var/www/someuser/data/www/somedomain.com/libs/PHPExcel/Writer/Excel2007.php:348
Stack trace:
#0 /var/www/someuser/data/www/somedomain.com/classes/Report/Leads/Export.php(339): PHPExcel_Writer_Excel2007->save('php://output')
#1 /var/www/someuser/data/www/somedomain.com/application/pages/account/controllers/TestController.php(13): Report_Leads_Export->Test()
#2 /var/www/someuser/data/www/somedomain.com/libs/Zend/Controller/Action.php(516): Account_TestController->indexAction()
#3 /var/www/someuser/data/www/somedomain.com/libs/Zend/Controller/Dispatcher/Standard.php(295): Zend_Controller_Action->dispatch('indexAction')
#4 /var/www/someuser/data/www/somedomain.com/libs/Zend/Controller/Front.php(954): Zend_Controller_Dispatcher_Standard->dispatch(Object(Zend_Controller_Request_Http), Object(Zend_Controller_Response_Http))
#5 /var/www/someuser/data/www/somedomain.com/index.php(511): Zend_Controller_Front->dispatch()
#6 {main}
PHP не работает в безопасном режиме. Этот опция "open_basedir" пуста (она закомментирована).
я нашел такой код в файлах PHPExcel:
if ($objZip->close() === false) {
throw new PHPExcel_Writer_Exception("Could not close zip file $pFilename.");
}
Итак, причина проблемы в том, что $objZip->close() === false
здесь $objZip
пример ZipArchive
класса.
в чем причина проблемы и как я могу решить эту проблему? Спасибо.
9 ответов
наиболее распространенной причиной этой ошибки при сохранении в php: / / output является ограничение open_basedir, которое не включает временную папку допустимой системы (например,/tmp
) или разрешения для временной папки системы... suhosin также может повлиять на это, даже если очевидные разрешения, по-видимому, установлены правильно.
возможным обходным путем является запись файла в файловую систему в каталоге, который вы знаете, что у вас есть полные права на запись, а затем используйте readfile () для потоковой передачи этого файла на php: / / вывод перед удалением файла
спасибо Марку Бейкеру. Его ответ решил проблему. Я написал простой вспомогательный метод, используя его подход.
static function SaveViaTempFile($objWriter){
$filePath = sys_get_temp_dir() . "/" . rand(0, getrandmax()) . rand(0, getrandmax()) . ".tmp";
$objWriter->save($filePath);
readfile($filePath);
unlink($filePath);
}
и я только что заменил $objWriter->save('php://output')
С SaveViaTempFile($objWriter)
Привет я попробовал следующий: на сервере linux Centos 7.0 не указан маршрут каталога tmp, введите:
function SaveViaTempFile($objWriter){
$filePath = '' . rand(0, getrandmax()) . rand(0, getrandmax()) . ".tmp";
$objWriter->save($filePath);
readfile($filePath);
unlink($filePath);
exit;
}
и работать !!
У меня была такая же ошибка, когда я пытаюсь запустить свой php-файл, просто измените следующую строку:
$objWriter->save("/dir1"."/".$file.".xlsx");
для этого:
$objWriter->save(dirname(__FILE__)."/dir1"."/".$file.".xlsx");
добавить комментарий dir
путь и это сработало!!!.
для некоторых людей, которые могут иметь это же сообщение об ошибке : это может быть очень просто потому, что имя файла, который вы пытаетесь сохранить, на самом деле уже открыто в вашем Excel.. Был мой случай
и мой ответ: Filename имел такие символы, как ":", ",", '"' Пришлось заменить их на другие. Все сработало
отличный друг работает для меня в php 7.1.2 и работает в PhpSpreadsheet, исправьте тот же файл.
PhpSpreadsheet/Writer/Excel2007.php
решение находится в функции de save в Excel2007.в PHP
if (strtolower($pFilename) == 'php://output' || strtolower($pFilename) == 'php://stdout') {
$pFilename = @tempnam(PHPExcel_Shared_File::sys_get_temp_dir(), 'phpxltmp');
заменить вторую строку следующим:
$pFilename = dirname(__FILE__).'/'. rand(0, getrandmax()) . rand(0, getrandmax()) . ".phpxltmp";
спасибо.
следующие работы для формата Excel2007. Его необходимо будет адаптировать к различным форматам.
открыть этот файл:
\Classes\PHPExcel\Writer\Excel2007.php
посмотрите рядом с линией 196 для:
if (strtolower($pFilename) == 'php://output' || strtolower($pFilename) == 'php://stdout') {
$pFilename = @tempnam(PHPExcel_Shared_File::sys_get_temp_dir(), 'phpxltmp');
заменить вторую строку следующим:
$pFilename = dirname(\__FILE__).'/'. rand(0, getrandmax()) . rand(0, getrandmax()) . ".phpxltmp";
затем вы можете использовать функцию экспорта, как описано в руководстве разработчика.