Wyjątek PHPExcel Writer z Komunikatem " nie można zamknąć pliku zip PHP://output."

Używam PHPExcel do eksportowania niektórych danych do użytkownika w pliku excel. Chciałbym, aby skrypt wysłał plik excel do użytkownika natychmiast po jego utworzeniu. Oto Mój kod testowy:

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();
}

Na moim lokalnym serwerze (Windows 7 x64, Php 5.3.8, Apache 2.2.21) dostaję poprawny plik xlsx. Nie ma żadnych błędów. Ale jest problem na serwerze live (Linux 2.6.32-5-amd64, PHP 5.3.3-7+squeeze13, Apache 2.2.16). Skrypt pozwala przeglądarce pobrać "eksport.XLSX " plik o takiej zawartości:

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 nie działa w trybie awaryjnym. Opcja "open_basedir" jest pusta (jest skomentował).

Znalazłem taki kod w plikach PHPExcel:

if ($objZip->close() === false) {
    throw new PHPExcel_Writer_Exception("Could not close zip file $pFilename.");
}

Więc powodem problemu jest to, że $objZip->close() === false Gdzie $objZip jest instancją klasy ZipArchive.

Jaka jest przyczyna problemu i jak mogę go rozwiązać? Dziękuję.

Author: pnuts, 2014-01-29

9 answers

Najczęstszą przyczyną tego błędu podczas zapisywania w PHP: / / output jest ograniczenie open_basedir, które nie zawiera poprawnego folderu tymczasowego systemu (np. /tmp) lub uprawnień do folderu tymczasowego systemu... suhosin może również mieć na to wpływ, nawet jeśli oczywiste uprawnienia wydają się być ustawione poprawnie.

Możliwym obejściem jest zapisanie pliku do systemu plików w katalogu, o którym wiesz, że masz pełne uprawnienia do zapisu, a następnie użycie metody readfile() do przesyłania strumieniowego tego pliku do php: / / wyjście przed usunięciem pliku

 36
Author: Mark Baker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-29 19:07:29

Dzięki Markowi Bakerowi. Jego odpowiedź rozwiązała problem. Przy jego podejściu napisałem prostą metodę pomocniczą.

static function SaveViaTempFile($objWriter){
    $filePath = sys_get_temp_dir() . "/" . rand(0, getrandmax()) . rand(0, getrandmax()) . ".tmp";
    $objWriter->save($filePath);
    readfile($filePath);
    unlink($filePath);
}

A ja właśnie zamieniłem $objWriter->save('php://output') na SaveViaTempFile($objWriter)

 23
Author: Pavel L,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-02 13:07:28

Witam wypróbowałem następujące: w serwerze Linux Centos 7.0 nie podaje trasy katalogu tmp, wejście:

function SaveViaTempFile($objWriter){
    $filePath = '' . rand(0, getrandmax()) . rand(0, getrandmax()) . ".tmp";
    $objWriter->save($filePath);
    readfile($filePath);
    unlink($filePath);
    exit;
}
I pracuj !!
 4
Author: DIEGO ALEXANDER MORA HIDALGO,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-08 14:45:44

Miałem ten sam błąd podczas próby uruchomienia pliku php, po prostu zmień w następnej linii:

$objWriter->save("/dir1"."/".$file.".xlsx");

Dla tego:

$objWriter->save(dirname(__FILE__)."/dir1"."/".$file.".xlsx");

Dodaj ścieżkę dir i zadziałało!!!.

 1
Author: Giovanny Canasto,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-16 18:27:13

Dla niektórych osób, które mogą mieć ten sam komunikat o błędzie : może to być po prostu dlatego, że nazwa pliku, do którego próbujesz zapisać, jest już otwarta w Twoim Excelu.. Was my case

 1
Author: Custam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-23 16:19:54

A moja odpowiedź brzmi: Nazwa pliku miała takie symbole jak ":", ",", '"' Musiałem je wymienić na inne. Wszystkie obrobione

 0
Author: Velaro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-05 09:38:56

Excelent Friend działa dla mnie w php 7.1.2 i działa w PhpSpreadsheet, naprawić ten sam plik.

PhpSpreadsheet/Writer/Excel2007.php

Rozwiązanie znajduje się w funkcji de save w Excel2007.php

if (strtolower($pFilename) == 'php://output' || strtolower($pFilename) == 'php://stdout') {
    $pFilename = @tempnam(PHPExcel_Shared_File::sys_get_temp_dir(), 'phpxltmp');

Zastąp drugi wiersz tym:

$pFilename = dirname(__FILE__).'/'. rand(0, getrandmax()) . rand(0, getrandmax()) . ".phpxltmp";
Dzięki.
 0
Author: blackslifer888,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-14 20:04:45

Następujące prace dla formatu Excel2007. Musiałby być dostosowany do różnych formatów.


Otwórz ten plik:

\Classes\PHPExcel\Writer\Excel2007.php

Spójrz w pobliżu linii 196 dla:

if (strtolower($pFilename) == 'php://output' || strtolower($pFilename) == 'php://stdout') {
    $pFilename = @tempnam(PHPExcel_Shared_File::sys_get_temp_dir(), 'phpxltmp');

Zastąp drugi wiersz tym:

    $pFilename = dirname(\__FILE__).'/'. rand(0, getrandmax()) . rand(0, getrandmax()) . ".phpxltmp";

Następnie możesz użyć funkcji eksportu, jak opisano w Przewodniku dla programistów.

 -1
Author: Zipfel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-08 01:22:28

Set chmod 777-r public / results

 -1
Author: Василий Большаков,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-04 20:28:34