【问题标题】:PHPExcel_Writer_Exception with message "Could not close zip file php://output."PHPExcel_Writer_Exception 出现消息“无法关闭 zip 文件 php://output。”
【发布时间】:2014-01-29 16:31:14
【问题描述】:

我正在使用 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 其中$objZipZipArchive 类的一个实例。

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

【问题讨论】:

    标签: php phpexcel ziparchive


    【解决方案1】:

    保存到 php://output 时出现此错误的最常见原因是 open_basedir 限制不包括有效系统的临时文件夹(例如/tmp)或系统临时文件夹的权限... suhosin即使明显的权限似乎设置正确,也会对此产生影响。

    一种可能的解决方法是将文件写入文件系统中您知道您确实具有完全写入权限的目录中,然后在删除文件之前使用 readfile() 将该文件流式传输到 php://output

    【讨论】:

    • Suhosin 安装在实时服务器上,但不在本地服务器上。所以suhosin可能会导致问题。但我不想看到它。正如您的建议,我想简单地使用临时文件来解决问题。谢谢!
    • 在我的情况下,我有一个错字.. :
    • 嘿。我会遇到同样的错误。我试图给 /tmp 和 /var/tmp 777 但它不起作用。你是怎么做到的?
    • 有没有不将临时文件保存到文件系统的解决方案?
    • 第一个点 (./) 确保路径是相对于当前工作文件夹的;第二个点(export_123.xlsx)是文件名和文件扩展名之间的分隔符
    【解决方案2】:

    感谢马克贝克。他的回答解决了问题。我使用他的方法编写了一个简单的辅助方法。

    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)

    【讨论】:

    • 听起来不错,但你必须在哪里替换它?
    【解决方案3】:

    您好,我尝试了以下方法: 在服务器linux Centos 7.0中不指定目录tmp的路由,输入:

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

    然后工作!!

    【讨论】:

    • 它对我不起作用
    【解决方案4】:

    对于可能有相同错误消息的某些人:这可能很简单,因为您尝试保存的文件名实际上已经在您的 Excel 中打开。 是我的情况

    【讨论】:

    • 这也是我的情况,所以可能会发生在其他人身上,请指出。
    【解决方案5】:

    优秀的朋友在 php 7.1.2 中为我工作并在 PhpSpreadsheet 中工作,修复相同的文件。

    PhpSpreadsheet/Writer/Excel2007.php
    

    解决办法是在de函数中保存在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";
    

    谢谢。

    【讨论】:

      【解决方案6】:

      当我尝试运行我的 php 文件时,我遇到了同样的错误,只需更改下一行:

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

      为此:

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

      添加dir 路径,它起作用了!!!。

      【讨论】:

        【解决方案7】:

        我的回答是: 文件名有“:”、“”、“”等符号 不得不将它们替换为不同的。 一切正常

        【讨论】:

          【解决方案8】:

          尝试将文件保存到不存在的文件夹时也会发生此错误。确保整个路径存在。

          【讨论】:

            【解决方案9】:

            以下适用于 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";
            

            然后您可以按照开发者指南中的说明使用导出功能。

            【讨论】:

              【解决方案10】:

              就我而言,我将目标文件夹的权限修改为 rwxrwxrwx (0777),现在可以使用了!

              【讨论】:

              • 你永远不应该将你的服务器目录配置为全世界都可以读写。
              【解决方案11】:

              这是由 dir 权限引起的。尝试进入最终文件夹,然后chmod -R 777 [folder_name]。它应该工作:)

              【讨论】:

              • 这将向任何人开放服务器,不要这样做
              【解决方案12】:

              设置 chmod 777 -R 公开/结果

              【讨论】:

              • 这将向任何人开放服务器,不要这样做。
              猜你喜欢
              • 2014-04-25
              • 2015-01-27
              • 1970-01-01
              • 2017-10-12
              • 1970-01-01
              • 1970-01-01
              • 2013-12-26
              • 1970-01-01
              • 2011-08-04
              相关资源
              最近更新 更多