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><!-- 1. 上传 导入 --><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// 上传文件解析csvasync 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>
抽取工具类
- excelUtil.js
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;
}
- 使用工具类方式 实现excel文件转json, 完整代码
<template>
<div><!-- 1. 上传 导入 --><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>