这个问题搞了我好久;
话不多说;
前端
<v-btn
class="ma-2 white--text"
color="blue-grey"
fab
@click="upload"
>
<v-icon dark>mdi-cloud-upload</v-icon>
</v-btn>
<input type="file" id="upload" ref="upload" @change="changefile" accept=".xlsx">
accept规定文件格式
upload () {
let uploadbtn = this.$refs.upload
uploadbtn.click()
},
changefile (e) {
let formData=new FormData()
formData.append('file', e.target.files[0])
upLoad(formData)
.then(res => {
if (res.status === 200) {
this.bookList();
}
})
.catch(err => {
console.log(err);
});
}
这里请求头header还要加个东西;所以;我重新封装了一个post;后面附上ajax封装代码;
这里是将formData传送给后台;注意我是单文件传输;
这就是前端代码;接下来重点了;后端代码
后端代码(egg)
在写代码前注意几个问题
1 Excel
这里我们需要使用插件来处理Excel,xlsx js
使用方法很简单:
1、安装
npm install xlsx --save-dev
或者:
yarn add xlsx --save-dev
2、引入
const XLSX = require('xlsx');
2 stream的配置
在config.default.js中添加以下代码
在这里插入代码片
multipart: {
fileSize: ‘50mb’, // 文件大小
mode: ‘stream’, // 必须写;千万别写错
whitelist: [ ‘.xlsx’ ], // 文件类型白名单;报400错;一般就是你没写这句话;允许接收解析该类型文件;
},
这里默认excel表的表头第一行是key;
controller层
async upLoad() {
const { ctx } = this;
const stream = await ctx.getFileStream();//单文件读取方法
console.log(stream.filename);//这里能打印说明没啥问题
// const exceldata = [];
await stream.on('data', function(chunk) {
// 读取内容流的方式 stream.on方法读取内容 ;该方法不会的可以查查;
const workbook = XLSX.read(chunk, { type: 'buffer' });// 读取excel表
//将stream读取的内容chunk给xlsx以buffer形式读取;
//这里可以尝试打印console.log(workbook);
const sheetNames = workbook.SheetNames; // 工作表名称集合;也就是excel里面有几张表
sheetNames.forEach(name => {
const worksheet = workbook.Sheets[name]; // 只能通过工作表名称来获取指定工作表
const headers = {};
const data = [];
const keys = Object.keys(worksheet);
keys
// 过滤以 ! 开头的 key
.filter(k => k[0] !== '!')
// 遍历所有单元格
.forEach(k => {
// 如 A11 中的 A
const col = k.substring(0, 1);
// 如 A11 中的 11
const row = parseInt(k.substring(1));
// 当前单元格的值
const value = worksheet[k].v;
// 保存字段名
if (row === 1) {
headers[col] = value;
return;
}
// 解析成 JSON
if (!data[row]) {
data[row] = {};
}
data[row][headers[col]] = value;
});
console.log(data);//解析成功的json数据
});
});
ctx.body = { result: 1 };//这个随便写的
ctx.status = 200;
}
搞定;
对excel 和stream 结构不是很清楚的看下面的;
stream方法详解
针对文件封装的post方法
postFile(url,params){
return new Promise((resolve,reject)=>{
axios({
url,
method:'post',
transformRequest: [function (data) {
// 对 data 进行任意转换处理
return data
}],
headers: {
'Content-Type': 'multipart/form-data'
},
data:params
}).then(res=>{
resolve(res)
}).catch(err=>{
reject(err)
})
})
}
// 上传文件
export const upLoad=params=>{
return axios.postFile(`${host}${apiBook}/upLoad`,params)
}
这个是接口