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
où $objZip
est une instance de ZipArchive
classe.
Quelle est la raison du problème et comment le résoudre? Remercier.
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
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)
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 !!
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é!!!.
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
Et ma réponse est: Nom de fichier a des symboles comme ":", ",", '"' Dû remplacer à fait différente. Tous travaillé
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.
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.