这篇文章主要介绍了vue怎么导入excel文件和多个sheets的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇vue怎么导入excel文件和多个sheets文章都会有所收获,下面我们一起来看看吧。
<el-button v-waves :loading='downloadLoading' class='filter-item' type='primary' icon='el-icon-download' @click='daoru'>
导入
</el-button>
<el-dialog title="导入文件" :visible.sync="excelImportShow">
<a rel="external nofollow" href="javascript:;" rel="external nofollow" class="file">
<input id="upload" type="file" @change="importfxx(this)" accept=".csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel" />
</a>
<div id="demo"></div>
<div slot="footer" class="dialog-footer">
<el-button @click.native="excelImportShow = false">取消</el-button>
<el-button type="primary" @click.native="submit">提交</el-button>
</div>
</el-dialog>
1.data里面的数据
JavaScript
excelImportShow: false, //导入文件的弹框
uploadArr: [], // 上传给后台的数据
realname: '', // 以下都是我要转换的数据,因人而异
gender: '',
age: '',
minzu: '',
wenhua: '',
shengfenzheng: '',
job: '',
mobile: '',
mark: ''
2. 导入弹框
JavaScript
daoru() {
this.excelImportShow = true
},
3. 导入方法
JavaScript
// 导入
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 = 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 = v
console.log('这是realname',v);
break;
case '性别':
console.log('这是性别',nameArr[v]);
_this.gender = v
console.log('这是gender',v);
break;
case '年龄':
console.log('这是年龄',nameArr[v]);
_this.age = v
console.log('这是age',v);
break;
case '民族':
console.log('这是民族',nameArr[v]);
_this.minzu = v
console.log('这是minzu',v);
break;
case '学历':
console.log('这是性别',nameArr[v]);
_this.wenhua = v
console.log('这是job',v);
break;
case '身份证号':
console.log('这是身份证号',nameArr[v]);
_this.shengfenzheng = v
console.log('这是shenfengzheng',v);
break;
case '工作单位/学校/社区':
console.log('"工作单位/学校/社区"',nameArr[v]);
_this.job = v
console.log('这是job',v);
break;
case '手机/电话':
console.log('这是手机/电话',nameArr[v]);
_this.mobile = v
console.log('这是mobile',v);
break;
case '备注':
console.log('这是备注',nameArr[v]);
_this.mark = v
console.log('这是mark',v);
break;
default:
break;
}
}
let obj
let 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,如果从第四行开始是数据,那这里就是2
uploadArr.push.apply(uploadArr,arrr)
_this.uploadArr = uploadArr
}
this.da.map(v => {
let obj = {}
obj.id = v.id
obj.status = v.status
arr.push(obj)
})
let para = {
withList: arr
}
_this.$message({
message: '请耐心等待导入成功',
type: 'success'
});
}
reader.readAsArrayBuffer(f);
}
if (rABS) {
reader.readAsArrayBuffer(f);
} else {
reader.readAsBinaryString(f);
}
},
4.确认导入
(其实这里就是上传到后台接口的,存到数据库里面才能保存)
JavaScript
// 确认导入
submit() {
let uploadArr = this.uploadArr
this.excelImportShow = false
let obj
for (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)
}
}
},
1.vue导入Excel表格
vue导入Excel表格主要有两种常用的方法,一个是借助ElementUI文件上传进行表格导入,另一个是自带的input做文件上传;以下对两个方法做详细介绍;
1.1 使用ElementUI中的upload组件 安装ElementUI
JavaScript
npm i element-ui -S
安装Excel表格解析插件
JavaScript
npm i xlsx -S
导入需要用的工具包
JavaScript
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);
引入组件
<el-upload
action="https://jsonplaceholder.typicode.com/posts/"
:on-success="handleChange"
:file-list="fileList"
class="el-upload"
>
添加处理逻辑
JavaScript
// 导入成功时执行
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 = 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);
}
以上处理的数据我这边用组件展示在了页面上,效果如下图:
1.2 使用input文件上传 安装Excel表格解析插件
JavaScript
npm i xlsx -S
导入需要用的工具包
JavaScript
import { read, utils } from "xlsx"; // 注意处理方法引入方式
使用input
<div class="flex-display">
<div class="left-box">文件上传(input):</div>
<input type="file" v-on:change="onChange" class="file-ipt" />
</div>
添加处理逻辑
基本与上面处理逻辑相同
JavaScript
onChange(e) {
const file = e.target.files[0];
const fileReader = new FileReader();
fileReader.onload = ev => {
try {
const data = 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. 总体代码与效果
效果如下:
总的样式以及代码如下:
<template>
<div>
<div class="flex-display">
<div class="left-box">表格上传(ElementUI):</div>
<el-upload
action="https://jsonplaceholder.typicode.com/posts/"
:on-success="handleChange"
:file-list="fileList"
class="el-upload"
>
<el-button size="small" type="primary" class="el-btn"
>点击上传</el-button
>
<div slot="tip" class="el-upload-tip">
只能上传xlsx文件,且不超过5MB
</div>
</el-upload>
</div>
<el-table v-if="tableHead.length" :data="tableData[0]" >
<el-table-column
v-for="(data, key) in tableHead"
:prop="data"
:label="data"
:key="key"
width="180"
>
</el-table-column>
</el-table>
<div class="flex-display">
<div class="left-box">文件上传(input):</div>
<input type="file" v-on:change="onChange" class="file-ipt" />
</div>
</div>
</template>
JavaScript
<script>
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);
export default {
data() {
return {
fileList: [], //上传文件列表
tableHead: [], //表头
tableData: [] // 表数据
};
},
methods: {
onChange(e) {
const file = e.target.files[0];
const fileReader = new FileReader();
fileReader.onload = ev => {
try {
const data = 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);
},
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
});
}
}
// this.fileList = fileList.slice(-3);
const files = { 0: file };
this.readExcel(files);
},
readExcel(file) {
const fileReader = new FileReader();
fileReader.onload = ev => {
try {
const data = 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[0].raw);
}
}
};
</script>
CSS
<style lang="scss" scoped>
.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;
}
</style>