2023年6月21日发(作者:)
PHP操作Excel插件phpspreadsheetphpspreadsheet 插件之前PHP操作Excel数据时都是使⽤PHPExcel库,但是phpoffice已经官⽅宣布PHPExcel已经被废弃不在维护,所以改⽤PHPExcel插件了。安装composer require phpoffice/phpspreadsheet使⽤因为⼀般业务给的Excel表格都⽐较⼤,所以需要分页处理,项⽬使⽤的是laravel框架。⾸先创建⼀个分页的函数:class ChunkReadFilter implements PhpOfficePhpSpreadsheetReaderIReadFilter { 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 = PhpOfficePhpSpreadsheetIOFactory::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官⽹针对内存溢出给出了解决⽅案。。。
2023年6月21日发(作者:)
PHP操作Excel插件phpspreadsheetphpspreadsheet 插件之前PHP操作Excel数据时都是使⽤PHPExcel库,但是phpoffice已经官⽅宣布PHPExcel已经被废弃不在维护,所以改⽤PHPExcel插件了。安装composer require phpoffice/phpspreadsheet使⽤因为⼀般业务给的Excel表格都⽐较⼤,所以需要分页处理,项⽬使⽤的是laravel框架。⾸先创建⼀个分页的函数:class ChunkReadFilter implements PhpOfficePhpSpreadsheetReaderIReadFilter { 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 = PhpOfficePhpSpreadsheetIOFactory::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官⽹针对内存溢出给出了解决⽅案。。。
发布评论