这周遇到一个对我目前来说比较棘手的需求,就是上次excel文件到后台,上传成功后后台立刻返回一个处理过的excel文件。我需要再下载下来。本来想着挺容易,结果做的时候才发现,坑一大堆。
一、构造页面
组件就选用elementUI的el-upload组件,第一个例子就挺适合我的需求的,不过看了一眼代码,发现属性有点多,所以就先选了标签,慢慢添加自己所需要的属性
<el-form-item label="上传文件:" prop="fileList" style="padding:0 24px">
<el-upload class="upload-demo" accept=".jpg,.png" action :before-upload="beforeUpload" :http-request="httpRequest" :file-list="fileList" style="display: flex;">
<div class="el-upload__text" style=" border: 1px solid #d7dde4; padding: 2px 15px; margin-right: 15px; color: #a599a5; border-radius: 5px;">
<i class="el-icon-upload"></i>
<em>选择上传文件</em>
</div>
<div class="el-upload__tip" slot="tip">只能上传excel文件,且不超过500kb</div>
</el-upload>
</el-form-item>
因为框架里请求可能会带有token和加密参数,所以不能使用组件自身的请求,而且自身的请求,好像有好多不能配置,不过最初我使用组件默认的请求是成功了的。
1. 先说下组件默认的请求方式:
1.1、最简单的配置:
action:必选参数--上传的地址
file-list:上传的文件目录---我自己写的时候就有点迷糊,上传一个图片,但是这里面没变化,不知道是不是没上传成功的原因。
name:长传文件的字段名,---要和后端保持一致,不然就会报错---Required request part ‘file‘ is not present
on-success:文件上传成功后的钩子,携带三个参数response, file, fileList,第一个就是成功后返回的请求,第二个第三个是上传的文件。
注:报错问题解决是看了其他以为友友的文章:原文链接:http://t.csdn.cn/igb3w
1.2、设置上传的文件类型:
上传的基本这些了,其他就是上传前后的设置了、比如要设置,只能上传jpg和png的图片,就可以在el-upload标签里设置accept参数:
accept=".jpg,.png"
只设置这个不行,这里知识让选择文件时只显示jpg文件和png文件,如果选择了显示所有文件,就可以继续选择其他类型的文件,所以还要在文件上传前判断上传的文件是否符合要求。那就需要设置另一个参数:
:before-upload="beforeUploadFun"
该属性是上传文件之前的钩子,参数为上传的文件,若返回 false 或者返回 Promise 且被 reject,则停止上传。携带一个参数file,是上传的文件类型信息,
// 上传之前判定文件类型和大小
beforeUpload(file) {
// 判断图片是否大于500kb
const isLt2M = file.size / 1024 / 1024 < 0.5;
// 判断图片的类型
const isJpg = file.type == "image/jpg" || file.type == "image/png";
if (!isJpg) {
this.$message.error("只能上传png和jpg格式的文件!");
return false;
}
if (!isLt2M) {
this.$message.error("上传文件大小不能超过 500kb!");
return false;
}
},
1.3上传成功后的函数
文件上传后也调用一个钩子:on-success="successFun"
on-success(response, file, fileList){
//response就是成功返回的请求,如果有需要处理的数据,就在这里处理
console.log(response)
}
我的需求就是上传成功后返回给我的是一个文件流,转成blob格式后下载,打开就是文件损坏,因此我怀疑是不是组件默认的请求响应方法里有什么是我没有设置的。再加上后面在测试环境调试时应该要携带token,所以就选用自定义方法。
2.自定义上传方法:
使用自定义方法必不可少的就是http-request参数,api里介绍的是会覆盖组件默认的 所以如果设置了这个参数,action就可以为空,但不可以没有。
httpRequest(file) {
const formData = new FormData();
formData.append("fil", file.file);
apis.export("url",formData).then(data => {
console.log(data);
// console.log(data)
if (data.data.type == "application/vnd.ms-excel") {
this.uploadText = true;
saveAs(data.data, "文件名称" + ".xlsx");
} else {
console.log("可能上传不成功");
}
}).catch(err => {
console.log(err);
});
},
因为我做的是上传excel文件,所以上传文件先转换成formData类型, 注意:1.axios里responseType: 'blob',必须 2.请求头一定不要设置,任何类型都不要设置,不然就会一直报Required request part ‘file‘ is not present,尽管你已经formData.append("fil", file.file);fil和后端一致了,也会报错,我就是这个问题困扰了两天,在论坛翻来翻去,无意间看到有一篇文字写到了,不过找不到是哪一篇帖子了。
注:有什么地方记录的不对的地方或者有什么更好的写法,还望帮忙指出来,一定虚心改正。
还有就是下载文件流一定要设置responseType: 'blob',不然下载后文件就会损坏