用PHP怎么编程一个通用的Excel导入程序
昨天和两个做开发的朋友聊天,对于我还在使用layui感到奇怪,我也没有多解释,毕竟layui对于做一些中小型的开发还是不错的,前端的框架中,熟悉了一个其他的也差之不多。但layui的资料不细致是个很大的缺憾。
用户提出有一个excel表的记录要导入,这个是基本要求,肯定要满足。
2006年,我用powerbuilder写过一个通用的导入程序,程序上也不难。
用前端框架来完成会有一点麻烦,主要在于
1、数据回显
如果是让用户选择一个excel文件然后就直接入库,那程序就太简单了,问题是要先让用户看到结果,可能的话还可以修改,然后再保存到数据库中。
2、数据保存
因为以前c/s开发使用的是强连接,操作数据后直接提交即可;但现在前端和后端是弱连接,一次交互就需要配置相应参数才可能保存数据,动态的表格保存就有一点小麻烦。
作为一般性的要求,这个程序肯定是要应对数据库中的所有表。
那么只能先将数据表的字段设置传到php中,然后php提取excel记录,按照layui对表记录的要求封装数据,传回到前端。
具体做法:
1、在数据库中创建表,记录要导入的表信息;
2、在前端列出表,让用户选择要导入的表;
3、根据选择的表,确定字段参数即对应的excel列;
4、将前端选择传入到php中,提取excel记录,传回前端;
5、用户确定要保存数据,点击保存,数据入库。
一天完成,功能全部正常,后面需要加入一些错误检测,还有文件名应该使用用户名加随机数来存储,这样可以防止多用户冲突,读取完删除。
这个程序主要涉及的就是动态对象、动态属性的创建与赋值。
完成的界面:
程序前端代码:
!doctype html> html> head> meta charset="utf-8"> title> 〖通用excel数据表导入〗/title> meta name="renderer" content="webkit"> meta http-equiv="x-ua-compatible" content="ie=edge,chrome=1"> meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"> link rel="stylesheet" href="../lib/layui-v2.6.3/css/layui.css" rel="external nofollow" media="all"> link rel="stylesheet" href="../css/public.css" rel="external nofollow" media="all"> script src="../lib/layui-v2.6.3/layui.js" charset="utf-8"> /script> style> body { background-color: #ffffff; } /style> /head> body> div class="layui-form layuimini-form"> form class="layui-form login-bottom" lay-fiter="ztbuseredit"> div class="layui-tab"> ul class="layui-tab-title"> li class="layui-this"> 导入设置/li> li> 导入的数据表记录/li> /ul> div class="layui-tab-content"> div class="layui-tab-item layui-show"> div style="width: 1000px; "> div class="layuimini-container"> div class="layuimini-main"> div class="layui-form layuimini-form" style="white-space:nowrap!important; "> div class="layui-form-item"> label class="layui-form-label"> 选择要导入的表/label> div class="layui-input-block"> select id="tablelist" lay-filter="tablelistfilter"> option value=""> /option> /select> /div> /div> div class="layui-form-item"> label class="layui-form-label"> excel文件/label> div class="layui-input-inline" style="width: 400px; "> input type="text" name="dc05" id="dc05" value="" style="width: 400px; " class="layui-input" disabled="disabled"> /div> div class="layui-input-inline"> button type="button" class="layui-btn layui-btn-sm layui-btn-normal" style="width: 100px; height: 39px; " id="selectexcel"> 选择excel文件/button> input type='file' id='readfile' style="opacity: 0; border: 0px solid #1e9fff; "> /div> /div> div class="layui-form-item" style="padding-left: 41px; "> div class="layui-input-inline"> label class="layui-form-label"> 工作簿序号/label> input type="number" id="excelsetsheet" value="1" class="layui-input" style="width: 50px; "> /div> div class="layui-input-inline"> label class="layui-form-label"> 起始行号/label> input type="number" id="excelsetstartrow" value="4" class="layui-input" style="width: 50px; "> /div> div class="layui-input-inline"> label class="layui-form-label"> 结束行号/label> input type="number" id="excelsetendrow" value="33" class="layui-input" style="width: 50px; "> /div> button class="layui-btn layui-btn-normal" lay-submit lay-filter="getdata" style="width: 100px; height: 39px; "> 提取数据/button> /div> /div> table class="layui-hide" id="currenttableidset" lay-filter="currenttablefilterset"> /table> /div> /div> /div> /div> div class="layui-tab-item"> button class="layui-btn layui-btn-normal" lay-submit lay-filter="savebtn"> 保存数据/button> table class="layui-hide" id="currenttableidtwo" lay-filter="currenttablefiltertwo"> /table> /div> /div> /div> /form> /div> script> let tablenamelist; let selecttablename; let tabletotalcount; let submitdata=[]; //准备一个空数组 let fieldset=[]; //字段设置 let dbrows={ } ; //excel记录的行对象 let colset=[]; let colsetchild=[]; let dbdatarecordcount; layui.use(['layer','form','table'], function () { var form = layui.form; var layer = layui.layer; var $ = layui.$; var table = layui.table; document.getelementbyid('selectexcel').addeventlistener('click',function(){ $("#readfile").trigger("click"); } ); document.getelementbyid('readfile').addeventlistener('change',function(){ if(this.files.length===0){ layer.msg('没有选择文件!',{ time:3000,icon:5} ); return; } if(this.files[0].name.split('.')[1]!='xls'){ layer.msg('请选择excel文件!',{ time:3000,icon:5} ); return; } let reader=new filereader(); reader.onload=function (){ console.log(reader.result); } document.getelementbyid('dc05').value=this.files[0].name; } ) //得到数据表的名称列表 $.ajax({ url:'ztbexceldatain.php', data:{ "op":"gettablelist"} , type:'post', async:false, success:function (data) { tablenamelist = data['data']; //在数组中找到对应的编码 for(var i=0; itablenamelist.length; i++){ $('#tablelist').append(new option(tablenamelist[i].c02, tablenamelist[i].c02)); } } ,error:function(data){ console.log(data); } } ); form.render(); form.on('submit(getdata)', function (data) { data = data.field; let tempdata=new object(); //准备一个空对象 tempdata.excelsheet=document.getelementbyid("excelsetsheet").value; tempdata.excelsetstartrow=document.getelementbyid("excelsetstartrow").value; tempdata.excelsetendrow=document.getelementbyid("excelsetendrow").value; let adddata=new object(); adddata.excelset=tempdata; submitdata.push(adddata); for(let i=0; i=tabletotalcount-1; i++){ tempdata=new object(); tempdata.c02=$("#currenttableidset").next().find("tbody tr[data-index='" +i +"'] td[data-field='c02'] div").html(); //字段英文名 tempdata.c03=$("#currenttableidset").next().find("tbody tr[data-index='" +i +"'] td[data-field='c03'] div").html(); //字段汉字名称 tempdata.c09=$("#currenttableidset").next().find("tbody tr[data-index='" +i +"'] td[data-field='c09'] div").html(); //字段对应的excel列 fieldset.push(tempdata); dbrows[tempdata.c02]=''; colsetchild={ } ; colsetchild['field']=tempdata.c02; colsetchild['title']=tempdata.c03; colsetchild['width']=100; colset.push(colsetchild); } submitdata.push(fieldset); //准备提取数据 let excelfile = document.getelementbyid('readfile'); //用formdata对象对表单数据进行封装 const fd = new formdata(); //formdata构造器接收的是一个form的dom对象 fd.append("excelfile",excelfile.files[0]); //excel文件数据 fd.append("excelset",json.stringify(submitdata)); //设置 fd.append("dbrows",json.stringify(dbrows)); //行对象 fd.append("op",'getset'); $.ajax({ url: 'ztbexceldatain.php', type: "post", data: fd, datatype: "json", async: true, processdata: false,//设置为false,jquery则不对数据进行序列化 contenttype: false,//设置为false,jquery则不设content-type请求头 beforesend: function(xhr){ } , complete: function(xhr,status){ } , error: function(xhr,status,error){ } , success: function(result){ //刷新数据记录表 table.render({ elem: '#currenttableidtwo', data:result['data'], cols: [colset], done: function (res, curr, count) { dbdatarecordcount=res.data.length; } } ); } } ); return false; } ) //监听下拉列表的点击事件 form.on('select(tablelistfilter)', function(data){ let selectitemname = data.value; //选择的单位名称 //选择的具体表 selecttablename=tablenamelist.find(element=> element.c02==selectitemname ).c01; //提取具体的设置信息 table.render({ elem: '#currenttableidset', url: 'ztbexceldatain.php', method:'post', where:{ "op":"getsetlist", "selecttable":selecttablename} , cols: [[ { field: 'c01', width: 80, title: '表的名字', hide: true} , { field: 'c02', width: 120, title: '字段英文名称'} , { field: 'c03', width: 150, title: '字段汉字名称'} , { field: 'c09', width: 120, title: '对应的excel列号',edit: 'number'} , { field: 'c04', width: 100, title: '数据类型'} , { field: 'c05', width: 100, title: '长度'} , { field: 'c06', width: 120, title: '能否为空'} ]], done: function (res, curr, count) { tabletotalcount=res.data.length; } } ); } ); form.on('submit(savebtn)', function (data) { for(let k=0; kdbdatarecordcount; k++){ let insertsql=''; let assignsql=''; for(let i=0; itabletotalcount; i++){ let tempfieldname=''; let tempfieddata; let tempfieldtype=''; tempfieldname=$("#currenttableidset").next().find("tbody tr[data-index='" +i +"'] td[data-field='c02'] div").html(); tempfieldtype=$("#currenttableidset").next().find("tbody tr[data-index='" +i +"'] td[data-field='c04'] div").html(); if(insertsql==''){ insertsql=tempfieldname; } else{ insertsql=insertsql +"," +tempfieldname; } tempfieddata=$("#currenttableidtwo").next().find("tbody tr[data-index='" + k +"'] td[data-field='"+tempfieldname+"'] div").html() if(tempfieddata=='undefined' || tempfieddata==null){ if(tempfieldtype=='integer' || tempfieldtype=='decimal'){ tempfieddata=0; } else{ tempfieddata=''; } } if(assignsql==''){ if(tempfieldtype=='integer' || tempfieldtype=='decimal'){ assignsql=tempfieddata; } else{ assignsql="'"+tempfieddata+"'"; } } else{ if(tempfieldtype=='integer' || tempfieldtype=='decimal'){ assignsql=assignsql+","+tempfieddata; } else{ assignsql=assignsql+",'"+tempfieddata+"'"; } } } //提交数据 $.ajax({ url:'ztbexceldatain.php', data:{ "op":"savedata", "insertsql":insertsql, "assignsql":assignsql, "tablename":selecttablename } , type:'post', async:false, success:function (data) { } ,error:function(data){ } } ); } return false; } ); } ); /script> /body> /html>
后端php代码:
?php require_once 'reader.php'; //加载reader require 'ztblinkconfig.php'; $ztbconn-> setattribute(pdo::attr_errmode, pdo::errmode_exception); $strfalse=""; $continue=true; $srcaddr="http://xx.xx.xx.xx"; $returnarr=[]; //准备返回的数组 if (array_key_exists('http_origin',$_server)) { $origin = $_server['http_origin']; } else if (array_key_exists('http_referer',$_server)) { $origin = $_server['http_referer']; } else { $origin = $_server['remote_addr']; } if(substr($origin,0,15)!=substr($srcaddr,0,15)){ $continue=false; $strfalse="拒绝访问".substr($origin,0,15)."!"; } if(!$_session[xxxyyyy']){ $continue=false; $strfalse="请登录!"; } if($continue){ $op=!empty($_post['op']) ? $_post['op'] : ''; //得到操作类型 switch($op){ case 'gettablelist'://数据表列表 $sql="select c01,c02 from dawntable"; $result=$ztbconn-> query($sql); $rows=$result-> fetchall(pdo::fetch_assoc); $returnarr['data']=$rows; break; case 'getsetlist'://具体表的字段设置项目 $selecttable=$_post['selecttable']; $sql1 = "select count(*) from dawnfield where c01='$selecttable'"; $res = $ztbconn-> query($sql1); $rows = $res-> fetch(); $rowcount = $rows[0]; $returnarr['code']=0; $returnarr['msg']=""; $returnarr['count']=$rowcount; $sql="select c01,c02,c03,c04,c05,c06,c07,c08,c09 from dawnfield where c01='$selecttable'"; $result=$ztbconn-> query($sql); $rows=$result-> fetchall(pdo::fetch_assoc); $returnarr['data']=$rows; break; case 'getset': $uploadfile = $_files["excelfile"]; //得到上传的文件 $excelblob=file_get_contents($uploadfile['tmp_name']); file_put_contents("./tempfile/123.xls",$excelblob, file_append); //将文件内容写到磁盘上 $exceldata = new spreadsheet_excel_reader(); //创建 reader $exceldata-> setoutputencoding('utf-8'); //设置文本输出编码 $exceldata-> read("./tempfile/123.xls"); //读取excel文件 //准备提取数据 $excelset=json_decode($_post['excelset'],true); //gettype($excelset[0]) $dbrows =json_decode($_post['dbrows'],true); $excelsetstartrow=$excelset[0]['excelset']['excelsetstartrow']; //起始行 $excelsetendrow =$excelset[0]['excelset']['excelsetendrow']; //结束行 $excelsheet=$excelset[0]['excelset']['excelsheet']-1; //工作簿序号 $returnarr['code']=0; $returnarr['msg']=""; $returnarr['count']=$excelsetendrow - $excelsetstartrow +1; $data=[]; try{ for ($i = $excelsetstartrow; $i = $excelsetendrow; $i++) { for($k=0; $ksizeof($excelset[1]); $k++){ $fieldname=$excelset[1][$k]['c02']; //字段名称 $fieldexcelcol=$excelset[1][$k]['c09']; //字段对应的列 $fieldtype=$excelset[1][$k]['c03']; //字段数据类型 if ( isset( $exceldata-> sheets[$excelsheet]['cells'][$i][$fieldexcelcol] )){ $fielddata=$exceldata-> sheets[$excelsheet]['cells'][$i][$fieldexcelcol]; } else{ $fielddata=''; } //装入数组 $dbrows[$fieldname]=$fielddata; } array_push($data,$dbrows); } } catch(pdoexception $e){ $returnarr['data']=$e.getmessage(); } $returnarr['data']=$data; break; case 'savedata': $insertsql=$_post['insertsql']; $assignsql=$_post['assignsql']; $tablename=$_post['tablename']; try{ $sql = "insert into $tablename($insertsql) values($assignsql)"; $result =$ztbconn-> exec($sql); if ( $result> 0 ) { $returnarr['data']='ok'; } else{ $returnarr['data']="数据插入错误!"; } } catch(exception $exception){ $returnarr['data']=$exception-> getmessage(); } break; default: $returnarr['data']="不支持的操作!"; break; } } else{ $returnarr=$strfalse; } header('content-type:text/json'); echo json_encode($returnarr,json_unescaped_unicode); //返回json格式的数据 ?>
这个程序虽然简单,但是应用的地方还是挺多的,有必要后面再对这个程序进行完善。
通过以上内容的阐述,相信大家对“用PHP怎么编程一个通用的Excel导入程序”已经有了进一步的了解,更多相关的问题,欢迎关注网络或到官网咨询客服。
声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!
若转载请注明出处: 用PHP怎么编程一个通用的Excel导入程序
本文地址: https://pptw.com/jishu/652033.html