vue 导入excel并转为json发送给后端
可以处理.xlsx , .csv , .xls 格式的文件
# 用于操作excel .xlsx .xls
npm install xlsx --save
# papaparse用于操作.csv 文件 jschardet编码解析
npm install papaparse --save
npm install jschardet --save
<template>
<div>
<el-upload action accept=".xlsx,.csv,.xls" :auto-upload="false" :on-change="handleImportFile" :show-file-list="false">
<el-button icon="el-icon-upload2">导入el-button>
el-upload>
div>
template>
<script>
// 2. 引入插件
// import xlsx from "xlsx"; // 使用这种方式引入时报错了
import * as xlsx from "xlsx";
import Papa from "papaparse";
export default {
data() {
return {
// 3.添加属性
changeCnToEn: {
姓名: "name",
年龄: 'age'
},
};
},
method: {
// 4. 处理选择文件回调
async handleImportFile() {
// 获取文件类型
const fileType = e.name.split(".")[e.name.split(".").length - 1];
let excelArr = "";
switch (fileType) {
case "csv":
excelArr = await this.importCsv(e.raw);
break;
case "CSV":
excelArr = await this.importCsv(e.raw);
break;
case "xlsx":
excelArr = await this.importXls(e.raw);
break;
case "xls":
excelArr = await this.importXls(e.raw);
break;
}
console.log(excelArr); // 数组对象 就是Excel里的数据
setTimeout(() => {
// 发给后端
// this.httpUpload(excelArr);
}, 500);
},
// 7. 请求后端接口
httpUpload(excelArr) {
const params = {
xxx: excelArr, // 表格数据
}
request({
url: '',
method: 'post',
params: leadData
}).then(res => {
console.log(res, 'res');
})
},
// 5. 解析excel为JSON
// 上传xlsx xls文件
async importXls(file) {
if (!file) return;
let data = await this.readFile(file);
// type :'binary' 类型为二进制
let eleData = xlsx.read(data, {
type: "binary"
});
let eleDataSheet = eleData.Sheets[eleData.SheetNames[0]];
eleData = xlsx.utils.sheet_to_json(eleDataSheet); // 将解析出的数据转换为json格式(xlsx自带的方法)
// eleData = eleData.length >1? eleData[1] : eleData[0]
const arr = [];
console.log(Object.keys(this.changeCnToEn));
eleData.forEach((item) => {
const userInfo = {};
Object.keys(item).forEach((key) => {
userInfo[this.changeCnToEn[key]] = item[key];
});
arr.push(userInfo);
});
return arr;
},
// 把文件按照二进制方式读取
readFile(file) {
return new Promise((resolve) => {
let reader = new FileReader();
reader.readAsBinaryString(file);
reader.onload = (ev) => {
resolve(ev.target.result);
};
});
},
// 6. 解析csv文件为JSON
// 上传文件解析csv
async importCsv(file) {
return new Promise((resolve) => {
let fReader = new FileReader();
fReader.readAsDataURL(file);
fReader.onload = (evt) => {
// 检查编码
let encoding = this.checkEncoding(evt.target.result);
// 将csv转换成二维数组
Papa.parse(file, {
encoding,
complete: (res) => {
// UTF8 \r\n与\n混用时有可能会出问题
let data = res.data;
if (data[data.length - 1] == "") {
//去除最后的空行
data.pop();
}
const dataKeys = Object.values(this.changeCnToEn);
let resArr = [];
data.forEach((element, index) => {
const resInfo = {};
if (index > 0) {
dataKeys.forEach((item, j) => {
resInfo[item] = element[j];
});
resArr.push(resInfo);
}
});
console.log(resArr);
// console.log(data)
resolve(resArr);
},
});
};
});
},
// 编码转换
checkEncoding(base64Str) {
// 这种方式得到的是一种二进制串
let str = atob(base64Str.split(";base64,")[1]);
// 要用二进制格式
const jschardet = require("jschardet");
let encoding = jschardet.detect(str);
encoding = encoding.encoding;
if (encoding === "windows-1252") {
encoding = "ANSI";
}
return encoding;
},
}
};
script>
抽取工具类
import * as xlsx from "xlsx";
import Papa from "papaparse";
// 使用:
/**
const excelArr = await xlsxToJson(file.raw);
const excelArr = await csvToJson(file.raw);
console.log(excelArr); // 数组对象 就是Excel里的数据
*/
/**
* 将xlsx, xls格式excel文件转为json数据
* @param {*} file excel文件
* @param {*} tableHeadCnToEn excel表头文字和字段的对应 示例: { 姓名: 'name', 年龄: 'age' }
* @returns
*/
export async function xlsxToJson(file, tableHeadCnToEn) {
if (!file) return;
// 读取file文件的内容(转换为json格式)
let data = await readFile(file);
// console.log(data); //解析出的二进制文件
// type :'binary' 类型为二进制
let eleData = xlsx.read(data, { type: "binary" });
let eleDataSheet = eleData.Sheets[eleData.SheetNames[0]];
eleData = xlsx.utils.sheet_to_json(eleDataSheet); // 将解析出的数据转换为json格式(xlsx自带的方法)
const arr = [];
eleData.forEach((item) => {
const userInfo = {};
Object.keys(item).forEach((key) => {
userInfo[tableHeadCnToEn[key]] = item[key];
});
arr.push(userInfo);
});
return arr;
}
/**
* 将csv格式excel文件转为json数据
* @param {*} file excel文件
* @param {*} tableHeadCnToEn excel表头文字和字段的对应 示例: { 姓名: 'name', 年龄: 'age' }
* @returns
*/
export async function csvToJson(file, tableHeadCnToEn) {
return new Promise((resolve) => {
let fReader = new FileReader();
fReader.readAsDataURL(file);
fReader.onload = (evt) => {
// 检查编码
let encoding = checkEncoding(evt.target.result);
// 将csv转换成二维数组
Papa.parse(file, {
encoding,
complete: (res) => {
// UTF8 \r\n与\n混用时有可能会出问题
let data = res.data;
if (data[data.length - 1] == "") {
//去除最后的空行
data.pop();
}
const dataKeys = Object.values(tableHeadCnToEn);
let resArr = [];
data.forEach((element, index) => {
const resInfo = {};
if (index > 0) {
dataKeys.forEach((item, j) => {
resInfo[item] = element[j];
});
resArr.push(resInfo);
}
});
resolve(resArr);
},
});
};
});
}
// 把文件按照二进制方式读取
function readFile(file) {
return new Promise((resolve) => {
let reader = new FileReader();
reader.readAsBinaryString(file);
reader.onload = (ev) => {
resolve(ev.target.result);
};
});
}
// 编码转换
function checkEncoding(base64Str) {
// 这种方式得到的是一种二进制串
let str = atob(base64Str.split(";base64,")[1]);
// 要用二进制格式
const jschardet = require("jschardet");
let encoding = jschardet.detect(str);
encoding = encoding.encoding;
if (encoding === "windows-1252") {
encoding = "ANSI";
}
return encoding;
}
<template>
<div>
<el-upload action accept=".xlsx,.csv,.xls" :auto-upload="false" :on-change="handleImportFile" :show-file-list="false">
<el-button icon="el-icon-upload2">导入el-button>
el-upload>
div>
template>
<script>
import { xlsxToJson, csvToJson } from "@/utils/excelUtil.js";
export default {
data() {
return {
// 3.添加属性
changeCnToEn: {
姓名: "name",
年龄: 'age'
},
};
},
method: {
// 4. 处理选择文件回调
async handleImportFile() {
// 获取文件类型
const fileType = e.name.split(".")[e.name.split(".").length - 1];
let excelArr = "";
switch (fileType) {
case "csv":
excelArr = await csvToJson(e.raw, this.changeCnToEn);
break;
case "CSV":
excelArr = await csvToJson(e.raw, this.changeCnToEn);
break;
case "xlsx":
excelArr = await xlsxToJson(e.raw, this.changeCnToEn);
break;
case "xls":
excelArr = await xlsxToJson(e.raw, this.changeCnToEn);
break;
}
console.log(excelArr); // 数组对象 就是Excel里的数据
setTimeout(() => {
// 发给后端
// this.httpUpload(excelArr);
}, 500);
},
// 7. 请求后端接口
httpUpload(excelArr) {
const params = {
xxx: excelArr, // 表格数据
}
request({
url: '',
method: 'post',
params: leadData
}).then(res => {
console.log(res, 'res');
})
},
}
};
script>