背景
PHP解析Excel有个比较有名的库是phpoffice/phpexcel。在实际使用的过程中,解析一两百行的Excel没有问题,遇到上万行的Excel时,phpexcel的内存使用量会飙升,很容易就能超过128M造成内存溢出
安装box/spout
composer require box/spout
使用案例
<?php
require 'vendor/autoload.php'; // 包含 Composer 自动生成的自动加载文件
use Box\Spout\Reader\Common\Creator\ReaderEntityFactory;
// 命令行参数变量
$console = array();
if (preg_match_all('/--(\w+)(=(.*?)(?=\s--|$))?/u', implode(' ', array_slice($_SERVER['argv'] /*获取命令行参数的完整字符串*/, 1)), $matches)) {
$console = [];
for ($i = 0; $i < count($matches[0]); $i++) {
$key = $matches[1][$i];
$value = $matches[3][$i];
$console[$key] = $value;
}
$filedMap = array(
'F' => 'file',
'L' => 'limit',
'H' => 'help'
);
foreach ($filedMap as $key => $item) {
if (isset($console[$key])) {
if (empty($console[$item]) && !empty($console[$key])) {
$console[$item] = $console[$key];
}
unset($console[$key]);
}
}
}
// 判断是否要获取使用方法
if (empty($console) || isset($console['help']) || empty($console['file'])) {
$errMsg = array(
'help:',
' as => php index.php --file=your_large_file.xlsx --limit=10',
'OR',
' as => php index.php --F=your_large_file.csv --L=0',
'',
''
);
die(implode(PHP_EOL.PHP_EOL, $errMsg));
}
// 从命令行获取excel资源路径
$filePath = $console['file'];
// 使用 Box/Spout 的工厂方法来自动识别文件类型
$reader = ReaderEntityFactory::createReaderFromFile($filePath);
// 设置编码(默认是按utf-8来读取文件)
// $reader->setEncoding('GB18030'); // 设置为GB18030编码
// $reader->setEncoding('UTF-8'); // 设置为UTF-8编码
// 打开文件
$reader->open($filePath);
$maxLimit = empty($console['limit'])? 0: $console['limit'];
foreach ($reader->getSheetIterator() as $sheet) {
foreach ($sheet->getRowIterator() as $row) {
// 处理每行的数据
$data = $row->toArray();
// $data 是一个包含每个字段的数组
print_r($data);
if (--$maxLimit === 0) {
$reader->close();
die();
}
}
}
$reader->close();