vue导入excel文件|vue导入excel文件,vue导入多个sheets的方式

目录

  • html 导入按钮和选择文件的弹框
  • js 重中之重 导入 excel 开始啦
    • 1.data里面的数据
    • 2. 导入弹框
    • 3. 导入方法
    • 4.确认导入
  • vue导入处理excel表格
    • 1.vue导入Excel表格
    • 2. 总体代码与效果
用input 导入 excel ,然后生成表格,然后调用接口上传到后台

html 导入按钮和选择文件的弹框 vue导入excel文件|vue导入excel文件,vue导入多个sheets的方式
文章图片
vue导入excel文件|vue导入excel文件,vue导入多个sheets的方式
文章图片

导入取消提交


js 重中之重 导入 excel 开始啦 【vue导入excel文件|vue导入excel文件,vue导入多个sheets的方式】
1.data里面的数据
excelImportShow: false,//导入文件的弹框uploadArr: [],// 上传给后台的数据realname: '',// 以下都是我要转换的数据,因人而异gender: '',age: '',minzu: '',wenhua: '',shengfenzheng: '',job: '',mobile: '',mark: ''


2. 导入弹框
daoru() {this.excelImportShow = true},


3. 导入方法
vue导入excel文件|vue导入excel文件,vue导入多个sheets的方式
文章图片

// 导入importfxx(obj) {let _this = this; let inputDOM = this.$refs.inputer; // 通过DOM取文件数据this.file = event.currentTarget.files[0]; var rABS = false; //是否将文件读取为二进制字符串var f = this.file; var reader = new FileReader(); FileReader.prototype.readAsBinaryString = function(f) {var binary = ""; var rABS = false; //是否将文件读取为二进制字符串var pt = this; var wb; //读取完成的数据var outdata; var reader = new FileReader(); reader.onload = function(e) {var bytes = new Uint8Array(reader.result); var length = bytes.byteLength; for (var i = 0; i < length; i++) {binary += String.fromCharCode(bytes[i]); }var XLSX = require('xlsx'); if (rABS) {wb = XLSX.read(btoa(fixdata(binary)), { //手动转化type: 'base64'}); } else {wb = XLSX.read(binary, {type: 'binary'}); }outdata = https://www.it610.com/article/XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]); //outdata就是你想要的东西this.da = [...outdata]let arr = []let nameArr = outdata[1]for (let v in nameArr) {// 拿到 excel 里面的列名,根据列名得到里面的键名let title = nameArr[v]switch (title){case'姓名':console.log('这是姓名',nameArr[v]); _this.realname = vconsole.log('这是realname',v); break; case '性别':console.log('这是性别',nameArr[v]); _this.gender = vconsole.log('这是gender',v); break; case '年龄':console.log('这是年龄',nameArr[v]); _this.age = vconsole.log('这是age',v); break; case '民族':console.log('这是民族',nameArr[v]); _this.minzu = vconsole.log('这是minzu',v); break; case '学历':console.log('这是性别',nameArr[v]); _this.wenhua = vconsole.log('这是job',v); break; case '身份证号':console.log('这是身份证号',nameArr[v]); _this.shengfenzheng = vconsole.log('这是shenfengzheng',v); break; case '工作单位/学校/社区':console.log('"工作单位/学校/社区"',nameArr[v]); _this.job = vconsole.log('这是job',v); break; case '手机/电话':console.log('这是手机/电话',nameArr[v]); _this.mobile = vconsole.log('这是mobile',v); break; case '备注':console.log('这是备注',nameArr[v]); _this.mark = vconsole.log('这是mark',v); break; default:break; }}let objlet uploadArr = []// 这里是一个excel里面会有多个sheets,把里面的恶数据整个到这个数组里面一起上传let leng = Object.keys(wb.Sheets).length// 用for循环,leng 是sheets的个数,用来循环次数for (var i = 0; i < leng+1; i++) {XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[i]])let arrr = XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[i]])arrr = arrr.slice(2)//如果从第三行开始是数据,那这里就是1,如果从第四行开始是数据,那这里就是2uploadArr.push.apply(uploadArr,arrr)_this.uploadArr = uploadArr}this.da.map(v => {let obj = {}obj.id = v.idobj.status = v.statusarr.push(obj)})let para = {withList: arr}_this.$message({message: '请耐心等待导入成功',type: 'success'}); }reader.readAsArrayBuffer(f); }if (rABS) {reader.readAsArrayBuffer(f); } else {reader.readAsBinaryString(f); }},


4.确认导入
(其实这里就是上传到后台接口的,存到数据库里面才能保存)
// 确认导入submit() {let uploadArr = this.uploadArrthis.excelImportShow = falselet objfor (let v in uploadArr) {obj = {realname:uploadArr[v][""+this.realname+""],age:uploadArr[v][""+this.age+""],gender: uploadArr[v][""+this.gender+""]=='男'?'MALE':'FEMALE',minzu: uploadArr[v][""+this.minzu+""],wenhua: uploadArr[v][""+this.wenhua+""],shengfenzheng: uploadArr[v][""+this.shengfenzheng+""],job: uploadArr[v][""+this.job+""],wenhua: uploadArr[v][""+this.wenhua+""],mobile:uploadArr[v][""+this.mobile+""],mark:uploadArr[v][""+this.mark+""],place: "00"}// 这里的obj 就是后台需要的参数,用变量表示键名 [""+此处是你的变量+""]createUser(obj).then((res) => {这是后台添加的方法if (res.data.return_code === '200') {this.dialogFormVisible = false} else {this.$notify.error(res.data.return_msg)}})if (parseInt(v) === parseInt(uploadArr.length)-1) {console.log(v+'和'+uploadArr.length); setTimeout(()=>{this.$notify({title: '成功',message: '创建成功',type: 'success',duration: 2000})this.getList({ page: 1,limit: 20 })// 添加成功之后调用list 接口,展示所添加的数据},1500)}}},


vue导入处理excel表格 最近遇到前端导入并处理excel表格的情况,趁此机会刚好研究一下vue导入并处理excel数据;当然自己手撸一个工具没有那么多时间,本文只是借助现有的工具来做一下工具使用总结。

1.vue导入Excel表格
vue导入Excel表格主要有两种常用的方法,一个是借助ElementUI文件上传进行表格导入,另一个是自带的input做文件上传;以下对两个方法做详细介绍;
1.1 使用ElementUI中的upload组件 安装ElementUI
npm i element-ui -S

安装Excel表格解析插件
npm i xlsx -S

导入需要用的工具包
import Vue from "vue"; import ElementUI from "element-ui"; import "element-ui/lib/theme-chalk/index.css"; import { read, utils } from "xlsx"; // 注意处理方法引入方式Vue.use(ElementUI);

引入组件

添加处理逻辑
// 导入成功时执行handleChange(res, file, fileList) {// 将文件放入for (let i = 0; i < fileList.length; i++) {if (file.name != fileList[i].name) {this.fileList.push({name: file.name,url: "",uid: file.uid}); }}const files = { 0: file }; this.readExcel(files); },readExcel(file) {const fileReader = new FileReader(); fileReader.onload = ev => {try {const data = https://www.it610.com/article/ev.target.result; const workbook = read(data, { type:"binary" }); const params = []; // 取对应表生成json表格内容workbook.SheetNames.forEach(item => {this.tableData.push(utils.sheet_to_json(workbook.Sheets[item])); }); // 该算法仅针对表头无合并的情况if (this.tableData.length > 0) {// 获取excel中第一个表格数据tableData[0][0],并且将表头提取出来for (const key in this.tableData[0][0]) {this.tableHead.push(key); }}// 重写数据} catch (e) {console.log("error:" + e); return false; }}; fileReader.readAsBinaryString(file[0].raw); }

以上处理的数据我这边用组件展示在了页面上,效果如下图:
vue导入excel文件|vue导入excel文件,vue导入多个sheets的方式
文章图片

1.2 使用input文件上传 安装Excel表格解析插件
npm i xlsx -S

导入需要用的工具包
import { read, utils } from "xlsx"; // 注意处理方法引入方式

使用input
文件上传(input):

添加处理逻辑
基本与上面处理逻辑相同
onChange(e) {const file = e.target.files[0]; const fileReader = new FileReader(); fileReader.onload = ev => {try {const data = https://www.it610.com/article/ev.target.result; const workbook = read(data, { type:"binary" }); const params = []; // 取对应表生成json表格内容workbook.SheetNames.forEach(item => {params.push({name: item,dataList: utils.sheet_to_json(workbook.Sheets[item])}); this.tableData.push(utils.sheet_to_json(workbook.Sheets[item])); }); // 该算法仅针对表头无合并的情况if (this.tableData.length > 0) {// 获取excel中第一个表格数据tableData[0][0],并且将表头提取出来for (const key in this.tableData[0][0]) {this.tableHead.push(key); }}return params; // 重写数据} catch (e) {console.log("error:" + e); return false; }}; fileReader.readAsBinaryString(file); }


2. 总体代码与效果
效果如下:

总的样式以及代码如下:


.upload-demo {width: 100%; }.flex-display {margin: 50px 30px; width: 100%; display: flex; justify-content: flex-start; .left-box {margin: 20 30; height: 36px; line-height: 36px; }}.el-upload {margin-left: 40px; .el-btn {font-size: 16px; }.el-upload-tip {display: inline; font-size: 12px; }}.file-ipt {width: 200px; height: 36px; line-height: 36px; button {background-color: #409eff; }}input #file-upload-button {background-color: #409eff; }

总结:较为容易踩坑的点就是xlsx这个包的导入方式,这个包处理excel表格功能时相当强大的,除了导入与数据解析,还有导出为excel等功能,在我们日常网站开发中非常常用。其次容易踩坑的就是vue中事件的监听与处理方式,我们可以看到使用组件贺不使用组件区别还是比较大的,当然使用现有组件往往能获得更好的效果,所以这里还是推荐大家使用方法一去实现这个功能。
最后本文仅对数据做简单处理,若要处理更为复杂的表格数据,就需要研究更强大的算法,不喜勿碰。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

    推荐阅读