php lumen 批量导入excel 文件 有时候总列数是 两个字母

首先,我用的项目环境是 lumen 6.0X, php 7.4,下一步lumen是需要安装 phpexcel扩展的,至于步骤,随便百度一下就有很多,只是简单写一下
导出文件 ,对于没有安装的,懒得百度的,可以走一遍这个流程
1、安装 maatwebsite/excel

composer require maatwebsite/excel

2、在bootstrap/app.php中加入 (就是注册)

$app->register(Maatwebsite\Excel\ExcelServiceProvider::class);

3、修改配置获取方式 (在配置里加些东西,理论上加不加应该都可以,会有默认值)

Maatwebsite\Excel\Readers\LaravelExcelReader.php 查找 Config::get 替换为 config

4、走完上面三步,就可以使用了,不过有一个令人头疼的地方就是,镜像是国内的话,会很慢,当初我也是用的国外的代理。
懒得改代码了,就说一下业务场景吧,我们是做考试系统的,里面有excel 导入试题,我们是后端只负责接收excel路径,前端会有专门接口上传文件,我们要做的就是获取前端传过来的 excel,咳咳,有点跑题了,说导入呢

下面贴导入代码:

validate($request, [
                'period_id' => 'required|string',
                'ques_url' => 'required|string',
            ]);
        } catch (\Exception $e) {
            throw new CommonapiException('param_error');
        }
        $input = $request->post();
        $file =  $request->post('ques_url');
        //下载到本地
        $localName = '/tmp/' . time() . mt_rand(1000, 9999) . '.xls';
        $fp_input = fopen($file, 'r');
        file_put_contents($localName, $fp_input);
        header("Content-type: text/html; charset='utf-8'");
        //读取excel内容
        $res = [];
        error_reporting(0);
        Excel::load($localName, function ($objPHPExcel) use (&$res) {
            $sheet = $objPHPExcel->getSheet(0);	 //指定的表
            $highestRow = $sheet->getHighestDataRow(); // 取得总行数
            $highestColumn = $sheet->getHighestDataColumn(); // 取得总列数
            $arr = array();
            $ques = array();

            //从2行开始读起
            for ($i = 2; $i <= $highestRow; $i++) {
                if (($sheet->getCell("A" . $i)->getValue()) != NULL) {
                    $questype = trim($sheet->getCell("A" . $i)->getValue());
                    $ques[$i]['ques_type'] = $this->quesTypeBack($questype);
                    if($highestColumn == "L"){
                        $ques_diff = $this->str_rep($sheet->getCell("J" . $i)->getValue());
                        $is_pratice = $this->str_rep($sheet->getCell("K" . $i)->getValue());
                        $ques_diff = $this-> quesDiffBack($ques_diff);
                        $is_pratice =  $this-> quesTestBack($is_pratice);
                        $ques[$i]['ques_body'] = $this->str_rep($sheet->getCell("B" . $i)->getValue());
                        $ques[$i]['ques_choice_a']   = $this->str_rep($sheet->getCell("C" . $i)->getValue());
                        $ques[$i]['ques_choice_b']   = $this->str_rep($sheet->getCell("D" . $i)->getValue());
                        $ques[$i]['ques_choice_c']   = $this->str_rep($sheet->getCell("E" . $i)->getValue());
                        $ques[$i]['ques_choice_d']   = $this->str_rep($sheet->getCell("F" . $i)->getValue());
                        $ques[$i]['ques_answer']     = $this->str_rep($sheet->getCell("G" . $i)->getValue());
                        $ques[$i]['ques_answer_key'] = $this->str_rep($sheet->getCell("H" . $i)->getValue());
                        $ques[$i]['ques_score']      = $this->str_rep($sheet->getCell("I" . $i)->getValue());
                        $ques[$i]['ques_difficulty'] = $ques_diff;
                        $ques[$i]['is_pratice']      = $is_pratice;
                        $ques[$i]['ques_memo']       = $this->str_rep($sheet->getCell("L" . $i)->getValue());
                    }
                    $answer = $ques[$i]['ques_answer'];
                    //字母全角转半角
                    if ($questype == "单选题" || $questype == "多选题" || $questype == "判断题") {
                        $ques[$i]['ques_answer'] = trim($this->SBC_DBC($answer, 1));
                    }

                    if ($questype == "判断题") {
                        if ($answer == '对' || $answer == '是' || $answer == '正确') {
                            $ques[$i]['ques_answer'] = "A";
                        }
                        if ($answer == '错' || $answer == '否' || $answer == '错误') {
                            $ques[$i]['ques_answer'] = "B";
                        }
                    }
                    //防止填空题答案为空
                    if ($questype == "填空题") {
                        if ($answer == '') {
                            $ques[$i]['ques_answer'] = '*空*';
                        } else {
                            $answer = preg_replace('/\s/', '', $answer);//填空题答案去空格
                            $answer = preg_replace('/,/', ',', $answer);//填空题中文逗号变英文逗号
                            $ques[$i]['ques_answer'] = $answer;
                        }
                    }
                    //防止问答题答案为空
                    if ($questype == '问答题') {
                        if ($answer == '') {
                            $ques[$i]['ques_answer'] = '*答案略*';
                        }
                    }
                }
            }

            $res['ques'] = $ques;
        });

        $res['period_id'] = $request->post('period_id');
        $result = $this->tklibInnerObj->revokeurl($this->sysname, 'ques/quesImport', $res);
        $status = $result['code'] ?? '';
        if (empty($status) || $status != 1) {
            return $this->render([], '获取失败', 0);
        }
        return $this->render($result['data']);
    }
}

代码太废了,说主要的,先引入

use Maatwebsite\Excel\Facades\Excel;


然后就是使用 excel

 Excel::load($localName, function ($objPHPExcel) use (&$res) {
     $sheet = $objPHPExcel->getSheet(0);	 //指定的表
     $highestRow = $sheet->getHighestDataRow(); // 取得总行数
     $highestColumn = $sheet->getHighestDataColumn(); // 取得总列数
     ......你的逻辑代码
 }

我写的代码有些low,见谅以前用CI3版本的,用习惯了,导入的话自然而然也就按照以前方式来了,值得注意的是:
$sheet = $objPHPExcel->getSheet(0);     //指定的表
 $highestRow = $sheet->getHighestDataRow(); // 取得总行数
 $highestColumn = $sheet->getHighestDataColumn(); // 取得总列数
这三行,有时候我获取excel内的列数、行数总是不准的,尤其是列数,有可能出来的不是数字,是两个字母,头疼了小半天,最后决定牺牲一些效率,用这种方法获取总行数跟列数:getHighestDataRow、getHighestDataColumn  就好了
当然了还有其他简单的方法,直接将每行每列搞成数组去处理,也可以,就像这样

    public function uploadUni(Request $request)
    {
        $file = $request->post('file');
        //下载到本地
        $localName = '/tmp/' . time() . mt_rand(1000, 9999) . '.xls';
        $fp_input = fopen($file, 'r');
        file_put_contents($localName, $fp_input);

        header("Content-type: text/html; charset=gbk");
        //读取excel内容
        $res = [];
        
        Excel::load($localName, function ($reader) use (&$res) {
            $reader = $reader->getSheet(0);
            $res = $reader->toArray();
        });
        //删除文件
        @unlink($localName);
        //开启事务,插入多个表
        DB::beginTransaction();
        try {
            //插表啊啊啊啊啊啊啊
            DB::commit();
        } catch (Exception $e) {
            DB::rollback();
            return $this->render([], '操作失败', 0);
        }
     }

其中 $res 就是一个二维数组,随便你怎么处理(删除文件下面的代码就不用看了,跟导入无关,是我跑题了)
 

导出excel的话,我有列表页接口,前端会在本地建一个excel,多次调用列表页接口,追加到excel就行,最后前端下载,这样不会有服务器端的超时问题
 

导出代码(导入都写了,导出随便搜一个吧)

public function cand_export(){
    $cellData = [
        [' 学号 ',' 姓名 ',' 编号'],
        ['10001','AAAAA','100001'],
        ['10002','BBBBB','100002'],
    ];

    Excel::create ('score',function ($excel) use ($cellData){
        $excel->sheet('score', function($sheet) use ($cellData){
            $sheet->rows($cellData);
        });
     })->export('xls');
}

 

你可能感兴趣的:(php)