1. 文件导出
常用的文件导出方式有两种:
1.1 根据后端返回的url导出
请求后端接口,获取返回的url ,直接window.location.href = url;
1.2 后端返回文件流导出
后端返回文件流的处理,一般是获取流文件,然后创建a标签,添加href属性,再打开访问,项目用的多可以封装一个专门的导出请求,示例:
import axios from 'axios'
const postDownload = function (url, params = {}, data = {}) { //定义postDownload方法
return new Promise((resolve, reject) => {
axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8';
axios.post(url, params, {
params: data,
responseType: "blob"
})
.then(response => {
let headers = response.headers;
let name = headers['content-disposition'];//这里如果没有获取到,联系后端设置一下headers
let filename = "";
let t = /filename="([^;]*);?"/i.exec(name);
null === t && (t = /filename=([^;]*);?/i.exec(name));
if (null !== t && t.length > 1) {
filename = decodeURIComponent(t[1]); //以上几步是为了获取传递过来的文件名,
}
let blob = new Blob([response.data], { //ArrayBuffer转为Blob
type: "application/octet-stream"
});
let downloadElement = document.createElement('a'); //创建a标签
let href = window.URL.createObjectURL(blob);
downloadElement.href = href; //设置href属性
downloadElement.download = filename; //设置文件名
document.body.appendChild(downloadElement);
downloadElement.click();
document.body.removeChild(downloadElement);
window.URL.revokeObjectURL(href); //释放创建的URL对象
resolve(response.data);
}, err => {
reject(err);
});
});
}
export{
postDownload
}
2.文件导入
element ui + vue 的项目,使用el-upload组件,如果仅仅导入文件没有传参需求,通常action绑定上传地址即可,如果需要传递参数,则可绑定http-request自定义上传事件
自定义上传事件导入压缩包,并实时显示进度条实例(解析文件包内容的部分注释掉了,根据需要拿):
html部分:
<el-upload
class="upload-demo"
action // 没有传参需求,此处可直接绑定地址
accept=".zip,.tar" //限制文件格式
:show-file-list="false"
:auto-upload="false" //自动上传关闭
ref="upload"
:http-request="requestHandler" //自定义上传事件
:on-change="handleChange"
:on-exceed="exceedHanlder"
>
<el-button type="primary" style="width: 200px"
>任务导入安装包</el-button
>
<div>
{{ fileName }}<i class="iconfont" v-if="isComplete"></i> //展示文件名,此处用了iconfont图标
</div>
<el-progress
v-if="isPercentage" //data中申明的变量,用于确定进度条的显示隐藏,默认false
class="progress"
:stroke-width="10"
style="width: 100px"
:percentage="percentage"
></el-progress>
</el-upload>
js部分:
handleChange(file, fileList) {
if (fileList.length > 1) {
fileList.splice(0, 1); //保持上传的文件只有一个,点击按钮导入的时候替换之前的包
}
this.fileName = file.name;
this.isComplete = false; //引入的icon图标是否展示,
如果项目需要解析包里的内容,需要封装一个promise拿到reading.onload里解析的结果resolve出来
直接全局定义变量然后赋值,在外部是拿不到这个结果的
// return new Promise((resolve, reject) => {
// let reader = new FileReader(); //先new 一个读文件的对象 FileReader
// if (typeof FileReader === "undefined") {
// //用来判断你的浏览器是否支持 FileReader
// this.$message({
// type: "info",
// message: "您的浏览器不支持文件读取。",
// });
// return;
// }
// // reader.readAsText(file.raw, "gb2312"); //读.txt文件
// reader.readAsArrayBuffer(file.raw); //读任意文件
// reader.onload = function (e) {
// var ints = new Uint8Array(e.target.result); //要使用读取的内容,所以将读取内容转化成Uint8Array
// ints = ints.slice(0, 5000); //截取一段读取的内容
// let snippets = new TextDecoder("gb2312").decode(ints); //二进制缓存区内容转化成中文(即也就是读取到的内容)
// console.log("读取的内容如下:");
// console.log(snippets);
// resolve(snippets);
// };
// }).then((res) => {
// console.log(res, "res");
// this.fileMessage = res;
// });
},
exceedHanlder(files, fileList) {
this.$message({ type: "warning", message: "只能上传一个文件" });
},
requestHandler(param) {
let params = new FormData(); //自定义上传事件,FormData格式上传文件,顺便携带project_name参数
params.append("file", param.file);
params.append("project_name", this.taskImportForm.name);
const config = {
onUploadProgress: (progressEvent) => { //通过回调函数拿到上传文件的实时信息,进度条percentage赋值
// progressEvent.loaded:已上传文件大小
// progressEvent.total:被上传文件的总大小
this.isPercentage = true;
this.percentage = Number(
((progressEvent.loaded / progressEvent.total) * 100).toFixed(2)
);
},
};
//axios需要引入一下,这里没有封装请求的方法
axios.post("http://192.168.40.183:8000/api/files/upload_zip", params, config)
.then((res) => {
if (res.data.code == 200) {
this.isPercentage = false;
this.isComplete = true;
this.packageInfoList = res.data.data;
this.$message({
type: "success",
message: "上传成功",
});
} else {
this.$message.error("上传失败,请重新上传!");
}
});
}
备注:el-updata组件要展示进度条,方便的做法是通过触发文件上传时on-progress钩子函数,拿到file已上传文件大小和总文件大小的数据,但是我发现项目里一直触发不了这个钩子函数,百度很多说是可能模拟数据引入了mock,但是项目并没有mock数据,暂时只能用请求回调中拿file信息,后面找到原因再补上。
版权声明:本文为weixin_50561602原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。