[TOC]
### 1、composer 安裝phpoffice/phpexcel
~~~
composer require phpoffice/phpexcel
~~~
### 2、通用建議放在common模塊
~~~
php think make:controller common/Import --plain
--plain 表示僅僅生成控制器
~~~
### 3、該控制器設置了兩種通用導出設置
~~~
1、commmonImport excel導入通用獲取數據--支持多個工作區
2、importBaseVerify excel導入數據基于基礎數據校驗
~~~
### 4、開始代碼之前說明
1.1 commmonImport通用導出需要引入
~~~
use app\common\controller\Files
//Files類--參考***Files通用封裝***
~~~
1.2 importBaseVerify通用導出需要引入
~~~
use app\common\controller\ImportBaseVerify
ImportBaseVerify類--參考***ImportBaseVerify輔助封裝***
~~~
### 5、開始commmonImport--直接看代碼
~~~
/**
* excel導入通用獲取數據--支持多個工作區
*
* @param array $map 參數值配置
* $map = [
* //每個數組的下標為工作區,確保采用的是正確的索引排序
* [
* 'row' => 2, //從第幾行開始讀取----行下標為1
* 'col' => 0, //從第幾列開始讀取----列下標為0
* 'firstHidden' => false //該參數配置的為true的話,表示在excel第一行隱藏了列對應的key值數據,返回的數據將會是以鍵值對返回
* ],
* [],
* ];
*
* @param string $path 文件路徑 如果默認為空,采用文件上傳方式
* @return array
*/
public static function commmonImport(array $map, $path = null)
{
if (is_null($path)) {
$data = (new Files())->upload('default.only_excel');
if (!$data['status']) {
return $data;
}
$path = $data['data']['file_path'];
}
if (!file_exists($path)) {
return [
'status' => false,
'message' => $path . '文件不存在'
];
}
if (empty($map)) {
return [
'status' => false,
'message' => 'map參數不正確'
];
}
$suffix = pathinfo($path)['extension'];
$loadReader = $suffix == 'xls' ? 'Excel5' : 'Excel2007';
$objReader = \PHPExcel_IOFactory::createReader($loadReader);
$objPHPExcel = $objReader->load($path);
$jsonData = [];
$sheetIndex = 0;
foreach ($map as $data) {
$row = $data['row'] ?? 2;
$col = $data['col'] ?? 0;
$firstHidden = $data['firstHidden'] ?? false;
$result = self::getCommanData(
$objPHPExcel,
$sheetIndex,
$row,
$col,
$firstHidden
);
if (!$result['status']) {
return $result;
} else {
$jsonData['sheet' . $sheetIndex] = $result['data'];
}
$sheetIndex++;
}
return $jsonData;
}
~~~
其中調用了getCommanData方法--方法如下
~~~
/**
* 獲取普通excel數據
*
* @param object $objPHPExcel
* @param integer $sheetIndex
* @param integer $rowstart
* @param integer $col
* @param bool $firstHidden
* @return array
*/
protected static function getCommanData(
$objPHPExcel,
$sheetIndex,
$rowstart,
$col,
$firstHidden
)
{
$sheet = $objPHPExcel->getSheet($sheetIndex);
$highestRow = $sheet->getHighestRow();
$highestColumm = $sheet->getHighestColumn();
$highestColumm = \PHPExcel_Cell::columnIndexFromString($highestColumm);
$fieldKeys = [];
if ($firstHidden) {
for ($column = $col; $column < $highestColumm; $column++) {
$cellData = trim(strval($sheet->getCellByColumnAndRow($column, 1)->getValue()));
array_push($fieldKeys, $cellData);
}
}
$excel_data = [];
for ($row = $rowstart; $row <= $highestRow; $row++) {
$temp = 0;
$datatemp = [];
for ($column = $col; $column < $highestColumm; $column++) {
$cellData = trim(strval($sheet->getCellByColumnAndRow($column, $row)->getValue()));
if ($firstHidden) {
if (isset($fieldKeys[($column - $col)]) && $fieldKeys[($column - $col)] != '') {
$datatemp[$fieldKeys[($column - $col)]] = $cellData;
} else {
return ['status' => false, 'message' => 'sheet' . $sheetIndex . '工作區key值少于數據值'];
}
} else {
array_push($datatemp, $cellData);
}
if($temp == ($highestColumm - 1)) break;
$temp++;
}
if (!empty($datatemp)) $excel_data[] = $datatemp;
}
$jsonData = ['status' => true, 'data' => $excel_data];
return $jsonData;
}
~~~
### 6、開始importBaseVerify--直接上代碼
~~~
/**
* excel導入數據基于基礎數據校驗
*
* @param string $key excel配置文件中的import key
* @param string $path 文件路徑 如果默認為空,采用文件上傳方式
*/
public static function importBaseVerify($key, $path = null)
{
if (empty($key)) {
return [
'status' => false,
'message' => 'key值不能為空'
];
}
if (is_null($path)) {
$data = (new Files())->upload('default.only_excel');
if (!$data['status']) {
return $data;
}
$path = $data['data']['file_path'];
}
if (!file_exists($path)) {
return [
'status' => false,
'message' => $path . '文件不存在'
];
}
$suffix = pathinfo($path)['extension'];
$loadReader = $suffix == 'xls' ? 'Excel5' : 'Excel2007';
$objReader = \PHPExcel_IOFactory::createReader($loadReader);
$objPHPExcel = $objReader->load($path);
$map = Config::get($key);
$jsonData = [];
$sheetIndex = 0;
foreach ($map as $data) {
$row = $data['row'] ?? 2;
$col = $data['col'] ?? 0;
$firstHidden = $data['firstHidden'] ?? false;
$verify = $data['verify'] ?? [];
$result = self::getBaseVerifyData(
$objPHPExcel,
$sheetIndex,
$row,
$col,
$firstHidden,
$verify
);
if (!$result['status']) {
return $result;
} else {
$jsonData['sheet' . $sheetIndex] = $result['data'];
}
$sheetIndex++;
}
return $jsonData;
}
~~~
其中調用了getBaseVerifyData方法如下
~~~
/**
* 獲取普通excel數據
*
* @param object $objPHPExcel
* @param integer $sheetIndex
* @param integer $rowstart
* @param integer $col
* @param bool $firstHidden
* @param array $verify
* @return array
*/
protected static function getBaseVerifyData(
$objPHPExcel,
$sheetIndex,
$rowstart,
$col,
$firstHidden,
array $verify
)
{
$sheet = $objPHPExcel->getSheet($sheetIndex);
$highestRow = $sheet->getHighestRow();
$highestColumm = $sheet->getHighestColumn();
$highestColumm = \PHPExcel_Cell::columnIndexFromString($highestColumm);
$fieldKeys = [];
if ($firstHidden) {
for ($column = $col; $column < $highestColumm; $column++) {
$cellData = trim(strval($sheet->getCellByColumnAndRow($column, 1)->getValue()));
array_push($fieldKeys, $cellData);
}
}
$v_flag = !empty($verify) ? true : false;
$excel_data = [];
$error = 0;
$error_msg = '';
for ($row = $rowstart; $row <= $highestRow; $row++) {
$temp = 0;
$datatemp = [];
for ($column = $col; $column < $highestColumm; $column++) {
$cellData = trim(strval($sheet->getCellByColumnAndRow($column, $row)->getValue()));
//數據校驗
if ($v_flag
&& isset($verify['col' . ($column - $col)])
) {
$verifyResult = ImportBaseVerify::ImportBaseVerifyEnum($verify['col' . ($column - $col)], $cellData);
if (!$verifyResult['status']) {
$error ++;
$error_msg .= 'sheet' . $sheetIndex . '在第' . $row . '行,第' . ($column + 1) . '列' . $verifyResult['message'] . ';';
}
}
if ($firstHidden) {
if (isset($fieldKeys[($column - $col)]) && $fieldKeys[($column - $col)] != '') {
$datatemp[$fieldKeys[($column - $col)]] = $cellData;
} else {
return ['status' => false, 'message' => 'sheet' . $sheetIndex . '工作區key值少于數據值'];
}
} else {
array_push($datatemp, $cellData);
}
if($temp == ($highestColumm - 1)) break;
$temp++;
}
if (!empty($datatemp)) $excel_data[] = $datatemp;
}
$jsonData = $error ? [
'status' => false,
'message' => $error_msg
] :
[
'status' => true,
'data' => $excel_data
];
return $jsonData;
}
~~~
其中的importBaseVerify中的key到底是什么?
key是在config目錄下excel.php中的配置key如下:
~~~
//代碼中調用key通過Config::get('excel.import.test')即可
'import' => [
'test' => [
[
//從第幾行開始讀取
'row' => 3,
//從第幾列開始讀取
'col' => 0,
//是否有隱藏的第一行字段
'firstHidden' => true,
//每一列對應的的校驗方法(列下標從0開始)
'verify' => [
'col2' => 'idcard',//ok
'col3' => 'date_ymd',//ok
'col4' => 'number_2dot',//ok
'col5' => 'number',//ok
'col6' => 'date_y-m-d',//ok
'col7' => 'number_2dot',
],
],
[]
],
],
~~~
### 7、作者有話說
1.說明一下解惑信息
commmonImport中如果傳入了文件path,則直接解析
如果是直接文件上傳的模式則調用了Files類的上傳upload方法
----其中importBaseVerify一樣
2.firstHidden是干什么用的
這個參數是為了有些量非常大,一般提供了模板導出的然后導入
然而一些數據庫字段要與該列的值一一對應
如果firstHidden設為false表示excel中第一行沒有隱藏的字段
那么返回的已普通數組模式返回即:
```
[
'sheet0' => [
['aa','bb','cc'],
['a2a','b2b','c2c'],
],
'sheet1' => [],
]
```
說明:該方法支持多個sheet工作區導入
如果firstHidden設為true表示excel中第一行有隱藏的字段
那么返回的將會以第一行的字段以鍵值對返回
```
[
'sheet0' => [
[
'name'=> 'aa',
'addr' => 'bb',
'age' => 20
],
[],
],
'sheet1' => [],
]
```
3.具體可以參考代碼的注釋
4.相信這些簡單的代碼難不倒各位phper
5.如果有一些不明白的直接留言
6.為了該方法的更直接了解,立馬寫Files類是怎么的
7.再插一句import配置中的verify是什么意思
col2=>idcard
col2表示的是第三列
idcard對應的是ImportBaseVerify中需要校驗的一個type
該type會在ImportBaseVerify中調用相應的方法
- 產品介紹
- 功能介紹
- 聯系合作
- 修訂記錄
- 環境安裝
- 依賴環境
- 依賴服務
- 前端環境
- 核心功能
- 流程引擎
- 流程編輯步驟
- 流程設計
- 業務表設計
- 表單設計
- 報表設計
- 節點配置
- 全局配置
- 規則引擎
- 模塊功能
- 系統管理
- 平臺架構
- 平臺(單位)管理
- 組織架構
- 用戶管理
- 角色管理
- 運維管理
- 菜單管理
- 流程管理
- 代碼管理
- 字典管理
- 車型庫管理
- 報表管理
- 產品管理
- 經銷商管理
- 數據字典
- 業務設置
- 業務報表設置
- 系統配置
- 微信小程序設置
- OCR識別
- 釘釘通知
- 釘釘登錄授權
- 云儲存設置
- 服務規劃
- 其他產品
- 教育點播
- 退役政務
- 三方報表
- 微信社群
- 場景名片
- 合同電子簽
- TP5實用封裝
- 通用封裝
- Export通用封裝
- Import通用封裝
- 配合Import通用封裝的ImportBaseVerify類
- Files通用封裝
- Directory通用封裝
- Pdf通用封裝
- Words通用封裝
- Nredis(redis封裝)
- ZipArchives壓縮zip文件封裝
- BarQrcode條形碼二維碼
- Publics公共方法封裝
- Curls(cUrl請求封裝)
- extend擴展開發
- 何時編寫擴展文件包
- 擴展文件包如何編寫
- 題外話
- 常用的compose安裝
- 一些建議及細節
- 實用工具
- 源碼分析
- 入口文件index.php
- think\Facade類詳解
- App對接Api設計
- 設計模式說明(為什么這么做)
- 代碼設計邏輯方案
- 數據庫備份
- 實用案例
- 如何“偷”JAVA代碼
- SAAS接口設計
- 1、創建saas基類文件
- 2、初始化控制器服務
- 3、身份校驗
- 4、創建登錄控制器
- 5、實現登錄服務層
- 6、服務層繼承的service類
- 7、該案例的完整模塊包
- 校驗型規則校驗擴展包
- 自定義規則解析(可供參考)
- 通用文件擴展包(File,Zip)
- PHP實現word轉PDF功能環境搭建
- 日志通用擴展包
- 定時任務
- PHP視頻處理器安裝環境搭建
- 日常開發問題記錄
- 1、mysql存儲中帶一些不可見字符
- 2、php開發規范校驗及修復