需求:导入execl到数据库,如果数据存在就修改,不存在就添加
主要技术点在于尽量不要在循环中操作数据库,先查出数据库中该数据是非否在,如果存在就修改,不存在就添加(设计到批量修改,速度很慢);这里使用删除操作,也就是把数据库存在的数据统一删除,然后再直接把表格数据全部添加进去,但是这样的话id会变,所以只适合id字段没有外键使用的情况
1.控制器代码
//1.文件上传
function upload(){
if(IS_POST){
$file = $_FILES;
foreach ($file as $k => $v) {
//生成唯一的ID
$filename = md5(uniqid(microtime(true),true));
if($file[$k]['error']==0){
$config=array(
'maxSize'=>70000000,
'exts'=>array('xls','xlsx'),
'rootPath'=>'Public/Uploads/',
//保存的文件名
'saveName' =>$filename,
//开启子目录
'subName' =>array('date','Ymd'),
);
$upload=new \Think\Upload($config);
// dump($upload);die;
$info=$upload->upload();
if($info){
//根目录
$rootPath=$config['rootPath'];
//文件保存路径
$savepath=$info[$k]['savepath'];
//文件名称
$savename=$info[$k]['savename'];
$fileUrl = $_SERVER['DOCUMENT_ROOT'].'/'.$rootPath.$savepath.$savename;
$data['msg']='文件上传成功';
$data['fileUrl']=$fileUrl;
$this->ajaxReturn($data);
}else{
$data['msg']=$upload->getError();
// dump($data);die;
$this->ajaxReturn($data);
}
}else{
$data['msg']='文件上传错误';
// dump($data);die;
$this->ajaxReturn($data);
}
}
}else{
$data['msg']='参数错误';
$this->ajaxReturn($data);
}
}
//2.整理execl导入的数据
function importDriver()
{
$fileUrl=I("post.file");
$filename=$fileUrl;
//导入PHPExcel类库,因为PHPExcel没有用命名空间,只能inport导入
vendor('PHPExcel.PHPExcel');
//创建PHPExcel对象,注意,不能少了
$PHPExcel = new \PHPExcel();
$exts=substr(strrchr($filename, '.'), 1);
//如果excel文件后缀名为.xls,导入这个类
if ($exts == 'xlsx') {
$objReader =\PHPExcel_IOFactory::createReader('Excel2007');
$objPHPExcel =$objReader->load($fileUrl, $encode = 'utf-8');
} else if ($exts == 'xls'){
$objReader =\PHPExcel_IOFactory::createReader('Excel5');
$objPHPExcel =$objReader->load($fileUrl, $encode = 'utf-8');
}
//获取表中的第一个工作表,如果要获取第二个,把0改为1,依次类推
$currentSheet = $objPHPExcel->getSheet(0);
//获取总列数
$allColumn = $currentSheet->getHighestColumn();
//获取总行数
$allRow = $currentSheet->getHighestRow();
//循环获取表中的数据,$currentRow表示当前行,从哪行开始读取数据,索引值从0开始
for ($currentRow = 1; $currentRow <= $allRow; $currentRow++) {
//从哪列开始,A表示第一列
for ($currentColumn = 'A'; $currentColumn <= $allColumn; $currentColumn++) {
//数据坐标
$address = $currentColumn . $currentRow;
//读取到的数据,保存到数组$data中
$cell = $currentSheet->getCell($address)->getValue();
if ($cell instanceof PHPExcel_RichText) {
$cell = $cell->__toString();
}
$data[$currentRow - 1][$currentColumn] = $cell;
// print_r($cell);
}
}
array_shift($data);
foreach ($data as $k=>$v){
$l[$k]['driver_id']=$v['A'];
$l[$k]['realname']=$v['B'];
$l[$k]['phone']=$v['C'];
$l[$k]['idnumber']=$v['D'];
}
// 写入数据库操作
return $this->insert_data($l,$filename);
}
//3.修改添加数据库
function insert_data($l,$url){
$l=$this->assoc_unique($l,"idnumber");//数据去重
$where['idnumber']=array('NEQ','');
$idnumberArr=M("driver_join")->field("idnumber")->where($where)->select();
foreach ($idnumberArr as $k=>$v){
$idnumberArrs[$k]=$v['idnumber'];
}
$info=array();
if(!empty($idnumberArrs)){
foreach ($l as $k=>$v){
if(in_array($v['idnumber'],$idnumberArrs)){
array_push($info,$v['idnumber']);
}
}
}
if(!empty($info)){
//删除已经有的
$wheres['idnumber']=array('IN',$info);
M("driver_join")->where($wheres)->delete();
}
M("driver_join")->addAll($l);
//删除上传的文件
unlink($url);
$this->ajaxReturn(['code'=>200,'msg'=>'导入成功']);
}
//4.二维数组去重
function assoc_unique($arr, $key) {
$tmp_arr = array();
foreach ($arr as $k => $v) {
if (in_array($v[$key], $tmp_arr)) {//搜索$v[$key]是否在$tmp_arr数组中存在,若存在返回true
unset($arr[$k]);
} else {
$tmp_arr[] = $v[$key];
}
}
sort($arr); //sort函数对数组进行排序
return $arr;
}
2.前端代码 (使用layui的upload)
<button type="button" class="layui-btn" id="test3"><i class="layui-icon"></i>批量导入</button>
<script>
layui.use('upload', function() {
console.log('进来啦');
var upload = layui.upload;
upload.render({
elem: '#test3'
,url: '/Admin/Join/upload' //改成您自己的上传接口
,accept: 'file' //普通文件
,done: function(res){
// console.log(res);
$.post("/Admin/Join/importDriver",{'file':res.fileUrl},function (msg) {
console.log(msg);
if(msg.code=200){
layer.msg('上传成功');
//请求table数据
$.post(
'/index.php/Admin/Join/join_list_data',
function(res){
render_table(res.data.data);
render_page(res.data.page);
layer.close(loading)
}
);
}
},'json');
}
});
});
</script>
3.前端代码(原生按钮)
<style>
.btnimport{display:inline-block;color:#fff; background-color: #1fb5ad;padding: 5px 10px; font-size: 12px; line-height: 1.5; border-radius: 3px; position: absolute;right: 200px;top: 182px;}
.btnimport input{position: absolute;opacity:0;filter:alpha(opacity=0);cursor:pointer;width: 50px;}
</style>
<div class="btnimport" id="imports">
<form action="upload" method="post" enctype="multipart/form-data" lay-filter="formDemos">
<input class="fileupload" type="file" id="fileExecl" name="importExcel" accept=".xlsx,.xls" >
</form>
<span>批量导入</span>
</div>
<script>
// 导入司机信息
$("#fileExecl").change(function () {
if ($("#fileExecl").val().length > 0) {
ajax_upload();
}
});
function ajax_upload()
{
var formData = new FormData();
formData.append('file', $('#fileExecl')[0].files[0]);
console.log(formData.get('file'));
$.ajax({
url: "upload",
type: "post",
data: formData,
processData: false,
contentType: false,
success: function (data) {
if(data.msg=="文件上传成功"){
$.post("importDriver",{'file':data.fileUrl},function (msg) {
if(msg.code=200){
alert(msg.msg)
}
},'json');
}
$('.tc_box').hide();
formData=null;
$("#fileExecl").val('');
},
error: function (e) {
formData=null;
alert("错误!!");
$("#fileExecl").val('');
}
})
}
</script>