搭建环境:vue.js+element ui+axios.min.js+xlsx.full.min.js
构建工具:HBuilderX+chrome
下载地址:element ui
编写后台登录界面
HTML代码如下:
<!DOCTYPE html>
<html><head><meta charset="utf-8" /><title></title><!-- elementUI——css cdn --><link rel="stylesheet" href=".css"><!-- login.css --><link rel="stylesheet" href="css/login.css" /></head><body><div id="app" v-cloak><el-container direction='vertical'><!-- 登录内容容器 --><el-main><div class="login-div"><h4>XXX医院管理系统</h4><div class="register"><span>登录</span><!-- <a href="#">还没有账号,立即注册</a> --></div><!-- 登录表单 --><el-form ref="form" :model='form' v-show='formCode1'><el-form-item><el-input v-model='form.name' :placeholder='placeholdermsg'prefix-icon="el-icon-user-solid"></el-input></el-form-item><el-form-item v-show='passshow'><el-input type='password' v-model='form.password' placeholder='请输入密码'prefix-icon="el-icon-s-goods"></el-input></el-form-item><el-form-item v-show='show'><el-input v-model=de' style='width: 228px;' placeholder='请输入手机验证码'prefix-icon="el-icon-phone"></el-input><!-- 验证码 --><el-button type='primary' round @click='send' :disabled='isdisabled'>{{codemsg}}</el-button></el-form-item><el-form-item class='form4'><el-switch v-model='form.verify' id='mima' @change='remenber(form.verify)'></el-switch><label for='mima'>记住密码</label><a href="#" @click.prevent="wangji">忘记密码?</a></el-form-item><el-form-item><el-button type="primary" @click="submitForm(form)" style='margin-left: 155px;'>登录</el-button><el-button @click="resetForm(form)">重置</el-button></el-form-item></el-form><!-- 验证手机验证码 --><el-form ref="forget1" :model='forget1' v-show='formCode2'><el-form-item><el-input v-model='forget1.name' placeholder='请输入手机号'prefix-icon="el-icon-phone"></el-input></el-form-item><el-form-item><el-input v-model=de' style='width: 228px;' placeholder='请输入手机验证码'prefix-icon="el-icon-s-goods"></el-input><el-button type='primary' round @click='send' :disabled='isdisabled'>{{codemsg}}</el-button></el-form-item><el-form-item><el-button @click="last">上一步</el-button><el-button @click="next(forget1)">下一步</el-button></el-form-item><el-form-item></el-form-item></el-form><!-- 修改密码 --><el-form ref="forget2" :model='forget2' v-show='formCode3'><el-form-item><el-input v-model='forget2.name' placeholder='请输入账号或手机号'prefix-icon="el-icon-phone"></el-input></el-form-item><el-form-item><el-input v-model='forget2.password' placeholder='请输入密码'prefix-icon="el-icon-s-goods"></el-input></el-form-item><el-form-item><el-input v-model=wpass' placeholder='请再次输入密码'prefix-icon="el-icon-s-goods"></el-input></el-form-item><el-form-item><el-button @click="finish(forget2)">完成</el-button></el-form-item></el-form></div></el-main><!-- 底部容器 --><el-footer></el-footer></el-container></div></body><!-- vue CDN --><script src=".js"></script><!-- 支持vue的elenemtUI封装js CDN --><script src=".js"></script><!-- axios AJAX库 --><script src=".19.0-beta.1/axios.min.js"></script><!-- login.js --><script src="js/login.js"></script>
</html>
这是HTML的代码,可以看得出来,写的不是很好,使用的element提供的组件进行开发,整体使用虚拟DOM 组件功能实现,从布局开始,使用标签
el-container这个标签定义 全局 盒子,然后看自己需要什么样的布局方式 ,可提供的有 el-header头部导航 ,el-main中部身体和el-aside左侧导航,跟el-footer尾部
需要注意的是在Container 中 子元素中有 el-header 或 el-footer 时为 vertical,否则为 horizontal
body{margin: 0px;padding: 0px;background: ;
}
[v-cloak]{display: none;
}
.el-main{position: relative;top:150px;
}
.login-div{position: fixed;top: 50%;left: 50%;width: 500px;height: auto;border: 1px solid skyblue;transform: translate(-50%,-50%);border-radius: 20px;box-shadow: 0 4px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04);
}
.login-div h4{text-align: center;
}
.register{width: 450px;height: 50px;margin: auto;text-align: center;color: brown;font-size: 20px;
}
.el-form{width: 450px;margin: auto;
}
.form4{color: #A52A2A;margin-left: 0px;
}
.form4 a{float: right;color: #A52A2A;text-decoration: none;
}
css样式 主要是对页面 效果做细节调整,虽然没怎么 调好,但是相信小编对div的窗口居中有问题,所以 记录 下来
position: fixed;top: 50%;left: 50%;width: 500px;height: auto;border: 1px solid skyblue;transform: translate(-50%,-50%);
使用固定定位将这个div居中,当然这个只限于整个页面需要展示的只有登录才行,如果小范围div中元素居中就不行了
new Vue({el:"#app",data:{//登录表单form:{name:"",password:"",code:"",verify:false,numbers:0,},//忘记密码步骤一表格forget1:{name:"",code:""},//更改密码表单forget2:{name:"",password:"",newpass:""},//登录通过formCode1:true,//忘记密码验证formCode2:false,//重新设置密码formCode3:false,//提示语placeholdermsg:'请输入账号',//判断密码是否显示passshow:true,//判断次数count:0,//判断验证码是否显示show:false,//按钮信息codemsg:'发送手机验证码',//判断是否禁用按钮isdisabled:false,//短信按钮定时器timer:null,//cookie保存setCookie:(cname,cvalue,exdays)=>{var d = new Date();d.Time()+(exdays*24*60*60*1000));var expires = "expires="GMTString();kie = cname+"="+cvalue+"; "+expires;},//cookie查询getCookie:(cname)=>{var name = cname + "=";var ca = kie.split(';');for(var i=0; i<ca.length; i++) {var c = ca[i].trim();if (c.indexOf(name)==0) { return c.substring(name.length,c.length); }}return "";},},methods:{//发送倒计时send(){let downTime=60;if(!this.timer){this.timer=setInterval(()=>{if(downTime>0 && downTime<=60){downTime--;if(downTime!==0){demsg="重新发送("+downTime+")";this.isdisabled=true;}else{clearInterval(this.timer);demsg="发送手机验证码";downTime=60;this.timer=null;this.isdisabled=false;}}},1000)}},//登录表单提交验证submitForm(form){let mima='123456';if(form.password===mima){this.setCookie('code',"",-1)/* 测试 */this.$message('密码正确');this.setCookie('name',this.form.name,6)this.setCookie('pass',this.form.password,6)window.location.href="backstage.html" }else{unt++;this.$message('密码错误')this.setCookie('code',unt,6)}let c = Cookie('code')if(c==3){this.$message('密码错误3次,请使用手机验证码登陆')this.placeholdermsg='请输入手机号'this.show=true;this.passshow=false}},//重置按钮resetForm(form) {form.name=''form.password='de=''form.verify=falsethis.setCookie('code',"",-1)},//记住密码remenber(isremenber){if(isremenber){this.setCookie('name',this.form.name,6)this.setCookie('pass',this.form.password,6)}},//忘记密码wangji(){this.formCode2=truethis.formCode1=falsethis.formCode3=false},//忘记密码-验证手机验证码next(msg){// 验证码接口:通过:ajax//举例let data=1234if(msg.name==null||msg.name==""){this.$message('手机号码为空')}else de==null||de==""){this.$message('验证码为空')}else de==data){this.formCode3=truethis.formCode2=falsethis.formCode1=false}else{this.$message('验证码错误')}},last(){this.formCode3=falsethis.formCode2=falsethis.formCode1=true},//修改密码,成功后返回登录finish(msg){// let data=JSON.stringify(msg)// $.ajax({// url:"",// ContextType:{},// data{// 数据// },// success// })//举例if(msg!=null){this.formCode3=falsethis.formCode2=falsethis.formCode1=true}}},//初始化判断cookie是否有内容,给出提示created:function(){//判断输入密码是否超过三次,改用手机号登录let c = Cookie('code')if(c>=3){this.show=true;this.passshow=unt=c;this.placeholdermsg='请输入手机号';}//判断是否点击保存密码,直接将值赋予inputlet nameCookie('name')let passCookie('pass')if(name!=""&&pass!=""){this.form.verify=truethis.form.name=name;this.form.password=pass;}else{this.form.verify=false}}
})
js采用纯粹的vue方式创建 ,其中涉及到 使用 cookie缓存的记住密码功能,手动编写即可
随后是关于忘记密码的发送定时器
这是登录页面的demo实现效果图
没做太多效果 ,不过没关系,登录界面的主体功能都是有的,当然,没有注册,应该后台登录界面我的设想是后台用户管理中使用权限添加用户
,做完登录后感觉 有点重复造轮子了,很多功能组件可以写成一个个小的功能组件来做的
后台界面这个我是使用的iframe来做路由的,算是路由吧…
那么废话不多说,上代码:
<!DOCTYPE html>
<html><head><meta charset="utf-8"><title>后台管理</title><!-- elementUI——css cdn --><link rel="stylesheet" href=".css"><!-- backstage.css后台css表 --><link rel="stylesheet" href="css/backstage.css" /></head><body><div id="app2"><!-- 最外层容器-横向 --><el-container v-cloak style='height: 770px;'><!-- 左菜单 --><el-aside width="auto"><el-menu default-active='2-1' class="el-menu-vertical-demo" :collapse='isCollapse' @select="select"><el-menu-item index="1"><i class="el-icon-s-home"></i><a href="backstage.html" style="text-decoration: none;color: black;"><span slot="title">XXX医院后台管理系统</span></a></el-menu-item><el-submenu index='2'><template slot='title'><i class="el-icon-user"></i><span slot="title">员工管理</span></template><el-menu-item-group><span slot='title'>员工信息管理</span><a href="people_management.html" class="jump_where" target='main'><el-menu-item index="2-1">员工基本信息</el-menu-item></a><a href="" class="jump_where" target='main'><el-menu-item index="2-2">员工权限</el-menu-item></a></el-menu-item-group></el-submenu><el-submenu index='3'><template slot='title'><i class="el-icon-s-custom"></i><span slot="title">病人管理</span></template><el-menu-item-group><span slot='title'>病人信息管理</span><a href="Patient_Information.html" class="jump_where" target='main'><el-menu-item index="3-1">病人基本信息</el-menu-item></a><el-menu-item index="3-2">病人离院审核</el-menu-item></el-menu-item-group></el-submenu><el-submenu index='4'><template slot='title'><i class="el-icon-s-tools"></i><span slot="title">系统管理</span></template><el-menu-item-group><el-menu-item index="4-1">日志信息</el-menu-item><el-menu-item index="4-2">背景颜色</el-menu-item></el-menu-item-group></el-submenu></el-menu></el-aside><!-- 第二个容器-竖向中部容器 --><el-container><!-- 头部 --><el-header style='background: #87CEEB;'><el-row class='row-1'><el-col :span='1'><el-checkbox-group v-model="isCollapse" style="margin-top: 11px;"><el-checkbox-button :label="isCollapse"><i class="el-icon-s-grid"></i> </el-checkbox-button></el-checkbox-group></el-col><el-col :span='12' style='line-height: 60px;'><el-autocompletev-model="state"suffix-icon="el-icon-search":fetch-suggestions="querySearch"placeholder="请输入内容"@select="handleSelect"style='float:right;'></el-autocomplete></el-col><el-col :span='11'><!-- 头像 --><el-dropdown style='float: right;' @command='selectdrop'><span><template><div class="demo-type"><el-avatar icon="el-icon-user-solid"></el-avatar></div></template></span><el-dropdown-menu slot='dropdown'><el-dropdown-item command='1'>消息通知</el-dropdown-item><el-dropdown-item command='2'>个人中心</el-dropdown-item><el-dropdown-item command='3'>系统设置</el-dropdown-item><el-dropdown-item command='4'>退出登录</el-dropdown-item></el-dropdown-menu></el-dropdown></el-col></el-row></el-header><!-- 主体内容部分 --><el-main style='background:#E9E4EA;padding: 0px;'><iframe id='uiui' src="people_management.html" name="main" width="99%" height="100%"></iframe></el-main><!-- 尾部 --><el-footer>请在此处放置备案</el-footer></el-container></el-container></div></body><!-- vue CDN --><script src=".js"></script><!-- 支持vue的elenemtUI封装js CDN --><script src=".js"></script><!-- axios AJAX库 --><script src=".19.0-beta.1/axios.min.js"></script><!-- backstage后台js --><script src="js/backstage.js"></script>
</html>
后端HTML的鸡架子先给它搭好,这样就知道哪里放什么了 ,然后呢,我这里使用了element ui 提供的左侧导航栏可收缩样式,看起来会轻便一些,
输入框本来设想是做一个跳转的,发现没啥页面,就算了,但是依然保留
主要点还是在iframe的使用吧,记住使用时name很重要,它必须跟target标签一致,也就是说,如果你使用a标签跳转,a标签必须添加target属性并且与iframe的name属性一致,好了,看看css样式吧
body{margin: 0px;padding: 0px;
}
[v-cloak]{display: none;
}
.el-menu-vertical-demo{background: rgb(236,245,255);
}
.el-menu-vertical-demo:not(.el-menu--collapse) {width: 200px;height: 770px;
}
.demo-type{height: 60px;width: 40px;
}
.demo-type span{margin-top: 11px;
}
.jump_where{text-decoration: none;
}
从这以后,css就写的少了,主要做一些微调,其它不需要了
那么还是看看我们的js代码吧没啥可说的。
new Vue({el:'#app2',data:{//菜单缩放isCollapse:false,//header搜索state:'',//搜索下拉列表值restaurants:[],},methods:{//过滤筛选对应下拉列表值querySearch(queryString, cb) {let restaurants = staurants;let results = queryString ? restaurants.ateFilter(queryString)) : restaurants;// 调用 callback 返回建议列表的数据cb(results);//查询跳转var newAll=this.loadAll();keydown=function(event){var e = event || window.event || arguments.callee.caller.arguments[0];if(e&&e.keyCode==13){var add=''newAll.filter((item)=>{if(item.value.indexOf(queryString)!=-1){add=item.address}});if(add!=null||add==""){if(add.indexOf(".html")!=-1){window.location.href=""+add}}}};},//创建过滤器createFilter(queryString) {return (restaurant) => {return (restaurant.value.indexOf(queryString) === 0);};},//点击列表跳转handleSelect(ev){console.log(ev.address)window.location.href=""+ev.address},//AJAX传入参数loadAll(){return [{"value": "三全鲜食(北新泾店)","address": "./login.html" },{"value": "Hot honey 首尔炸鸡(仙霞路)","address": "长宁区北新泾街道天山西路490-1号"},{"value": "新旺角茶餐厅"},{"value": "泷千家(天山西路店)"},{"value": "胖仙女纸杯蛋糕(上海凌空店)"},{"value": "贡茶"},];},//登录用户系图标下拉列表selectdrop(e){console.log(e)},//左边导航栏下拉列表select(e,a){console.log(e,a)},},//生命周期钩子方法加载页面传递数据到搜索框restaurants中mounted:function(){let el=document.querySelector('.el-menu')let ifarme=document.querySelector('#uiui')// console.Attribute('src'))console.log(staurants=this.loadAll();}
})
好吧,感觉也没啥可说的,全是套用的element的组件,简直就是抄的,附上效果图吧,也让大家明白点
当当当当,就是这么个效果,low吧,不过只要实现效果就好,毕竟是练习demo,接下来说一说关于这表格的页面把,其中涉及到axios异步读取json文件,接着是xlsx的导入导出功能实现,来看 代码 吧
<!DOCTYPE html>
<html><head><meta charset="utf-8"><title></title></head><!-- elementUI——css cdn --><link rel="stylesheet" href=".css"><!-- 1.css后台css表 --><link rel="stylesheet" href="css/people_management.css" /><body><div id="app3" v-cloak><el-container><el-header><div class="fun_group"><el-button plain icon='el-icon-upload el-icon--right' @click="uploadFile()">导入</el-button><el-button plain icon='el-icon-download' @click="downloadFile(tableData)">下载</el-button><el-button plain icon='el-icon-delete' @click="delBates(Selection)" :disabled='this.Selection.length===0'>批量删除</el-button><el-button plain icon='el-icon-edit-outline' @click="isaddtab=true">添加数据</el-button></div></el-header><el-main><el-dialog title='添加数据' :visible.sync='isaddtab'><div style="width: 250px;margin: auto;"><el-form :model='addform'><el-form-item label='日期' prop='dateTime' label-width='40px'><el-date-picker v-model="addform.dateTime" type="date" placeholder="选择日期"></el-date-picker></el-form-item><el-form-item label='名字' prop='name' label-width='40px'><el-input v-model='addform.name' placeholder='请输入名称' autocomplete="off"></el-input></el-form-item><el-form-item label='地址' prop='address' label-width='40px'><el-input v-model='addform.address' placeholder='地址到县级即可'></el-input></el-form-item><el-form-item><el-button type='primary' @click="handleEditadd">确定</el-button><el-button plain @click='isaddtab=false'>取消</el-button></el-form-item></el-form></div></el-dialog><el-dialog title='更新数据' :visible.sync='isUpdata'><div style="width: 250px;margin: auto;"><el-form :model='updata'><el-form-item label='日期' prop='dateTime' label-width='40px'><el-date-picker v-model="updata.dateTime" type="date" placeholder="选择日期"></el-date-picker></el-form-item><el-form-item label='名字' prop='name' label-width='40px'><el-input v-model='updata.name' placeholder='请输入名称' autocomplete="off"></el-input></el-form-item><el-form-item label='地址' prop='address' label-width='40px'><el-input v-model='updata.address' placeholder='地址到县级即可'></el-input></el-form-item><el-form-item><el-button type='primary' @click="handleEditupdata">确定</el-button><el-button plain @click='isUpdata=false'>取消</el-button></el-form-item></el-form></div></el-dialog><div v-loading.fullscreen.lock='fullscreenLoading' element-loading-text='拼命加载中...'><!-- 导入文件 --><input type="file" @change="importFile(this)" id="imFile" style="display: none"accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel"/><!-- 下载链接 --><a id="downlink"></a></div><el-table :data='tableData' @selection-change='handleSelectionChange'><el-table-column type="selection" width="55"></el-table-column><el-table-column label='日期' prop='dateTime'></el-table-column><el-table-column label='名字' prop='name'></el-table-column><el-table-column label='地址' prop='address'></el-table-column><el-table-column align="left" label='操作'><template slot-scope="scope"><el-buttonsize="mini"@click="handleEdit(scope.$index, w)">更新</el-button><el-buttonsize="mini"type="danger"@click.native.prevent="handleDelete(scope.$index, tableData)">删除</el-button></template></el-table-column></el-table></el-main></el-container></div></body><!-- vue CDN --><script src=".js"></script><!-- 支持vue的elenemtUI封装js CDN --><script src=".js"></script><!-- axios AJAX库 --><script src=".19.0-beta.1/axios.min.js"></script><!-- xlsx表格文件导入导出工具类 --><script src=".15.1/xlsx.full.min.js"></script><!-- people_management.js --><script src="js/people_management.js"></script>
</html>
HTML照搬一下即可实现一样的效果没啥可以说的,css也一样,根本就没有,那么 直接看js
new Vue({el:'#app3',data:{//查询数据// search:"",fullscreenLoading: false,//加载imfile:'',//导入outfile:'',//导出//模拟数据tableData:[{'dateTime': '2016-05-02','name': '王小虎','address': '上海市普陀区金沙江路 1518 弄'}],//储存选中数据Selection:[],//添加数据对话框控件isaddtab:false,//添加数据form表单addform:{dateTime:'',name:'',address:''},//更新数据对话框控件isUpdata:false,//更新数据表单updata:{dateTime:'',name:'',address:''},//控制更新数据下标index:''},mounted(){this.imfileElementById('imFile')this.outfileElementById('downlink');Vue.prototype.$ajax=axios;this.$('./json/file.json').then(res=>{this.tableData=res.data})},methods:{//更新按钮handleEdit(index,row){// let arr=[]// this.$('./json/file.json').then(res=>{// arr=res.data// })this.isUpdata=true;this.updata=rowthis.index=index// this.handleEdit(row)},//更新表单 handleEditupdata(){this.updata.dateTime=this.formatDate(this.updata.dateTime)this.tableData[this.index]=this.updatathis.isUpdata=false;this.$message({message: '更新成功',type: 'success'});},//批量删除delBates(Selection){for(let i=0;i<this.tableData.length;i++){for(let j=0;j<Selection.length;j++){if(this.tableData[i]==Selection[j]){this.tableData.splice(i,1)}}}},//删除操作handleDelete(index,row){row.splice(index, 1);},//时间格式formatDate(date) {if(date instanceof Date){var y = FullYear(); var m = Month() + 1; m = m < 10 ? ('0' + m) : m; var d = Date(); d = d < 10 ? ('0' + d) : d; return y + '-' + m + '-' + d;}return date},//添加操作handleEditadd(){let data=this.addformif(data.dateTime==null||data.dateTime==""){this.$('时间不能为空');}else if(data.name==null||data.name==""){this.$('名字不能为空');}else if(data.address==null||data.address==""){this.$('地址不能为空');}else{data.dateTime=this.formatDate(data.dateTime)this.tableData.push(data)this.isaddtab=falsethis.$message({message: '添加成功',type: 'success'});this.addform={}}},//获取checkbox选中表全部数据handleSelectionChange(val){this.Selection=val},//点击导入按钮uploadFile(){this.imfile.click()},//点击导出按钮 downloadFile(re){let data=[{}]for(let key in re[0]){data[0][key]=key}dataat(re)this.downloadExl(data,"医院信息")},//导入操作change事件importFile() { // 导入excelthis.fullscreenLoading = truelet obj = this.imfileif (!obj.files) {this.fullscreenLoading = falsereturn}var f = obj.files[0] var reader = new FileReader()let $t = load = function (e) {var data = sultif ($t.rABS) {$t.wb = ad(btoa(this.fixdata(data)), { // 手动转化type: 'base64'})} else {$t.wb = ad(data, {type: 'binary'})}let json = XLSX.utils.sheet_to_json($t.wb.Sheets[$t.wb.SheetNames[0]])// console.log(typeof json)$t.dealFile($t.analyzeData(json)) // analyzeData: 解析导入数据}if (this.rABS) {adAsArrayBuffer(f)} else {adAsBinaryString(f)}},//导出操作引用事件具体实现downloadExl(json, downName, type) {// 导出到excellet keyMap = [] // 获取键for (let k in json[0]) {keyMap.push(k)}// console.info('keyMap', keyMap, json)let tmpdata = [] // 用来保存转换好的jsonjson.map((v, i) => keyMap.map((k, j) => Object.assign({}, {v: v[k],position: (j > 25 ? CharCol(j) : String.fromCharCode(65 + j)) + (i + 1)}))).reduce((prev, next) => at(next)).forEach(function (v) {tmpdata[v.position] = {v: v.v}})//替换字符串for(let key in tmpdata){if(tmpdata[key].v=='dateTime'){tmpdata[key].v='日期'}else if(tmpdata[key].v=='name'){tmpdata[key].v='名字'}else if(tmpdata[key].v=='address'){tmpdata[key].v='地址'}}let outputPos = Object.keys(tmpdata) // 设置区域,比如表格从A1到D10let tmpWB = {SheetNames: ['mySheet'], // 保存的表标题Sheets: {'mySheet': Object.assign({},tmpdata, // 内容{'!ref': outputPos[0] + ':' + outputPos[outputPos.length - 1] // 设置填充区域})}}let tmpDown = new Blob([this.s2ab(XLSX.write(tmpWB,{bookType: (type === undefined ? 'xlsx' : type), bookSST: false, type: 'binary'} // 这里的数据是用来定义导出的格式类型))], {type: ''}) // 创建二进制对象写入转换好的字节流var href = ateObjectURL(tmpDown) // 创建对象超链接this.outfile.download = downName + '.xlsx' // 下载名称this.outfile.href = href // 绑定a标签this.outfile.click() // 模拟点击实现下载setTimeout(function () { // 延时释放vokeObjectURL(tmpDown) // 用vokeObjectURL()来释放这个object URL}, 100)},analyzeData(data) { // 此处可以解析导入数据return data},dealFile(data) { // 处理导入的数据// console.log(data[0])//替换表头let newdata=[]for(let i=0;i<data.length;i++){let json1 = JSON.parse(JSON.stringify(data[i]).replace(/日期/g,"dateTime"));let json2 = JSON.parse(JSON.stringify(json1).replace(/名字/g,"name"));let json3 = JSON.parse(JSON.stringify(json2).replace(/地址/g,"address"));newdata.push(json3)}this.imfile.value = ''this.fullscreenLoading = falseif (newdata.length <= 0) {this.$('请导入正确信息');} else {this.$message({message: '导入成功',type: 'success'});this.tableData = newdata}},s2ab(s) { // 字符串转字符流var buf = new ArrayBuffer(s.length)var view = new Uint8Array(buf)for (var i = 0; i !== s.length; ++i) {view[i] = s.charCodeAt(i) & 0xFF}return buf},getCharCol(n) { // 将指定的自然数转换为26进制表示。映射关系:[0-25] -> [A-Z]。let s = ''let m = 0while (n > 0) {m = n % 26 + 1s = String.fromCharCode(m + 64) + sn = (n - m) / 26}return s},fixdata(data) { // 文件流转BinaryStringvar o = ''var l = 0var w = 10240for (; l < data.byteLength / w; ++l) {o += String.fromCharCode.apply(null, new Uint8Array(data.slice(l * w, l * w + w)))}o += String.fromCharCode.apply(null, new Uint8Array(data.slice(l * w)))return o}},})
内容可丰富了,主要讲讲关于axios和xlsx的使用吧 ,axios我是直接赋值给了vue实例原型创建的$ajax上的
mounted(){this.imfileElementById('imFile')this.outfileElementById('downlink');Vue.prototype.$ajax=axios;this.$('./json/file.json').then(res=>{this.tableData=res.data})},
那么,然后就是关于methods的一些方法了,主要说xlsx的使用吧,由于导入导出需要我直接从网上拷了一套使用方式
//导入操作change事件importFile() { // 导入excelthis.fullscreenLoading = truelet obj = this.imfileif (!obj.files) {this.fullscreenLoading = falsereturn}var f = obj.files[0] var reader = new FileReader()let $t = load = function (e) {var data = sultif ($t.rABS) {$t.wb = ad(btoa(this.fixdata(data)), { // 手动转化type: 'base64'})} else {$t.wb = ad(data, {type: 'binary'})}let json = XLSX.utils.sheet_to_json($t.wb.Sheets[$t.wb.SheetNames[0]])// console.log(typeof json)$t.dealFile($t.analyzeData(json)) // analyzeData: 解析导入数据}if (this.rABS) {adAsArrayBuffer(f)} else {adAsBinaryString(f)}},//导出操作引用事件具体实现downloadExl(json, downName, type) {// 导出到excellet keyMap = [] // 获取键for (let k in json[0]) {keyMap.push(k)}// console.info('keyMap', keyMap, json)let tmpdata = [] // 用来保存转换好的jsonjson.map((v, i) => keyMap.map((k, j) => Object.assign({}, {v: v[k],position: (j > 25 ? CharCol(j) : String.fromCharCode(65 + j)) + (i + 1)}))).reduce((prev, next) => at(next)).forEach(function (v) {tmpdata[v.position] = {v: v.v}})//替换字符串for(let key in tmpdata){if(tmpdata[key].v=='dateTime'){tmpdata[key].v='日期'}else if(tmpdata[key].v=='name'){tmpdata[key].v='名字'}else if(tmpdata[key].v=='address'){tmpdata[key].v='地址'}}let outputPos = Object.keys(tmpdata) // 设置区域,比如表格从A1到D10let tmpWB = {SheetNames: ['mySheet'], // 保存的表标题Sheets: {'mySheet': Object.assign({},tmpdata, // 内容{'!ref': outputPos[0] + ':' + outputPos[outputPos.length - 1] // 设置填充区域})}}let tmpDown = new Blob([this.s2ab(XLSX.write(tmpWB,{bookType: (type === undefined ? 'xlsx' : type), bookSST: false, type: 'binary'} // 这里的数据是用来定义导出的格式类型))], {type: ''}) // 创建二进制对象写入转换好的字节流var href = ateObjectURL(tmpDown) // 创建对象超链接this.outfile.download = downName + '.xlsx' // 下载名称this.outfile.href = href // 绑定a标签this.outfile.click() // 模拟点击实现下载setTimeout(function () { // 延时释放vokeObjectURL(tmpDown) // 用vokeObjectURL()来释放这个object URL}, 100)},analyzeData(data) { // 此处可以解析导入数据return data},dealFile(data) { // 处理导入的数据// console.log(data[0])//替换表头let newdata=[]for(let i=0;i<data.length;i++){let json1 = JSON.parse(JSON.stringify(data[i]).replace(/日期/g,"dateTime"));let json2 = JSON.parse(JSON.stringify(json1).replace(/名字/g,"name"));let json3 = JSON.parse(JSON.stringify(json2).replace(/地址/g,"address"));newdata.push(json3)}this.imfile.value = ''this.fullscreenLoading = falseif (newdata.length <= 0) {this.$('请导入正确信息');} else {this.$message({message: '导入成功',type: 'success'});this.tableData = newdata}},s2ab(s) { // 字符串转字符流var buf = new ArrayBuffer(s.length)var view = new Uint8Array(buf)for (var i = 0; i !== s.length; ++i) {view[i] = s.charCodeAt(i) & 0xFF}return buf},getCharCol(n) { // 将指定的自然数转换为26进制表示。映射关系:[0-25] -> [A-Z]。let s = ''let m = 0while (n > 0) {m = n % 26 + 1s = String.fromCharCode(m + 64) + sn = (n - m) / 26}return s},fixdata(data) { // 文件流转BinaryStringvar o = ''var l = 0var w = 10240for (; l < data.byteLength / w; ++l) {o += String.fromCharCode.apply(null, new Uint8Array(data.slice(l * w, l * w + w)))}o += String.fromCharCode.apply(null, new Uint8Array(data.slice(l * w)))return o}},
当然也有一些自己改的地方,比如,导入导出会出现表头如果是英文那么,导入会是英文,而我的数据是需要中文表头的,所以导入我给 替换了一下
let newdata=[]for(let i=0;i<data.length;i++){let json1 = JSON.parse(JSON.stringify(data[i]).replace(/日期/g,"dateTime"));let json2 = JSON.parse(JSON.stringify(json1).replace(/名字/g,"name"));let json3 = JSON.parse(JSON.stringify(json2).replace(/地址/g,"address"));newdata.push(json3)}
导出也一样
//替换字符串for(let key in tmpdata){if(tmpdata[key].v=='dateTime'){tmpdata[key].v='日期'}else if(tmpdata[key].v=='name'){tmpdata[key].v='名字'}else if(tmpdata[key].v=='address'){tmpdata[key].v='地址'}}
这样就可以保障导入不会出现数据key不对称啊,导出表头为英文啊这种问题了
好了 ,就说这么多,持续踩坑中哦
sdkt ,没别的意思,就是推广一下网站,欢迎广州地区有需要中央空调的同志们来本站看看
本文发布于:2024-02-01 04:50:40,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170673424233988.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |