先从我的Github上,下载PHPExcel类扩展: https://github.com/hujinchen/PHPexcel/tree/master
然后去TP框架的 extend 文件夹下新建个文件夹命名为 phpexcel,把下载下来的文件放到这目录下
前端代码:
//html
<div style="display: inline-flex;position: relative;">
<button class="layui-btn layui-bg-cyan" id='uploadExcel'><i class="layui-icon"></i>一键导入</button>
<form id="uploadForm" enctype="multipart/form-data">
<input style="opacity:0;width:113px;height:38px;position:absolute;right:0;top:0;" id="files" type="file" name="file"
accept=".csv, .xls, .xlsx" />
</form>
</div>
//js
<script type="text/javascript">
$("#files").on("change", function (e) {
var file = document.getElementById("files").files[0];
var val = document.getElementById("files").value;
var suffix = val.substr(val.indexOf("."));
//只能选择Excel类型的文件
if (suffix == '' || suffix == null) return;
if (suffix != '.csv' && suffix != '.xlsx' && suffix != '.xls') {
$('#files').val("");
layer.msg('只能选择Excel类型的文件', { icon: 0, time: 2000, anim: 6 });
return;
}
layer.load(); //加载框
var formData = new FormData($('#uploadForm')[0]);
$.ajax({
type: 'post',
url: '{:url("admin/selfproject/importExcel")}',
data: formData,
cache: false,
processData: false,
contentType: false,
timeout: 0,
async: false,
}).success(function (res) {
$('#files').val(""); //解决选择两次相同的文件后第二次没有触发的方法
layer.closeAll('loading');//关闭加载框
if(res.code == 1) {
layer.msg(res.msg, { icon: 1, time: 2000 }, function () {
location.reload();
});
} else {
layer.msg(res.msg, { icon: 0, time: 2500 });
}
});
})
</script>
后端代码:
public function importExcel() {
import('phpexcel.PHPExcel', EXTEND_PATH, '.php'); // 引用PHPExcel文件
$excel = new \PHPExcel();
$user = Cookie::get('user');
$file = request()->file('file'); // 获取表单上传文件
$info = $file->move(ROOT_PATH . 'public' . DS . 'uploads'); // 移动到框架应用根目录/public/uploads/ 目录下
if($info) {
$filename = ROOT_PATH . 'public' . DS . 'uploads/' .$info->getSaveName();
$objReader = \PHPExcel_IOFactory::createReader('Excel5'); //如果写称Excel2017有些情况下会报错
$obj_PHPExcel = $objReader->load($filename, $encode = 'utf-8'); //加载文件内容,编码utf-8
$excel_array = $obj_PHPExcel->getsheet(0)->toArray(); //转换为数组格式
$arr = reset($excel_array); //excel表格第一行的值
unset($excel_array[0]); //删除第一个数组(标题)
//查询已添加的所有医院名
$ynameData = Db::table('hospitals')->field('yname')->find();
if(empty($ynameData)) {
unlink($filename);
return $this->rejson(0, '您还没有添加过医院,请先前去添加');
}
if(count($arr) != 4) {
unlink($filename);
return $this->rejson(0, '您的表格格式不正确,只能有4列');
}
//判断表格中的数据是否可以使用
foreach($excel_array as $k4 => $v4) {
//判断表格中的医院是否在后台已有添加过
$yname = Db::table('hospitals')->field('yid')->where('yname', $v4[0])->find();
if(empty($yname)) {
unlink($filename);
$str = '所属医院不存在,请检查:第' .($k4 + 1). '行,第1列';
return $this->rejson(0, $str);
}
if($user['jid'] == 2 && $yname['yid'] != $user['yid']) {
unlink($filename);
return $this->rejson(0, '只能导入您自己所属医院的数据');
}
$res = Db::table('this_option')
->field('a.yid')
->alias('a')
->join('hospitals b', 'a.yid = b.yid')
->where(['b.yname' => $v4[0], 'a.xname' => $v4[1]])
->find();
if(!empty($res)) {
unlink($filename);
$str = '项目名已存在,请检查:第' .($k4 + 1). '行,第2列';
return $this->rejson(0, $str);
}
//判断表格的格式
foreach($v4 as $k2 => $v2) {
//ctype_space 判断字符串全部为空格
if($v2 == ''|| ctype_space($v2)) {
unlink($filename);
$str = '单元格的值不能为空,请检查:第' .($k4 + 1). '行,第' .($k2 + 1). '列';
return $this->rejson(0, $str);
}
//判断项目价格是否为数值型
if(!is_numeric($v4[3])) {
unlink($filename);
$str = '项目价格的格式不正确, 请检查:第' .($k4 + 1). '行,第4列';
return $this->rejson(0, $str);
}
}
}
//数据正确,开始导入数据
$data = [];
foreach($excel_array as $k => $v) {
$yid = Db::table('hospitals')->field('yid')->where('yname', $v[0])->find();
$data[] = [
'yid' => $yid['yid'],
'xname' => $v[1],
'xdec' => $v[2],
'xprice' => $v[3],
'status' => '1',
'isdelete' => '0'
];
}
//一次添加多条数据
$res = Db::table('this_option')->insertAll($data);
unlink($filename); //上传成功删除服务器本地的文件
return $this->rejson(1, '一键导入成功', $info->getFilename());
} else {
// 上传失败获取错误信息
return $this->rejson(0, $file->getError());
}
}
我这边导入数据时,先判断excel表格中的数据格式是不是完全正确的。
只有当数据完全可以使用时,才开始导入,所以采用了两个循环!