PHPExcel Écrivain d'Exception avec le message "impossible de fermer le fichier zip de php://output."

J'utilise PHPExcel pour exporter des données vers un utilisateur dans un fichier excel. Je voudrais que le script pour envoyer le fichier excel à l'utilisateur immédiatement après sa création. Voici mon code de test:

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

Sur mon serveur local (Windows 7 x64, Php 5.3.8, Apache 2.2.21) j'obtiens un fichier XLSX valide. Il n'y a pas d'erreurs. Mais il y a un problème sur le serveur live (Linux 2.6.32-5-amd64, PHP 5.3.3-7+squeeze13, Apache 2.2.16). Le script permet au navigateur de télécharger le "exportation.XLSX " fichier avec un tel contenu:

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 ne fonctionne pas en Mode sûr. Le l'option" open_basedir " est vide (elle est commentée).

j'ai trouvé un tel code dans les fichiers PHPExcel:

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

Donc la raison du problème est que $objZip->close() === false$objZip est une instance de ZipArchive classe.

Quelle est la raison du problème et comment le résoudre? Remercier.

24
demandé sur pnuts 2014-01-29 20:31:14

9 réponses

la cause la plus fréquente de cette erreur lors de l'enregistrement de php: / / output est une restriction open_basedir qui n'inclut pas le dossier temp d'un système valide (par exemple /tmp), ou les permissions pour le dossier temp du système... suhosin peut aussi affecter cela, même si les permissions évidentes semblent être réglées correctement.

Un possible contourner est d'écrire le fichier sur le système de fichiers dans un répertoire que vous savez que vous avez des privilèges d'écrire, et ensuite utiliser readfile() pour diffuser ce fichier php://output avant de supprimer le fichier

36
répondu Mark Baker 2014-01-29 19:07:29

merci à Mark Baker. Sa réponse a résolu le problème. J'ai écrit une méthode d'aide simple en utilisant son approche.

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

et je viens de remplacer $objWriter->save('php://output')SaveViaTempFile($objWriter)

23
répondu Pavel L 2017-02-02 13:07:28

Salut j'ai essayé la suivante: dans un serveur Linux Centos 7.0 ne spécifie pas la route du répertoire tmp, input:

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

et le travail !!

4
répondu DIEGO ALEXANDER MORA HIDALGO 2015-05-08 14:45:44

J'ai eu la même erreur quand j'ai essayé d'exécuter mon fichier php, il suffit de changer la ligne suivante:

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

pour ceci:

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

ajouter dir chemin et cela a fonctionné!!!.

1
répondu Giovanny Canasto 2015-05-16 18:27:13

pour certaines personnes qui peuvent avoir ce même message d'erreur : il peut très simplement être parce que le nom du fichier que vous essayez de sauvegarder est en fait déjà ouvert dans votre Excel.. C'était mon cas

1
répondu Custam 2017-03-23 16:19:54

Et ma réponse est: Nom de fichier a des symboles comme ":", ",", '"' Dû remplacer à fait différente. Tous travaillé

0
répondu Velaro 2016-02-05 09:38:56

ami Excelent travailler pour moi en php 7.1.2 et travailler en PhpSpreadsheet, corriger le même fichier.

PhpSpreadsheet/Writer/Excel2007.php

LA solution est en fonction Enregistrer dans Excel2007.php

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

remplacer la deuxième ligne par:

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

merci.

0
répondu blackslifer888 2018-02-14 20:04:45

les travaux suivants pour le format Excel2007. Il faudrait l'adapter à différents formats.


Ouvrir ce fichier:

\Classes\PHPExcel\Writer\Excel2007.php

regardez près de la ligne 196 pour:

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

remplacer la deuxième ligne par:

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

vous pouvez alors utiliser la fonction export comme décrit dans le guide du développeur.

-1
répondu Zipfel 2017-02-08 01:22:28

mettre chmod 777-R public / results

-1
répondu Василий Большаков 2017-05-04 20:28:34