需求:上传excel表格到服务器,然后接收返回的结果(二进制)并转成excel表格下载
实施:采用 Element-UI的uploade 组件,功能较全且有完整的生命周期钩子可设置。
<el-upload
class="upload-demo"
ref="upload"
action=""
:on-remove="handleRemove"
:on-error="handleError"
:file-list="fileList"
:auto-upload="false"
:limit=1
>
<el-button
slot="trigger"
size="small"
type="primary"
>选取文件</el-button>
</el-upload>
问题1:post请求,不能用window.open(_url)的方式触发浏览器下载。
解决方法:blob对象,将二进制转成文件,在DOM中增加一个a标签,href设置成转出文件地址,手动触发a标签的click事件。
downloadFile(data) {
if (!data) {
return;
}
let url = window.URL.createObjectURL(new Blob([data]));
let link = document.createElement("a");
link.style.display = "none";
link.href = url;
link.setAttribute("download", "check.xlsx");
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
ok,成功下载了.xlsx文件。
问题2:下载的.xlsx文件无法打开,office excel 提示文件被损坏
解决方法:
采用原生的Request对象发送请求,拿到返回的Response,再调用 downloadFile() 方法
var formData = new FormData();//FormData对象用以将数据编译成键值对,以便用XMLHttpRequest来发送数据
formData.append("file", this.$refs.upload.uploadFiles[0].raw);//拿到组件中的上传文件的原始数据,添加到FormData中
var xhr = new XMLHttpRequest();
xhr.responseType = "blob";//设置responseType 为 blob
xhr.open(
"POST",
"http://devserver.6tiantian.com/ajax/question-bank-service/admin/question/knowledge_tag/check",
true
);
xhr.onload = function() {
this.downloadFile(xhr.response);
}.bind(this);
xhr.send(formData); //发送请求
},
原因分析:Uploader组件包装了上传的文件/请求,导致返回的数据类型出现错误,无法转换成真正的.xlsx文件。
经试验,用 uploader 自带的 this.$refs.upload.submit() 发送请求,用 on-success(response,file,fileList)钩子获取到的response类型为string,而 XMLHttpRequest 发送的请求得到的response类型为 object。
art.js/