【问题标题】:PHPExcel unable to open the saved filePHPExcel 无法打开保存的文件
【发布时间】:2015-04-24 17:14:42
【问题描述】:

我正在尝试打开一个现有的 Excel 文件,修改一些单元格并保存它。我正在使用 Excel2007 作为读写器。

输入文件大约 1 MB 大,其中包含很少的公式、受保护的数据以及隐藏的行和列以及我不修改的工作表。

我能够加载数据并在其中读取和写入一些值,我使用代码中的各种 var_dump 检查这些值。

问题在于保存时。它会在超时时引发一些致命错误,而且如果它写入文件,文件大小会膨胀到 9.2 MB,如果我可以打开它就可以了。

代码 sn-p - 没什么特别的。

$objReader = PHPExcel_IOFactory::createReader('Excel2007');
$objPHPExcel = $objReader->load($inputFile);

$objPHPExcel->setActiveSheetIndex(2);
$activeSheet = $objPHPExcel->getActiveSheet();

$currCell = $activeSheet->getCell("O3");
$cellValidation = $currCell->getDataValidation("O3");
$values = array();
if ($cellValidation->getShowDropDown() == true)
{
    $values = $cellValidation->getFormula1();
    $valArray = explode(",", $values);
    $currCell->setValue($valArray[0]);
}

$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
$objWriter -> setPreCalculateFormulas(false);
$objWriter->save($outputFile);

我使用 MS Excel 2010 打开生成的文件,但它只需要很长时间,甚至一次都没有打开过。

请帮我解决这个问题,告诉我应该在哪里寻找。

非常感谢任何帮助。

【问题讨论】:

    标签: php phpexcel


    【解决方案1】:

    不要将其保存到文件中,而是将其保存到php://output­Docs:

    $objWriter->save('php://output');
    

    这会将其原样发送到浏览器。

    您想先添加一些headers­Docs,就像在文件下载中很常见,这样浏览器就知道该文件是哪种类型以及应该如何命名(文件名):

    // We'll be outputting an excel file
    header('Content-type: application/vnd.ms-excel');
    
    // It will be called file.xls
    header('Content-Disposition: attachment; filename="file.xls"');
    
    // Write file to the browser
    $objWriter->save('php://output');
    

    先做标题,然后保存。对于 excel 标题,请参阅以下问题:Setting mime type for excel document。

    所以最终的代码会有以下几行 -

    // Save Excel 2007 file
    #echo date('H:i:s') . " Write to Excel2007 format\n";
    $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
    ob_end_clean();
    // We'll be outputting an excel file
    header('Content-type: application/vnd.ms-excel');
    // It will be called file.xls
    header('Content-Disposition: attachment; filename="file.xlsx"');
    $objWriter->save('php://output');
    

    我认为这行:

    ob_end_clean();
    

    应该可以解决你的问题。

    谢谢!

    【讨论】:

    • 感谢@CloudFreezer 的回复。我之前尝试过,但下载的文件仍然大小相同,仍然无法打开。我不知道 ZipArchive 是否与这种腹胀有关。此外,当我选择提取数据时,通过 Excel 我可以看到数据,但会丢失输入文件中的所有格式。
    • 不是 ob_end_clean() 来清理输出缓冲区吗?
    【解决方案2】:

    “膨胀”的原因有很多,而且很大程度上取决于工作表中的实际数据,但是 MS Excel 本身使用许多不同的技术来保持文件大小较小,而 PHPExcel 编写了一个简单版本的OfficeOpenXML 格式。

    例如,MS Excel 查看所有单元格的字符串内容,并将各个字符串存储在字符串表中。如果一个字符串被两个或多个单元格使用,则字符串表中将只有一个条目。但是,检查字符串表中是否已存在字符串会产生性能开销,因此 PHPExcel 不会执行该检查,但会在字符串表中重复条目。这意味着它会因为重复而创建一个大文件,但会尽可能快地保持保存速度。

    同样,MS Excel 会查看所有公式,如果公式与现有公式相似(只有行/列偏移差异),它将存储为共享公式而不是单元格公式,因此实际公式数据只存储一次。同样,PHPExcel 不会执行此检查,因为它在保存时会产生很大的性能开销,因此它将每个公式存储为单元格公式而不是共享公式。


    不,我无法解释为什么该文件无法在 MS Excel 2010 中加载,也无法在无法通过调试运行整个过程的情况下对其进行解释

    【讨论】:

    • 谢谢马克。我知道在不知道输入文件的内容的情况下很难提供帮助。我确实尝试制作一个带有隐藏表、数据验证、密码保护的 excel 文件,并且我能够使用 PHPExcel 读取、修改和保存。我目前只是在尝试调试它,并且不断收到一些致命的超时错误,这些错误发生在 writer 对象中。这是最新的:致命错误:在第 487 行的 /var/www/html/application/third_party/PHPExcel/Writer/Excel2007/Worksheet.php 中超过了 300 秒的最大执行时间。还有一种方法可以增加 300 秒,如果需要?
    • PHPExcel 是否在最新版本中使用 Stop if true 选项处理条件格式?我有一个来自客户的 excel 文件,我需要在其中数据但保留它已有的任何公式和格式。我试图找出最好的方法来做到这一点,而不是花太多时间试图弄清楚已经完成的事情工作簿。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-16
    相关资源
    最近更新 更多