周大胖子 发表于 2020-8-5 17:28:24

laravel 上传的excel 批量上传,批量过滤 问题 ;

构思:

        1. 关于文件多少tab 页问题, 这个得是个循环;
       
        2. 关于如何 过滤到已经有的那些
       
                解决方案 1:
               
                        一条一条来吧 速度好像不行 太慢了 -.- ,先不管了开始一条一条来
                       
                       
                解决方案 2:
               
                        建议每一页都这样操作
                       
                        2.2.1 提取出 所有的 注册号, 搞成个 一位数组 comArr ;
                        2.2.2 对数据库来个 in 查询=》查询的结果提出来[只拿出注册号字段即可 ,也搞成个一维数组 myArr];
                        2.2.3 循环 所有要添加的数据,内部循环 myArr ,剔除掉 注册号重复的数据, 然后开始批量存; [建议分页操作]


                        过滤操作:
                               
                                1.过滤掉空的注册号
                                       
                                2.        过滤掉上传文件中重复的数据
                               
                                3.将上传文件 搞成一维数组 进行操作 ,再通过跟数据库比对,过滤掉 数据库中已经存在的注册号
                               
                               

实际代码:

    /**
   *类别        注册号        商标        注册日期[格式为2020-02-02]        使用商品        商品组别        法律状态[不可以超出徐峰的code 范围]        下证情况[有证、无证]备注       
   *参数   [ file => excel文件 ]
   *
   *访问路由: http://www.newadmin.com/comeExcel
   *
   */
    public function comeExcel(Request $request)
    {
      if (!$request->hasFile('file')) {
            return [
                'code' => 1,
                'message' => '未检索到上传文件'
            ];
      }
      // 解决问题
      // 1.把文件上传到 本系统
      $file = $request->file('file');

      //原文件名
      // $originalName = $file->getClientOriginalName();

      // 保存随机
      $file->getClientSize();

      //扩展名
      $ext = $file->getClientOriginalExtension();
   
      // 这段代码是用来处理导入时报的一个读取XML过大的错误
      Settings::setLibXmlLoaderOptions(LIBXML_COMPACT | LIBXML_PARSEHUGE);
      // 设置内存无限制
      ini_set('memory_limit', -1);

      $newName = 'is'.date('Y-m-d').time().'.'.$ext;
      // 存放到本地
      $path=$file->move('./uploads/excel/', $newName);

      $filePath = './uploads/excel/'.$newName;
   
      $array = Excel::toArray(new CmsSellTrademarkImport, $filePath);

      // return $array;

      // 拿到徐峰的编码值
      $stateCurrentArr = config('xufengcode.stateCurrentArr');
      $tradeCodeArr = config('xufengcode.tradeCodeArr');


      // 去掉 各个tab 页的分级 搞成一个最大的
      $newBaseArr = array();
      // 将$array 搞成一套维数组
      foreach ($array as $k => $v) {
            // var_dump(count($v));

            // 去掉各个tab 页头部的标记信息,先去掉一行
            array_splice($v, 0, 1);

            foreach ($v as $ak=>$av) {

                // 如果注册号不为空 [过滤掉空导入 ]
                if (!empty($av)) {
                  
                  // 在这里 对数据进行处理 这里是判断大类
                  if ($av<0 || $av>45) {
                        downjson(1, '上传文件数据异常,请认真检查[格式判定错误]');
                  }
                  if (empty($av)) {
                        downjson(1, '上传文件数据异常,请认真检查[商标名不能为空]');
                  }
                  // 匹配日期 [ 不按照 要求 匹配的 完全是 ]
                  if (preg_match('/^({4})-({2})-({2})$/', $av)) {
                        $av = $av;
                  } else {
                        $av = null;
                  }
                  // 过滤当前数值 将中文 换成数字
                  $av = array_search( $av, $stateCurrentArr);
                  $av = array_search( $av, $tradeCodeArr);
                  
                  //搞这个的目的 就是拆分一级 成为单一的一个数组 方便操作
                  $newBaseArr[] =$av;
                }
            }
      }

      // 数组去重[去掉文件中相同的 商标]
      array_unique($newBaseArr, SORT_REGULAR);

      $comArr=array();

      // 每一条 进行操作
      foreach ($newBaseArr as $k => $v) {

            // 1. 拿到所有注册号 下标 1 的时候,这是注册号所在的位置
            $comArr[] = $v;
      }

      // laravel 的in 查询
      $myArr = CmsSellTrademark::whereIn('tmNumberText', $comArr)->select('id', 'tmNumberText')->get()->toArray();

      // dd(count( $myArr) );

      // 循环数据库内的值筛选出数据库中已有的值 【这两个循环 位置颠倒 效果不一样】
      foreach ($myArr as $n => $m) {
            // 再循环每一条 进行操作
            foreach ($newBaseArr as $k => $v) {
            // var_dump($k); 事实证明 如果截取掉一部分,不影响 循环本身的长度似乎这个$value 已经被分配了一个 临时的值

                if ($v == $m['tmNumberText']) {
                  array_splice($newBaseArr, $k, 1);
                }
            }
      }
      // 去重失败
      // dd( count( $newBaseArr ));
      $intoNewBaseArr = count($newBaseArr);
      if($intoNewBaseArr == 0){
            return [
                'code' => 1,
                'message' => '请避免重复导入'
            ];
      }

      
      /*
      修改键值 [
            ctype => 国际分类
            tmNumberText => 申请号
            tmNameText => 商品名称
            registerDate => 注册日期    [格式必须为2020-02-02 ]
            stateCurrent => 商标状态   需要转化[此出得到的值newBaseArr 是转化后的] ,
            tradeCode=> 0、无证 ,1 有证    需要转化[此出得到的值newBaseArr 是转化后的] ,
      ]
      */
      $kname = array('ctype', 'tmNumberText', 'tmNameText', 'registerDate','tmGoodsName','likegroup','stateCurrent','tradeCode','remarks');

      // 调用公共方法 foo拼凑处json 数据
      array_walk($newBaseArr, 'foo', $kname);
            
      // 处理 并存入数据库 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
      // 拆开了再存[ 一次性插入过大就凉凉 所以拆开 每次500条 ]
      $t = array_chunk($newBaseArr, 100);

      foreach ($t as $v) {
            CmsSellTrademark::insert($v);
      }
      

      downjson(0, "导入成功",$intoNewBaseArr);
      
      //返回的数据 被数据库过滤掉了
      // return $newBaseArr;
    }
}




页: [1]
查看完整版本: laravel 上传的excel 批量上传,批量过滤 问题 ;