封装PHPExcel接入类
使用的是PHPExecl-1.8
<?php
/*
* @Author: Alfred
* @Date: 2019-12-31 17:17:44
* @LastAuthor : Alfred
* @LastTime : 2020-01-03 13:40:10
* @Description: Excel对接
*/
namespace Common\Utility;
class ExcelAction {
static protected $objExcel;
public function __construct() {
vendor('PHPExcel.PHPExcel');
self::$objExcel = new \PHPExcel();
}
/**
* 导出
*
* @param string $title
* @param array $cellName ['id','name'] 或 ['cuid'=>'孩子ID','real_name'=>'孩子名字']
* @param array $data [['id'=>111,'name'=>'222'],['id'=>111,'name'=>'222']]
* @return string 下载文件地址
*/
public function downloadExcel($title = '', array $cellName, array $data) {
$topNumber = 2; //表头有几行占用
$xlsTitle = iconv('utf-8', 'gb2312', $title); //文件名称
$fileName = $title . date('_YmdHis'); //文件名称
$cellKey = array(
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
'AA', 'AB', 'AC', 'AD', 'AE', 'AF', 'AG', 'AH', 'AI', 'AJ', 'AK', 'AL', 'AM',
'AN', 'AO', 'AP', 'AQ', 'AR', 'AS', 'AT', 'AU', 'AV', 'AW', 'AX', 'AY', 'AZ',
);
//处理表头标题
self::$objExcel->getActiveSheet()->mergeCells('A1:' . $cellKey[count($cellName) - 1] . '1'); //合并单元格(如果要拆分单元格是需要先合并再拆分的,否则程序会报错)
self::$objExcel->setActiveSheetIndex(0)->setCellValue('A1', $title);
self::$objExcel->getActiveSheet()->getStyle('A1')->getFont()->setBold(true);
self::$objExcel->getActiveSheet()->getStyle('A1')->getFont()->setSize(18);
self::$objExcel->getActiveSheet()->getStyle('A1')->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
self::$objExcel->getActiveSheet()->getStyle('A1')->getAlignment()->setVertical(\PHPExcel_Style_Alignment::VERTICAL_CENTER);
//处理表头
$index = 0;
foreach ($cellName as $k => $v) {
self::$objExcel->setActiveSheetIndex(0)->setCellValue($cellKey[$index] . $topNumber, $v); //设置表头数据
// self::$objExcel->getActiveSheet()->freezePane($cellKey[$index] . ($topNumber + 1)); //冻结窗口
self::$objExcel->getActiveSheet()->getStyle($cellKey[$index] . $topNumber)->getFont()->setBold(true); //设置是否加粗
self::$objExcel->getActiveSheet()->getStyle($cellKey[$index] . $topNumber)->getAlignment()->setVertical(\PHPExcel_Style_Alignment::VERTICAL_CENTER); //垂直居中
$index++;
// if ($v[3] > 0) //大于0表示需要设置宽度
// {
// self::$objExcel->getActiveSheet()->getColumnDimension($cellKey[$index])->setWidth($v); //设置列宽度
// }
}
//数据表头处理方式
$dataWrite = $cellName[0] ? 1 : 0; //如果是1 直接取v1 否则取 k1
//处理数据
foreach ($data as $k => $v) {
$cell_index = 0;
foreach ($cellName as $k1 => $v1) {
self::$objExcel->getActiveSheet()->setCellValue($cellKey[$cell_index] . ($k + 1 + $topNumber), $v[$dataWrite ? $v1 : $k1]);
$cell_index++;
}
}
//导出execl
ob_end_clean(); //清除缓冲区,避免乱码
header('pragma:public');
header('Content-type:application/vnd.ms-excel;charset=utf-8;name="' . $xlsTitle . '.xls"');
header("Content-Disposition:attachment;filename=$fileName.xls"); //attachment新窗口打印inline本窗口打印
$objWriter = \PHPExcel_IOFactory::createWriter(self::$objExcel, 'Excel5');
$objWriter->save('php://output');
exit;
}
/**
* 导入,excel 头两行作为备注或注意事项描述信息
*
* 第三行为数据列标题如:id,name,……
*
* 第四行开始为列对应的数据
*
* @param array $file 上传的文件form-data
* @param array $checkColumn 要检测的列值 ['shop_name','create_data']
* @return array 读取到的数据
*/
public function uploadExcel($file = [], $checkColumn = []) {
$file_tmp_name = $file['tmp_name'];
// $fileType = \PHPExcel_IOFactory::identify($file['name']); //读取不到网络文件 只能读取到固定目录的文件
$fileSuffix = explode('.', $file['name']);
switch (end($fileSuffix)) {
case 'xlsx': // Excel (OfficeOpenXML) Spreadsheet
case 'xlsm': // Excel (OfficeOpenXML) Macro Spreadsheet (macros will be discarded)
case 'xltx': // Excel (OfficeOpenXML) Template
case 'xltm': // Excel (OfficeOpenXML) Macro Template (macros will be discarded)
$fileType = 'Excel2007';
break;
case 'xls': // Excel (BIFF) Spreadsheet
case 'xlt': // Excel (BIFF) Template
$fileType = 'Excel5';
break;
}
if (empty($fileType)) {
return makeinformation(550, '导入失败,请上传正确的Excel格式的文件!');
}
//excel初始化列
$cellKey = array(
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
'AA', 'AB', 'AC', 'AD', 'AE', 'AF', 'AG', 'AH', 'AI', 'AJ', 'AK', 'AL', 'AM',
'AN', 'AO', 'AP', 'AQ', 'AR', 'AS', 'AT', 'AU', 'AV', 'AW', 'AX', 'AY', 'AZ',
);
//初始化excel版本
$objReader = \PHPExcel_IOFactory::createReader($fileType);
//读取excel
$objPHPExcel = \PHPExcel_IOFactory::load($file_tmp_name);
$sheet = $objPHPExcel->getSheet(0);
$highestRow = $sheet->getHighestDataRow(); // 取得有数据的总行数
$highestColumn = $sheet->getHighestDataColumn(); // 取得有数据的总列数
$getColumnKeyList = []; //保存读取到的列值 后续遍历数据时使用的标识 ['A'=>'shop_name','B'=>'child_id'……]
foreach ($cellKey as $v) {
$value = $objPHPExcel->getActiveSheet()->getCell($v . '2')->getValue();
if (empty($value)) { //如果取的列值是空 直接跳出
break;
}
$getColumnKeyList[$v] = $value;
if ($v == $highestColumn) { //读取到最后一列跳出
break;
}
}
//提取标识名称与传入限定数据进行比较 ['shop_name','shop_id'……]
$getColumn = array_values($getColumnKeyList);
if (array_diff($checkColumn, $getColumn) || array_diff($getColumn, $checkColumn)) { //反复比较 避免得不到差值
return makeinformation(550, '获取的列值与系统不匹配,请下载最新的模版再操作!', $checkColumn);
}
//遍历数据
$result = [];
for ($i = 3; $i <= $highestRow; $i++) { //从第3行开始取数据
$rowData = [];
foreach ($getColumnKeyList as $k => $v) {
$value = $objPHPExcel->getActiveSheet()->getCell($k . $i)->getValue(); //标识对应的值,例如:['shop_name'=>'大大的店']
if ($k == 'A' && is_null($value)) { //如果取的第一列的值是空则直接跳出,需要保证第一列没有空值
break;
}
$rowData[$v] = $value;
}
//避免返回空值数据
$rowData && $result[] = $rowData;
}
return makeinformation(200, '', $result);
}
}
以下为公共方法
<?php
/**
* 生成返回提示信息
*
* @param [type] $code
* @param string $desc
* @param string $data
* @return void
*/
function makeinformation($code, $desc = '', $data = '') {
return array("code" => $code, 'desc' => $desc, 'data' => $data);
}
文件放置位置
PHPExcel-1.8及上传模版下载地址 ↓↓↓↓↓↓ :)
附件:PHPExcel-1.8及上传模版