PHPExcel - 在 null 时调用成员函数 getCacheData()

PHPExcel - Call to a member function getCacheData() on null

我在写入文件时遇到如下错误

Error: Call to a member function getCacheData() on null 
File E:\websites\d3a-qa\vendor\PHPExcel\PHPExcel\Worksheet.php 
Line: 2554

第 2554 行:

public function garbageCollect() {
        // Flush cache
        $this->_cellCollection->getCacheData('A1');

我知道这个错误是因为 $this->_cellCollectionnull 但我不知道为什么是 null。我打电话给 $writer->save($saving_name);,它给出了这个问题。

我尝试了各种各样的事情。从回溯到注释 disconnectWorksheet 代码。重置 PHPExcel 对象的变量但没有任何效果。

有趣的是它有时有效,有时无效。互联网上没有太多关于 PHPExcel 的文档或查询的答案。因此,我终于来到这里,这样我就可以得到任何答案,或者至少得到需要做什么的提示。

提前致谢。

编辑

这是我使用 PHPExcel 的代码。错误似乎出现在 $writer->save($saving_name);

$parts是一个有若干个XLS的数组,需要合并成一个XLS sheet.

PS:只有在处理繁重(或将近 45 sheets)时才会出现错误。对于较小的 xls,它可以正常工作。

if(!empty($insertSummary)) {
            $PHPExcel = new \PHPExcel();
            $PHPExcel = $PHPExcel->createSheet();
            $PHPExcel->setTitle(_EXPORT_DES_SUMMARY);
        }

        foreach ($parts as $part) {        
            $bigExcel = '';

            if(!empty($insertSummary))
                $bigExcel = $this->addSummarySheet($insertSummary, $part, $PHPExcel);

            $bigExcel = $this->processPartFiles($part, $bigExcel);

            $writer = \PHPExcel_IOFactory::createWriter($bigExcel, 'Excel5');
            $returnFilename = $dbName . '_' . 'DES' . '_' . date('Y-m-d-h-i-s') . '_' . 'Part_' . ++$count . '.xls';

            // name of file, which needs to be attached during email sending
            $saving_name = _DES_PATH_WEBROOT . DS . $returnFilename;

            $zipFiles[] = $saving_name;
            $writer->save($saving_name);

            //Log::write('debug', 'Line(' . __LINE__ .') memory_get_peak_usage - ' . memory_get_peak_usage(true));
            //Log::write('debug', 'Line(' . __LINE__ .') memory_get_usage - ' . memory_get_usage());
        }

EDIT-2

$this->addSummarySheet()

public function addSummarySheet($insertSummary, $part, $PHPExcel) {
        $keys = array_keys($part);
        $bigExcel = $this->CommonInterface->readXlsOrCsv($insertSummary, false);

        //Copy & paste values of range of cells
        $cellValuesTitle = $bigExcel->getActiveSheet()->rangeToArray('A1:C1');
        $cellValues = $bigExcel->getActiveSheet()->rangeToArray('A' . ($keys[0] + 1) .':C' . ($keys[count($keys) - 1] + 1));
        $bigExcel->removeSheetByIndex(0);

        $bigExcel->addSheet($PHPExcel);
        $bigExcel->getActiveSheet()->fromArray($cellValuesTitle, null, 'A1');
        $bigExcel->getActiveSheet()->fromArray($cellValues, null, 'A2');

        foreach($keys as $rowCount => $sheet) {
            $cellCordinateRow = $rowCount + 2;
            $bigExcel->getActiveSheet()->getCell('A' . $cellCordinateRow)->getHyperlink()->setUrl("sheet://'Data $sheet'!A{$cellCordinateRow}");
        }

        return $bigExcel;
    }

$this->CommonInterface->readXlsOrCsv()

public function readXlsOrCsv($filename = null, $unlinkFile = true, $sheetnames = null) {

        require_once(ROOT . DS . 'vendor' . DS . 'PHPExcel' . DS . 'PHPExcel' . DS . 'IOFactory.php');
        /**  Identify the type of $inputFileName  **/
        $inputFileType = \PHPExcel_IOFactory::identify($filename);
        $objReader = \PHPExcel_IOFactory::createReader($inputFileType);

        if(!empty($sheetnames)) {
            //$objReader->setReadDataOnly(true);
            $objReader->setLoadSheetsOnly($sheetnames);
        }
        $objPHPExcel = $objReader->load($filename);

        //$objPHPExcel = \PHPExcel_IOFactory::load($filename);
        if ($unlinkFile == true)
            $this->unlinkFiles($filename); // Delete The uploaded file
        return $objPHPExcel;
    }

我已经解决了我在使用 PHPExcel 时遇到的问题。

我已将 $bigExcel = $this->CommonInterface->readXlsOrCsv($insertSummary, false);$this->addSummarySheet() 中删除,并将其放在 if(!empty($insertSummary)) { 下,如 EDIT 2.

中所述

此外,我在 $this->addSummarySheet()

中添加了以下代码行
$PHPExcelSheet = new \PHPExcel();
$PHPExcelSheet->removeSheetByIndex(0);

$PHPExcel = new \PHPExcel();
$PHPExcel = $PHPExcel->createSheet();
$PHPExcel->setTitle(_EXPORT_DES_SUMMARY);

所以我在 $this->addSummarySheet() 中的最终代码变为

public function addSummarySheet($insertSummary, $part, $PHPExcel, $summaryExcel) {
        $keys = array_keys($part);
        //$summaryExcel= $this->CommonInterface->readXlsOrCsv($insertSummary, false);

        //Copy & paste values of range of cells
        $cellValuesTitle = $summaryExcel->getActiveSheet()->rangeToArray('A1:C1');
        $cellValues = $summaryExcel->getActiveSheet()->rangeToArray('A' . ($keys[0] + 1) .':C' . ($keys[count($keys) - 1] + 1));

        $PHPExcelSheet = new \PHPExcel();
        $PHPExcelSheet->removeSheetByIndex(0);

        $PHPExcel = new \PHPExcel();
        $PHPExcel = $PHPExcel->createSheet();
        $PHPExcel->setTitle(_EXPORT_DES_SUMMARY);

        $PHPExcelSheet->addSheet($PHPExcel);
        $PHPExcelSheet->getActiveSheet()->fromArray($cellValuesTitle, null, 'A1');
        $PHPExcelSheet->getActiveSheet()->fromArray($cellValues, null, 'A2');

        foreach($keys as $rowCount => $sheet) {
            $cellCordinateRow = $rowCount + 2;
            $PHPExcelSheet->getActiveSheet()->getCell('A' . $cellCordinateRow)->getHyperlink()->setUrl("sheet://'Data $sheet'!A{$cellCordinateRow}");
        }

        return $PHPExcelSheet;
    }

感谢马克提供 $this->addSummarySheet() 提示。真的很有帮助。