我正在使用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
其中$objZip
是ZipArchive
类的实例。
问题的原因是什么?如何解决?谢谢。
答案 0 :(得分:38)
保存到php:// output时出现此错误的最常见原因是open_basedir限制,该限制不包含有效系统的临时文件夹(例如/tmp
),或系统临时文件夹的权限。即使明显的权限似乎设置正确,suhosin也会影响这一点。
一个可能的workround是将文件写入你知道你有完全权限要编写的目录中的文件系统,然后在删除文件之前使用readfile()将该文件传输到php://输出
答案 1 :(得分:24)
感谢Mark Baker。他的回答解决了这个问题。我用他的方法编写了一个简单的辅助方法。
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)
答案 2 :(得分:4)
您好我尝试了以下内容: 在服务器linux Centos 7.0中没有指定目录tmp的路由,输入:
function SaveViaTempFile($objWriter){
$filePath = '' . rand(0, getrandmax()) . rand(0, getrandmax()) . ".tmp";
$objWriter->save($filePath);
readfile($filePath);
unlink($filePath);
exit;
}
并且工作!!
答案 3 :(得分:2)
对于可能有相同错误消息的某些人:可能只是因为您尝试保存的文件名实际上已经在Excel中打开了。 是我的案子
答案 4 :(得分:2)
Excelent Friend在php 7.1.2中为我工作并在PhpSpreadsheet中工作,修复了同一个文件。
PhpSpreadsheet/Writer/Excel2007.php
解决方案是在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";
感谢。
答案 5 :(得分:1)
$objWriter->save("/dir1"."/".$file.".xlsx");
为此:
$objWriter->save(dirname(__FILE__)."/dir1"."/".$file.".xlsx");
添加dir
路径,它有效!!!。
答案 6 :(得分:0)
我的答案是: 文件名包含符号,如":",",",'"' 不得不把它们换成不同的。 全部工作
答案 7 :(得分:0)
就我而言,我将目标文件夹的权限修改为rwxrwxrwx(0777),现在可以使用!
答案 8 :(得分:0)
当尝试将文件保存到不存在的文件夹中时也会发生此错误。确保整个路径都存在。
答案 9 :(得分:-1)
以下适用于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 :(得分:-1)
设置chmod 777 -R public / results
答案 11 :(得分:-1)
这是由于dir权限引起的。尝试输入最终文件夹,然后输入chmod -R 777 [folder_name]
。它应该可以工作:)