根據後臺返回的不一樣的內容進行文件下載的方法javascript
雖說用window.open(url)也能夠很方便進行文件的下載,可是下載圖片和txt文件會變成打開另一個頁面,體驗不太友好,因此封裝瞭如下代碼,方便各類文件的下載html
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.jsvue
// 下載資源
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()
},複製代碼
注意點:a標籤下載不要傳tokenjava
env.js文件ios
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文件ajax
<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的頁面,顯示一段後臺返回的報錯信息,因此我又把它優化了一下,就是如下的樣子vuex
<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格式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;
};複製代碼
當後臺給的請求方法爲post時,就不能直接用a標籤添加地址來下載文件了,須要post請求接口,此時就須要用到另一種方法,就是把後臺返回的responseType的axios
格式文件轉化爲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文件並瀏覽器導出下載