PHP操作Excel插件phpspreadsheet

phpspreadsheet 插件

之前PHP操作Excel数据时都是使用PHPExcel库,但是phpoffice已经官方宣布PHPExcel已经被废弃不在维护,所以改用PHPExcel插件了。

安装

composer require phpoffice/phpspreadsheet

使用

因为一般业务给的Excel表格都比较大,所以需要分页处理,项目使用的是laravel框架。

首先创建一个分页的函数:

class ChunkReadFilter implements \PhpOffice\PhpSpreadsheet\Reader\IReadFilter
	{
	    private $startRow = 0;
	    private $endRow   = 0;
	
	    /**  Set the list of rows that we want to read  */
	    public function setRows($startRow, $chunkSize) {
	        $this->startRow = $startRow;
	        $this->endRow   = $startRow + $chunkSize;
	    }
	
	    public function readCell($column, $row, $worksheetName = '') {
	        //  Only read the heading row, and the configured rows
	        if (($row == 1) || ($row >= $this->startRow && $row < $this->endRow)) {
	            return true;
	        }
	        return false;
	    }
	}

分页读出Excel表格内容:

try {
            $inputFileType = self::getFileType($filePath);
            if (!$inputFileType) {
                Log::error(sprintf('获取文件类型失败%s', $filePath));

                return null;
            }
            $reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader($inputFileType);

            $chunkFilter = new ChunkReadFilter();
            $reader->setReadFilter($chunkFilter);

            while (true) {
                $startRow = 2 + $perpage * $page;
                $chunkFilter->setRows($startRow, $perpage);
                $spreadsheet = $reader->load($filePath);
                $sheet       = $spreadsheet->getActiveSheet();
                $sheetData   = $sheet->toArray(null, true, true, true);
                $sheetData   = array_slice($sheetData, $startRow - 1, $perpage);
                if (empty($sheetData)) {
                    break;
                }

                $this->importDatas($sheetData, $total, $success);    //业务处理函数
                Log::info('第'.$i.'页导入'.$i);

                $i++;
                $page++;
                usleep(300000);
            }
        } catch (\Exception $e) {
            Log::error(
                sprintf(
                    'getFileContent error, file:%s, error: %s',
                    $filePath,
                    $e->getMessage()
                )
            );

            return null;
        }
	
	//获取文件类型函数
	private static function getFileType($file)
    {
        $fileExtentsion = pathinfo($file, PATHINFO_EXTENSION);
        if ($fileExtentsion == "xlsx") {
            return "Xlsx";
        }
        if ($fileExtentsion == "xls") {
            return "Xls";
        }
        if ($fileExtentsion == "csv") {
            return "Csv";
        }

        return null;
    }

这样就能分页处理Excel表格了。

此方法及其容易引起内存溢出,因为这种分页的实现是先将分页数据前的数据读入内存,再从你要的数据开始返回你的分页数,当page越大时,需要load进内存的记录越多,当达到一定的数量就会发生溢出。

phpspreadsheet官网针对内存溢出给出了解决方案。。。

你可能感兴趣的:(PHP)