PHPExcel_Writer_Exception,消息"无法关闭zip文件php://输出."

Pav*_*l L 26 php phpexcel ziparchive

我正在使用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();
}
Run Code Online (Sandbox Code Playgroud)

在我的本地服务器上,(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}
Run Code Online (Sandbox Code Playgroud)

PHP没有以安全模式运行."open_basedir"选项为空(已注释掉).

我在PHPExcel文件中找到了这样的代码:

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

所以问题的原因是$objZip->close() === falsewhere $objZip是一个ZipArchive类的实例.

问题的原因是什么,我该如何解决?谢谢.

Mar*_*ker 40

保存到php://输出时出现此错误的最常见原因是open_basedir限制,该限制不包含有效系统的临时文件夹(例如/tmp),或系统临时文件夹的权限... suhosin也会影响此,甚至当明显的权限似乎设置正确时.

一个可能的workround是将文件写入一个你知道你有完全权限要编写的目录中的文件系统,然后在删除文件之前使用readfile()将该文件传输到php://输出

  • 嘿。我陷入了同样的错误。我试图给 /tmp 和 /var/tmp 777 但它不起作用。你是怎么做的? (2认同)

Pav*_*l L 27

感谢Mark Ba​​ker.他的回答解决了这个问题.我用他的方法编写了一个简单的帮助方法.

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

而我刚刚接替$objWriter->save('php://output')SaveViaTempFile($objWriter)


小智 5

嗨,我尝试了以下操作:在服务器linux Centos 7.0中,未指定目录tmp的路由,请输入:

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

和工作 !!