使用phpexcel分批处理excel数据

程斌 2019-05-26 PM 2462℃ 4条

需求

需要将一个大文件Excel,导入数据库。

思路

通过内存监测,phpexcel load方法载入excel文件的时候,会内存溢出,很多时候就会想当然的去适当的把php的内存配置调大。我认为这种方式,可行,但是要根据具体的业务来分析,如果业务本身都不清晰将来导入的文件大小,这种调节配置内存的方式,也就不能从根本上解决问题。所有,采用分页分批次的处理方式该问题。
接下来,我们通过phpexcel功能库来分批次处理大文件Excel。

自定义拦截器

class MyReadFilter implements \PHPExcel_Reader_IReadFilter
{
    public $startRow = 1;
    public $endRow;

    public function readCell($column, $row, $worksheetName = '') {
        //如果endRow没有设置表示读取全部
        if (!$this->endRow) {
            return true;
        }
        //只读取指定的行
        if ($row >= $this->startRow && $row <= $this->endRow) {
            return true;
        }

        return false;
    }
}

使用自定义过滤器,分页载入excel

// 是否结束
$isEnd = false;
// 当前页面
$pageIndex = 0;
// 每页大小,pagesize
$ps = 20;
do {
            $pageIndex++;
            echo "PAGE::". $pageIndex . PHP_EOL;
            echo 'rowReadData::PAGE::MEMORY::' . round(memory_get_usage()/1024/1024, 2).'MB'.PHP_EOL;
            // 计算分页参数,因为第一行是标题 +1,这里是要得到读取的行数,所有从1开始 +1,整体 +2
            $begin = ($pageIndex-1)*$ps+2;
            $end = $begin + $ps;
            // 加入拦截器,载入文件
            $perf           = new MyReadFilter();
            $perf->startRow = $begin;
            $perf->endRow   = $end;
            $PHPReader->setReadFilter($perf);
            $phpexcel    = $PHPReader->load($filePath);
            $activeSheet = $phpexcel->getSheet(0);  //读取文件中的第一个工作表
            $highestColumn      = $activeSheet->getHighestColumn(); //最后列数所对应的字母,例如第2行就是B
            $highestColumnIndex = \PHPExcel_Cell::columnIndexFromString($highestColumn); //总列数
            $data = array();
            // 循环读取,每次读取20行
            for($i=$begin; $i<$end; $i++) {
                echo "ROW::". $i . PHP_EOL;
                echo 'rowReadData::PAGE::ROW::MEMORY::' . round(memory_get_usage()/1024/1024, 2).'MB'.PHP_EOL;
                $values = [];
                for ($col = 0; $col < $highestColumnIndex; $col++) {
                    $val = (string) $activeSheet->getCellByColumnAndRow($col, $i)->getValue();
                    // 读取到空行了,break,结束
                    if($col == 0 && empty($val)) {
                        $isEnd = true;
                        break 2;
                    }
                    $values[] = $val;
                }

                $c = count($fields) - count($values);
                for ($ti=0; $ti<$c;$ti++) {
                    $values[]= "";
                }

                $rowData = [];
                $temp = array_combine($fields, $values);
                foreach ($temp as $k => $v) {
                    if (isset($fieldArr[$k]) && $k !== '') {
                        $rowData[$fieldArr[$k]] = $v;
                    }
                }

                if ($rowData) {
                    $count = $userTable->where(['username' => $rowData['username']])->count();
                    if ($count > 0) {
                        continue;
                    }
                    if (isset($rowData['exptime']) && $rowData['exptime'] != "0000-00-00 00:00:00") {
                        $rowData['exptime'] = strtotime($rowData['exptime']);//\PHPExcel_Shared_Date::ExcelToPHP($rowData['exptime']);
                    } else {
                        $rowData['exptime'] = 0;
                    }
                    $data[] = $rowData;
                }
            }

            if($data) {
                $result = $userTable->insertAll($data);
                if(false === $result) {
                    Db::name('user_import_list')
                        ->where(['id'=>$id])
                        ->update(
                            [
                                'status'=>'clcw',
                                'index_row' => $begin
                            ]);
                    return false;
                }
            }

        } while(!$isEnd);

效果截图(29500行数据)

导入效果图

标签: none

非特殊说明,本博所有文章均为博主原创。

上一篇 一天过
下一篇 支付宝APP支付

评论啦~



已有 4 条评论


  1. 温

    Notice: Undefined variable: group in /home/wwwroot/www.chengbin.name/usr/themes/echo/comments.php on line 34

    你好啊,能提供一下html和js这些代码吗?

    回复 2019-06-25 14:28
  2. 温

    Notice: Undefined variable: group in /home/wwwroot/www.chengbin.name/usr/themes/echo/comments.php on line 34

    能给完整的代码吗?包括html和js,我允许的时候报错了

    回复 2019-06-25 14:43
    1. 红酒花生
      红酒花生 博主

      我在命令行下边执行的,没有什么其他的代码,都是PHP的代码。

      回复 2019-07-10 11:56
  3. 红酒花生
    红酒花生 博主

    我在命令行下边执行的,没有什么其他的代码,都是PHP的代码。

    回复 2019-07-10 11:56