zoukankan      html  css  js  c++  java
  • php添加excel更新数据表数据

    公司有个需求,是用excel更新数据的,把错误的行列放到一个数组返回出来,正常的数据则插入,且返回数量

    1.先需要引入phpspreadsheet,这里使用composer 安装

    composer require phpoffice/phpspreadsheet

    2.还需要在头部引入,命名空间自己根据vendor目录设置

    use Exception;
    use PhpOfficePhpSpreadsheetCellCoordinate;
    use PhpOfficePhpSpreadsheetReaderXlsx;
    use PhpOfficePhpSpreadsheetReaderXls;
    use PhpOfficePhpSpreadsheetReaderCsv;

    3.下面就是相关代码了,其实逻辑很简单,把excel导入的数据和数据表的字段拼接成二维数组,然后插入就行了

      /**
       * excel开启上传
       * author: panzhide
       * @return array
       * Date: 2020/9/4
       */
      public function logisticsImportExcel()
      {
        $file = request()->file('file');
        if (!$file) {
          return json_success('excel文件不能为空', 'file');
        }
        //将文件保存到public/storage/uploads/目录下面
        $savename = 	hinkFacadeFilesystem::disk('public')->putFile('uploads', $file);
    
        //获取文件路径
        $filePath = getcwd() . '/storage/' . $savename;
        if (!is_file($filePath)) {
          return json_success('没有发现结果');
        }
        //实例化reader
        $ext = pathinfo($filePath, PATHINFO_EXTENSION);
        if (!in_array($ext, ['csv', 'xls', 'xlsx'])) {
          return json_success('未知的数据格式');
        }
        if ($ext === 'csv') {
          $file = fopen($filePath, 'r');
          $filePath = tempnam(sys_get_temp_dir(), 'import_csv');
          $fp = fopen($filePath, "w");
          $n = 0;
          while ($line = fgets($file)) {
            $line = rtrim($line, "
    
    ");
            $encoding = mb_detect_encoding($line, ['utf-8', 'gbk', 'latin1', 'big5']);
            if ($encoding != 'utf-8') {
              $line = mb_convert_encoding($line, 'utf-8', $encoding);
            }
            if ($n == 0 || preg_match('/^".*"$/', $line)) {
              fwrite($fp, $line . "
    ");
            } else {
              fwrite($fp, '"' . str_replace(['"', ','], ['""', '","'], $line) . ""
    ");
            }
            $n++;
          }
          fclose($file) || fclose($fp);
    
          $reader = new Csv();
        } elseif ($ext === 'xls') {
          $reader = new Xls();
        } else {
          $reader = new Xlsx();
        }
    
        //导入文件首行类型,默认是注释,如果需要使用字段名称请使用name
        $importHeadType = isset($this->importHeadType) ? $this->importHeadType : 'comment';
        //默认的表名
        $table = OrderAddress::build()->getTable();
    
        $fieldArr = [];
        $list = Db::query('SHOW FULL COLUMNS FROM `' . $table . '`');
        foreach ($list as $k => $v) {
          if ($importHeadType == 'comment') {
            $fieldArr[$v['Comment']] = $v['Field'];
          } else {
            $fieldArr[$v['Field']] = $v['Field'];
          }
        }
    
        //加载文件
        $insert = [];
        try {
          if (!$PHPExcel = $reader->load($filePath)) {
            return json_success('未知的数据格式');
          }
          $currentSheet = $PHPExcel->getSheet(0);  //读取文件中的第一个工作表
          $allColumn = $currentSheet->getHighestDataColumn(); //取得最大的列号
          $allRow = $currentSheet->getHighestRow(); //取得一共有多少行
          $maxColumnNumber = Coordinate::columnIndexFromString($allColumn);
          $fields = [];
          for ($currentRow = 1; $currentRow <= 1; $currentRow++) {
            for ($currentColumn = 1; $currentColumn <= $maxColumnNumber; $currentColumn++) {
              $val = $currentSheet->getCellByColumnAndRow($currentColumn, $currentRow)->getValue();
              $fields[] = $val;
            }
          }
    
          for ($currentRow = 2; $currentRow <= $allRow; $currentRow++) {
            $values = [];
            for ($currentColumn = 1; $currentColumn <= $maxColumnNumber; $currentColumn++) {
              $val = $currentSheet->getCellByColumnAndRow($currentColumn, $currentRow)->getValue();
              $values[] = is_null($val) ? '' : $val;
            }
            $row = [];
            $temp = array_combine($fields, $values);
            foreach ($temp as $k => $v) {
              if (isset($fieldArr[$k]) && $k !== '') {
                $row[$fieldArr[$k]] = $v;
              }
            }
            if ($row) {
              $insert[] = $row;
            }
          }
        } catch (Exception $exception) {
          return json_success($exception->getMessage());
        }
    
        if (!$insert) {
          return json_success('没有更新行');
        }
    
        $n = 0;
        foreach ($insert as $key => $value) {
          $n++;
          if (!$value['logistics_sn']) {
            $error[] = '第' . $n . '行物流编号不得为空';
          } else {
            $kuaidicom_code = KuaidiCode::build()->where('name', $value['kuaidicom'])->find();
            if (!$kuaidicom_code) {
              $error[] = '第' . $n . '行' . $value['kuaidicom'] . '物流公司不支持';
            } else {
              $info = OrderAddress::build()->where('order_sn', $value['order_sn'])->find();
              if (!$info) {
                $error[] = '第' . $n . '行订单不存在';
              } else {
                $update_data['kuaidicom_code'] = $kuaidicom_code['code'];
                $update_data['update_time'] = time();
                $update_data['order_sn'] = $value['order_sn'];
                $update_data['kuaidicom'] = $value['kuaidicom'];
                $update_data['logistics_sn'] = $value['logistics_sn'];
                $update_data['id'] = $info['id'];
                $update_data_list[] = $update_data;
              }
            }
          }
        }
        $this->logisticsImportExcelUpdate($update_data_list);
        $msg = '导入成功,共整合更新' . count($update_data_list) . '条订单数据';
        return json_success($msg, $error);
      }
    
      private function logisticsImportExcelUpdate($update_data_list)
      {
        Db::startTrans();
        try {
          OrderAddress::build()->saveAll($update_data_list);
        } catch (Exception $e) {
          Db::rollback();
          $msg = $e->getMessage();
          return json_success($msg);
        } catch (Exception $e) {
          Db::rollback();
          return json_success($e->getMessage() . $e->getLine());
        }
        Db::commit();
      }
     
  • 相关阅读:
    求字符串中最大的递增子序列
    分析函数改写自关联
    收集统计信息让SQL走正确的执行计划
    利用case when 减少表扫描次数
    利用查询提示优化SQL
    利用SQL进行推理
    查找字段连续相同的最大值
    优化有标量子查询的SQL
    将部分相同的多行记录转成一行多列
    .net 测试工具类
  • 原文地址:https://www.cnblogs.com/seanpan/p/14661793.html
Copyright © 2011-2022 走看看