实现excel导入_PhpOffice实现Excel表格导入的解耦方法
前言:
在业务中开发中,表格的导入导出功能很常见。但是这里主要是使用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表格导入的解耦方法相关推荐
- excel怎么设置自动计算_excel表格设置自动计算的方法步骤(2)
Excel函数求最高值的方法 1.下图是一个电子表格范例,我们要求全班同学在每个科目中的最高分. Excel函数求最高值的方法图1 2.鼠标选中如图中高等数学的最高分单元格,即B11. Excel函数 ...
- excel数据整理:网络表格数据规范处理方法
网络数据整理一直是个难题.导出的网络数据要么是单列的,要么是有一些特殊符号,都需要整理后才能使用.譬如如何把单列数据按属性变成多列数据? Excel新人.老手各有自己的一套方法,从匪夷所思的查找替换到 ...
- h5页面如何预览excel文件_如何使用JavaScript实现前端导入和导出excel文件?(H5编辑器实战复盘)...
前言 最近笔者终于把H5-Dooring的后台管理系统初步搭建完成, 有了初步的数据采集和数据分析能力, 接下来我们就复盘一下其中涉及的几个知识点,并一一阐述其在Dooring H5可视化编辑器中的解 ...
- 如何使用JavaScript实现前端导入和导出excel文件(H5编辑器实战复盘)
前言 最近笔者终于把H5-Dooring的后台管理系统初步搭建完成, 有了初步的数据采集和数据分析能力, 接下来我们就复盘一下其中涉及的几个知识点,并一一阐述其在Dooring H5可视化编辑器中的解 ...
- mysql数据库导入到excel表格数据_[转载]将EXCEL表格中的数据导入mysql数据库表中(两种方法)...
今天项目上遇到需要将excel中的数据导入到数据库的classify表中,于是乎拼命上网查阅方法,发现以下两种方法比较可行: 在此之前先说说按照网上的说法我没有试验成功的方法,将excel文件xls保 ...
- oracle导出一个表数据库,excel怎么导出多个表格数据库数据-一个excel表格中有多个sheet,如何将其导入oracle数......
一个excel表格中有多个sheet,如何将其导入oracle数... 解决方案如下: 可以新建一个查询,查询你所说的2个表中的所有数据 运行查询,这样查询结果就包含了你要的数据,再把查询结果导出 就 ...
- excel表格导入功能
1.表格导入方法 (1)首先jsp文件中加入对应的HTML样式,并调用对应js中的方法 <em class="separ"></em><a class ...
- 如何在ex表格导入php_怎么使用php把表格中的数据导入到excel中,php如何快速导入excel表格数据...
php怎么导入大量数据的excel php导出数据的Excel: PHP从数据库分多次读取100万行记录,和分将100万入文本文件都没问题 Excel可以支100万行记录,Excel 2003最大支持 ...
- 关于怎么把Excel表格导入MySQL数据库中
关于怎么把Excel表格导入MySQL数据库中 第一步:建造Excel表格并且编辑数据. 1.我们要建立一个Excel表格文件 2.编辑我们需要的数据 3.保存到你知道的位置 第二步:在MySQL中建 ...
最新文章
- jupyter怎么调字体_AJ里最低调的系列之一:Air Jordan 3
- linux epoll模型
- 为什么不能够用unsigned 修饰 float和double
- python处理大量excel数据-python如何批量处理excel数据?
- JVM:-Xmx和-Xms应该维持什么样的比例?
- linux签名服务器,linux – 如何在远程服务器上使用gpg签名密钥?
- 余弦函数导数推导过程_人工智能数学基础----导数
- metadata usage in the runtime
- 2013年08月13日
- 图书管理系统_目前图书管理系统存在的问题
- java 多线程 实例浅析
- 杭电 4907 Task schedule ·
- Lamp兄弟连Linux视频教程
- Linux实现倒计时显示时分QT,qt实现倒计时示例
- 我国5G现状:今年底或发放5G牌照
- 精美摘抄,献给每一位喜欢文学的人
- OOP-面向对象程序设计
- 深入理解内存:原理简介
- STM32连接TFT-LCD
- python中异或运算_Tensorflow轻松实现XOR运算的方式