根据后台返回的不同的内容进行文件下载的方法
1.后台返回url地址进行下载(.docx /.pptx /.txt /.png /.xls等等)
虽然说用window.open(url)也可以很方便进行文件的下载,但是下载图片和txt文件会变成打开另外一个页面,体验不太友好,所以封装了以下代码,方便各种文件的下载
course.vue
<template>
<ul class="view-course-container clear">
<li v-for="(course,courseIndex) in courseList.classArrangeFileList" :key="courseIndex">
<div>
<span :style="`background: url('static/img/${course.img}.png') center center no-repeat;`"></span>
<div>
<p @click="downloadCourse(course.url,course.name)">{{course.name}}</p>
<var>{{course.createdTime}} {{course.createUser}}上传</var>
</div>
<del @click="deleteFile(course.id)"></del>
</div>
</li>
</ul>
</template>
<script>
export default {
methods: {
downloadCourse(url,name) {
this.$common.downloadFile(url, name)
}
}
}
</script>
复制代码
common.js
// 下载资源
downloadFile (url, fileName) {
let _this = this
let xhr = new XMLHttpRequest()
xhr.open('GET', url)
xhr.responseType = 'blob'
xhr.onload = function () {
// 请求完成
let blob = this.response
console.log(blob)
// 创建隐藏的可下载链接
let eleLink = document.createElement('a')
eleLink.download = fileName
eleLink.style.display = 'none'
// eleLink.href = url
eleLink.href = URL.createObjectURL(blob);
// 触发点击
document.body.appendChild(eleLink)
eleLink.click()
// 然后移除
document.body.removeChild(eleLink)
}
xhr.ontimeout = function(e) {
//下载超时请重试
console.log(e)
// _this.$message.error('下载超时请重试')
}
xhr.onerror = function(e) {
//下载出错
console.log(e)
// _this.$message.error('下载出错,请联系管理员')
}
// 发送ajax请求
xhr.send()
},复制代码
2.后台返回的文档流前端下载Excel(get请求)
注意点:a标签下载不要传token
env.js文件
import Vue from 'vue'
let baseUrl = 'http://192.168.1.146:8002/ttfs-base-check'; // 测试环境
// 用户模块ip地址
let userUrl = 'http://192.168.1.146:8002/ttfs-user'; // 测试环境
// 分版本登录地址
Vue.prototype.$loginUrl = "http://192.168.1.146/manage";
export {
baseUrl,
userUrl
}复制代码
score.vue文件
<template>
<a :href="excelUrl" class="download-excel">下载Excel</a>
</template>
<script>
import { baseUrl, userUrl } from '@/config/env';
export default {
computed: {
// excell模板下载地址
excelUrl () {
//所需的参数
let params = {
kSchoolId: this.kSchoolId,
kSchoolYearId: this.kSchoolYearId,
kSemesterId: this.newSemester.id,
kClassesGroupId: this.classId,
}
params.scoreClassesGroupId = this.tableFirstId;
if(this.orderCodeNum != -1) {
params.orderCode = this.orderCodeNum;
}
if(this.courseRankIndex != -1) {
params.kCourseId = this.scoreCourseId;
}
//地址拼接
let url = `${baseUrl}/api/score/classes/group/export`;
url += '?'
for(const item in params){
//encodeURIComponent() 函数可把字符串作为 URI 组件进行编码
url += encodeURIComponent(item) + '=' + encodeURIComponent(params[item]) + '&';
};
return url
},
}
}
</script>复制代码
以上的方式虽然简单,但是下载不了的话报错不友好,会直接跳到一个300的页面,显示一段后台返回的报错信息,所以我又把它优化了一下,就是以下的样子
<template>
<div class="report" v.loading.fullscreen="loading" element-loading-text="拼命加载中...">
<var class="score-analysis-download" @click="downloadExcel" v-if="classInfomation.classType!=undefined&&scoreId.id!==''">下载Excel</var>
<a :href="excelUrl" style="display:none" ref="loadA">下载Excel</a>
</div>
</template>
<script>
export default {
data(){
return{
loading: true
}
},
methods: {
downloadExcel(e) {
this.loading = true;
let params = {
kSchoolId: this.kSchoolId,
kSchoolYearId: this.kSchoolYearId,
kSemesterId: this.newSemester.id,
scoreClassesGroupId: this.scoreId.id,
orderCode: 1
}
//行政班id
if(this.classInfomation.classType === 1 || this.classInfomation.classType === 6) {
params.kClassesGroupId = this.classInfomation.kClassesGroupId
}else{
params.kClassesGroupId = this.classInfomation.kClassId
}
this.$ajax.get('/api/score/classes/group/export', params).then(res => {
if(res.code == 300) {
this.loading = false;
this.excelUrl = 'javascript:;';
this.$message.error(res.msg);
}else{
let url = `${baseUrl}/api/score/classes/group/export`;
url += '?'
for(const item in params){
url += encodeURIComponent(item) + '=' + encodeURIComponent(params[item]) + '&';
};
this.excelUrl = url;
// e.target.href = url;
this.$nextTick(() => {
this.$refs.loadA.click();
this.loading = false;
})
}
});
}
}
</script>复制代码
this.$ajax为封装的axios代码,responseType默认为json格式
get(url, urlData, data = 0) {
this.isUserModel(url);
// 创建一个promise对象
// let data=JSON.stringify(datas);
// if(data==undefined){
this.promise = new Promise((resolve, reject) => {
if (data == 0) {
url += '?';
for (const item in urlData) {
// url += '/' + urlData[item];
// url += '?' +item+'=' +urlData[item];
url += item + '=' + urlData[item] + '&';
};
} else if (data == 1) {
for (const item in urlData) {
url += '/' + urlData[item];
// url += '?' +item+'=' +urlData[item];
};
}
axios.get(url).then((res) => {
// debugger
if (this._isStatus(res.data)) {
resolve(res.data);
this.countlyMonitorResponse(url);
}
}).catch((err) => {
// console.log(err);
// Message.error(err);
})
})
return this.promise;
};复制代码
3.后台返回的文档流前端下载Excel(post请求)
当后台给的请求方法为post时,就不能直接用a标签添加地址来下载文件了,需要post请求接口,此时就需要用到另外一种方法,就是把后台返回的responseType的
格式文件转化为arraybuffer二进制流文件,然后动态创建一个a标签来下载
<template>
<div class="score">
<span class="download-excel">下载Excel</span>
</div>
</template>
<script>
import {mapState,mapMutations} from 'vuex'
export default {
name: 'scorePage',
data(){
return {
kSchoolId: this.$common.getSession("userData").school.id,
kSchoolYearId: this.$common.getSession("userData").schoolYear.id,classId: '123',
}
},
computed:{
...mapState('semester',['newSemester']),
},
methods: {
// 下载excel表格
downloadExcel() {
let params = {
kSchoolId: this.kSchoolId,
kSchoolYearId: this.kSchoolYearId,
kSemesterId: this.newSemester.id,
kClassesGroupId: this.classId,
}
params.scoreClassesGroupId = this.tableFirstId;
if(this.orderCodeNum != -1) {
params.orderCode = this.orderCodeNum;
}
if(this.courseRankIndex != -1) {
params.kCourseId = this.scoreCourseId;
}
let url = `${baseUrl}/api/score/classes/group/export`;
url += '?'
for(const item in params){
url += encodeURIComponent(item) + '=' + encodeURIComponent(params[item]) + '&';
};
// responseType: "arraybuffer"将后台返回的默认json改为二进制
axios.post(url,{responseType: "arraybuffer"}).then(res=>{
let result = res.data;
let url = window.URL.createObjectURL(new Blob([result]));//处理文档流
// let fileTye = url.match(/.+\/(.+)$/)[1];
let link = document.createElement('a');
link.style.display = 'none';
link.href = url;
// link.download = fileTye;
link.download = '成绩汇总表.xls';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
})
}
}
}
</script>复制代码
此方法并不局限于post请求,get请求也一样可以
最后,分享篇关于导入二进制流文件的文章
zhuanlan.zhihu.com/p/51941539?…
JS前端创建html或json文件并浏览器导出下载
www.zhangxinxu.com/wordpress/2…