前言:   

在业务中开发中,表格的导入导出功能很常见。但是这里主要是使用PhpOffice类库介绍实现导入表格数据的功能。

冲突:

大部分的导入功能,就是通过点击按钮上传一张表格,然后后台读取表格数据根据业务整理后直接插入到数据库,最后再返回给前端。但是如果表格数据庞大,业务逻辑复杂的时候,就会导致导入那一块很臃肿不好维护。

解决方法:

处理方式是把导入与业务数据插入分离,所以在二者之间添加一个队列就可以了。导入只负责将表格数据存入队列。业务部分可以是单独的系统,最后就是消费队列中的数据了。这样一来,不但提升了导入速度,而且还让导入与系统解耦,不会因为异常而影响到其他业务。

编码:

1. 下载PhpOffice。

composer repuire phpoffice/phpspreadsheet

2. 导入导出代码。

<?php namespace app\common\helper;use PhpOffice\PhpSpreadsheet\Spreadsheet;use PhpOffice\PhpSpreadsheet\Writer\Xlsx;use PhpOffice\PhpSpreadsheet\IOFactory;use PhpOffice\PhpSpreadsheet\Cell\Coordinate;use think\Exception;class Excel{// 导出public function outPut($data, $columns, $table = '导出文件'){        $spreadsheet = new Spreadsheet();        $sheet = $spreadsheet->getActiveSheet();// 设置第一栏的标题foreach ($columns as $k => $v) {            $sheet->setCellValue($k . "1", $v['title']);        }//第二行起 设置内容        $baseRow = 2; //数据从N-1行开始往下输出 这里是避免头信息被覆盖foreach ($data as $key => $value) {foreach ($columns as $k1 => $v1) {                $i = $key + $baseRow;                $sheet->setCellValue($k1 . $i, $value[$v1['field']]);            }        }        $writer = new Xlsx($spreadsheet);        $filename = $table . date("Y-m-d", time()) . '_' . time() . '.xlsx';        $writer->save('./excel/' . $filename);return '/excel/' . $filename;    }// 导入public function importExcel($file = '', $sheet = 0, $columnCnt = 0, &$options = []){try {            $file = iconv("utf-8", "gb2312", $file);if (empty($file) OR !file_exists($file)) {throw new \Exception('文件不存在!');            }            $objRead = IOFactory::createReader('Xlsx');if (!$objRead->canRead($file)) {                $objRead = IOFactory::createReader('Xls');if (!$objRead->canRead($file)) {throw new \Exception('只支持导入Excel文件!');                }            }/* 如果不需要获取特殊操作,则只读内容,可以大幅度提升读取Excel效率 */empty($options) && $objRead->setReadDataOnly(true);/* 建立excel对象 */            $obj = $objRead->load($file);/* 获取指定的sheet表 */            $currSheet = $obj->getSheet($sheet);//$currSheet = $obj->getSheetByName($sheet);      // 根据名字if (isset($options['mergeCells'])) {/* 读取合并行列 */                $options['mergeCells'] = $currSheet->getMergeCells();            }if (0 == $columnCnt) {/* 取得最大的列号 */                $columnH = $currSheet->getHighestColumn();/* 兼容原逻辑,循环时使用的是小于等于 */                $columnCnt = Coordinate::columnIndexFromString($columnH);            }/* 获取总行数 */            $rowCnt = $currSheet->getHighestRow();            $data = [];/* 读取内容 */for ($_row = 1; $_row <= $rowCnt; $_row++) {                $isNull = true;for ($_column = 1; $_column <= $columnCnt; $_column++) {                    $cellName = Coordinate::stringFromColumnIndex($_column);                    $cellId = $cellName . $_row;                    $cell = $currSheet->getCell($cellId);if (isset($options['format'])) {/* 获取格式 */                        $format = $cell->getStyle()->getNumberFormat()->getFormatCode();/* 记录格式 */                        $options['format'][$_row][$cellName] = $format;                    }if (isset($options['formula'])) {/* 获取公式,公式均为=号开头数据 */                        $formula = $currSheet->getCell($cellId)->getValue();if (0 === strpos($formula, '=')) {                            $options['formula'][$cellName . $_row] = $formula;                        }                    }if (isset($format) && 'm/d/yyyy' == $format) {/* 日期格式翻转处理 */                        $cell->getStyle()->getNumberFormat()->setFormatCode('yyyy/mm/dd');                    }                    $data[$_row][$cellName] = trim($currSheet->getCell($cellId)->getFormattedValue());if (!empty($data[$_row][$cellName])) {                        $isNull = false;                    }                }if ($isNull) {unset($data[$_row]);                }            }return $data;        } catch (\Exception $e) {throw $e;        }    }}

3. 抽取指定的字段格式化Excel数据。

return [

// 导入的表格标题"bidding" => ["stock_no" => "编号","price" => "价格","mobile" => "手机","nickname" => "姓名"    ]

];

// 格式化指定列数据(默认第一行表头)public static function formattingCells(array $data, array $cellConfig){  $res = array_values($data);

// 表头 $header = $res[0];

 $cellKeys = [];foreach ($header as $key => $value) {foreach ($cellConfig as $k => $v) {if ($value == $v) {               $cellKeys[$key] = $k;            }     } }

if (count($cellKeys) != count($cellConfig)) {throw new Exception('表格不完整');  }

// 需要添加过滤    $temp = [];for ($i = 1; $i <= count($res) - 1; $i++) {foreach ($cellKeys as $m => $n) {           $temp[$i][$n] = $res[$i][$m];        } }

return array_values($temp);}

4. 导入部分,上传接口。

// 导入表格,上传接口public function importExcel(){ $upload_file = $_FILES['files']['tmp_name']; $input = $this->input;

// ID   $id = isset($input['id']) ? $input['id'] : 0;

// 默认取第一工作表 $excelData = (new Excel())->importExcel($upload_file, 0);

// 取Excel字段  $config = config('excel_export.bidding');

    $price_offer = Excel::formattingCells($excelData, $config);

// 判断每条记录的手机和价格格式// ……

    $jsonList = json_encode(compact('id', 'price_offer'));//$jsonList = json_encode($price_offer);

// 入MQ  $host = config("mq.host"); $options = config("mq.price_offer_import");

try {       $mq = new ProductMQ($host, $options);

      $mq->publish($jsonList);

     $mq->close();

    } catch (\Exception $e) {return $this->jsonData(200, $e->getMessage());   }// 入MQ

return $this->jsonData(200, '导入成功');}

5. 消费业务逻辑。

实现excel导入_PhpOffice实现Excel表格导入的解耦方法相关推荐

  1. excel怎么设置自动计算_excel表格设置自动计算的方法步骤(2)

    Excel函数求最高值的方法 1.下图是一个电子表格范例,我们要求全班同学在每个科目中的最高分. Excel函数求最高值的方法图1 2.鼠标选中如图中高等数学的最高分单元格,即B11. Excel函数 ...

  2. excel数据整理:网络表格数据规范处理方法

    网络数据整理一直是个难题.导出的网络数据要么是单列的,要么是有一些特殊符号,都需要整理后才能使用.譬如如何把单列数据按属性变成多列数据? Excel新人.老手各有自己的一套方法,从匪夷所思的查找替换到 ...

  3. h5页面如何预览excel文件_如何使用JavaScript实现前端导入和导出excel文件?(H5编辑器实战复盘)...

    前言 最近笔者终于把H5-Dooring的后台管理系统初步搭建完成, 有了初步的数据采集和数据分析能力, 接下来我们就复盘一下其中涉及的几个知识点,并一一阐述其在Dooring H5可视化编辑器中的解 ...

  4. 如何使用JavaScript实现前端导入和导出excel文件(H5编辑器实战复盘)

    前言 最近笔者终于把H5-Dooring的后台管理系统初步搭建完成, 有了初步的数据采集和数据分析能力, 接下来我们就复盘一下其中涉及的几个知识点,并一一阐述其在Dooring H5可视化编辑器中的解 ...

  5. mysql数据库导入到excel表格数据_[转载]将EXCEL表格中的数据导入mysql数据库表中(两种方法)...

    今天项目上遇到需要将excel中的数据导入到数据库的classify表中,于是乎拼命上网查阅方法,发现以下两种方法比较可行: 在此之前先说说按照网上的说法我没有试验成功的方法,将excel文件xls保 ...

  6. oracle导出一个表数据库,excel怎么导出多个表格数据库数据-一个excel表格中有多个sheet,如何将其导入oracle数......

    一个excel表格中有多个sheet,如何将其导入oracle数... 解决方案如下: 可以新建一个查询,查询你所说的2个表中的所有数据 运行查询,这样查询结果就包含了你要的数据,再把查询结果导出 就 ...

  7. excel表格导入功能

    1.表格导入方法 (1)首先jsp文件中加入对应的HTML样式,并调用对应js中的方法 <em class="separ"></em><a class ...

  8. 如何在ex表格导入php_怎么使用php把表格中的数据导入到excel中,php如何快速导入excel表格数据...

    php怎么导入大量数据的excel php导出数据的Excel: PHP从数据库分多次读取100万行记录,和分将100万入文本文件都没问题 Excel可以支100万行记录,Excel 2003最大支持 ...

  9. 关于怎么把Excel表格导入MySQL数据库中

    关于怎么把Excel表格导入MySQL数据库中 第一步:建造Excel表格并且编辑数据. 1.我们要建立一个Excel表格文件 2.编辑我们需要的数据 3.保存到你知道的位置 第二步:在MySQL中建 ...

最新文章

  1. jupyter怎么调字体_AJ里最低调的系列之一:Air Jordan 3
  2. linux epoll模型
  3. 为什么不能够用unsigned 修饰 float和double
  4. python处理大量excel数据-python如何批量处理excel数据?
  5. JVM:-Xmx和-Xms应该维持什么样的比例?
  6. linux签名服务器,linux – 如何在远程服务器上使用gpg签名密钥?
  7. 余弦函数导数推导过程_人工智能数学基础----导数
  8. metadata usage in the runtime
  9. 2013年08月13日
  10. 图书管理系统_目前图书管理系统存在的问题
  11. java 多线程 实例浅析
  12. 杭电 4907 Task schedule ·
  13. Lamp兄弟连Linux视频教程
  14. Linux实现倒计时显示时分QT,qt实现倒计时示例
  15. 我国5G现状:今年底或发放5G牌照
  16. 精美摘抄,献给每一位喜欢文学的人
  17. OOP-面向对象程序设计
  18. 深入理解内存:原理简介
  19. STM32连接TFT-LCD
  20. python中异或运算_Tensorflow轻松实现XOR运算的方式

热门文章

  1. 西班牙人:武磊身体无恙 可以出场比赛
  2. 环境搭建-CentOS集群搭建
  3. 笔者使用macOS的一些经验点滴记录1
  4. PHP 01 Apache HTTP
  5. apache ab测试与centos系统优化
  6. SQL Server还原和一些小发现
  7. A ndroid 获取屏幕高度、标题高度、状态栏高度详解
  8. Windows8测试版使用感受
  9. java和python和php_Java、Python和PHP三者的区别
  10. 一网打尽软件测试面试必问的所有Web测试点,你不知道的这都有!