vue-下载后端返回的文件流(post),上传,请求前置过滤器,响应数据拦截并做通用处理
vue-下载后端返回的文件流(post)
vue
<script>
import axios from 'axios'
import {MessageBox, Message} from 'element-ui'
import {Loading} from 'element-ui'
const http = axios.create({
// baseURL: process.env.VUE_APP_BASE_API,
baseURL: process.env.VUE_APP_BASE_API,
timeout: 60000,
withCredentials: true
})
export default {
methods:{
/**
* 下载 url:后台地址 data:需要导出的数据 fileName:文件名
* @param url
* @param data
*/
download(url, data, fileName) {
return new Promise((resolve, reject) => {
// 打开
const loading = Loading.service({
text: '正在下载数据...',
background: 'rgba(0, 0, 0, 0.7)'
})
http.request({
url: url,
method: 'post',
data: data,
timeout: 1200000,
responseType: 'arraybuffer'
})
.then(res => {
loading.close()
// 文件下载
const blob = new Blob([res.data], {
type: 'application'
})
// 获得文件名称
let link = document.createElement('a')
link.download = fileName
link.style.display = 'none'
link.href = URL.createObjectURL(blob)
document.body.appendChild(link)
link.setAttribute('download', fileName + '.xls')
link.click()
URL.revokeObjectURL(link.href);
document.body.removeChild(link);
link = null
Message.success('导出成功!')
})
.catch(err => {
loading.close()
reject(err)
})
})
},
}
}
</script>
django
def export(self, request):
...... 获取数据根据实际情况获取
# 假设数据是这样的
ret = [[1, 'tom', 2], [2, 'jerry', 1]]
import pandas as pd
df = pd.DataFrame(ret, columns=['id', 'name', 'age'])
# 利用pandas将数据存入excel文件中
from io import BytesIO
bio = BytesIO()
writer = pd.ExcelWriter(bio, engine='xlsxwriter') # 注意安装这个包 pip install xlsxwriter
df.to_excel(writer, sheet_name='Sheet1')
writer.save()
bio.seek(0)
# bio.read() 不要read出来,否则seek就到文件最后了,导致下载的是空文件
# 至此,数据已写入bio中
from django.http import FileResponse
response = FileResponse(bio)
response['Content-Type'] = 'application/octet-stream'
response['Content-Disposition'] = 'attachment;filename="mm.xlsx"'
return response
上传文件
vue
<script>
import axios from 'axios'
import {MessageBox, Message} from 'element-ui'
import {Loading} from 'element-ui'
const http = axios.create({
// baseURL: process.env.VUE_APP_BASE_API,
baseURL: process.env.VUE_APP_BASE_API,
timeout: 60000,
withCredentials: true
})
methods:{
/**
* 上传
* @param url
* @param data
*/
upload (url, file, data) {
const formData = new FormData()
formData.append('file', file)
// 附加数据
if (data) {
Object.keys(data).forEach(key => {
formData.append(key, data[key])
})
}
return new Promise((resolve, reject) => {
// 打开
const loading = Loading.service({
text: '正在上传数据...',
background: 'rgba(0, 0, 0, 0.7)'
})
http
.request({
url: url,
method: 'post',
data: formData,
timeout: 1200000
})
.then(response => {
console.log(response)
loading.close()
resolve(response)
})
.catch(err => {
loading.close()
reject(err)
})
})
}
}
</script>
汇总
import axios from 'axios'
import { MessageBox, Message } from 'element-ui'
import { Loading } from 'element-ui'
import store from '@/store'
import { getToken } from '@/utils/auth'
// 请求实例
const http = axios.create({
// baseURL: process.env.VUE_APP_BASE_API,
baseURL: process.env.VUE_APP_BASE_API,
timeout: 60000,
withCredentials: true
})
// 请求前置过滤器
http.interceptors.request.use(
config => {
if (store.getters.token) {
config.headers['token'] = getToken()
}
return config
},
error => {
console.log(error)
return Promise.reject(error)
}
)
// 响应数据拦截并做通用处理
http.interceptors.response.use(
response => {
const res = response.data
// 下载文件直接返回
if (res.type === 'application/octet-stream') {
return response
}
if (res.type === 'application/vnd.ms-excel') {
return response
}
// 0为正确响应码
// if (res.code !== 0 ) {
// Message({
// message: res.msg || 'Error',
// type: 'error',
// duration: 5 * 1000
// })
//
// // 登录超时响应码
if (res.code != 200 && res.message == '暂未登录或token已经过期') {
// to re-login
MessageBox.confirm('登录超时,请重新登录!', '登录提示', {
confirmButtonText: '重新登录',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
store.dispatch('user/resetToken').then(() => {
location.reload()
})
})
} else {
return res
}
},
error => {
console.log('err' + error)
Message({
message: error.message,
type: 'error',
duration: 5 * 1000
})
return Promise.reject(error)
}
)
/**
* 上传
* @param url
* @param data
*/
export function upload (url, file, data) {
const formData = new FormData()
formData.append('file', file)
// 附加数据
if (data) {
Object.keys(data).forEach(key => {
formData.append(key, data[key])
})
}
return new Promise((resolve, reject) => {
// 打开
const loading = Loading.service({
text: '正在上传数据...',
background: 'rgba(0, 0, 0, 0.7)'
})
http
.request({
url: url,
method: 'post',
data: formData,
timeout: 1200000
})
.then(response => {
console.log(response)
loading.close()
resolve(response)
})
.catch(err => {
loading.close()
reject(err)
})
})
}
/**
* 下载
* @param url
* @param data
*/
export function download (url, data, fileName) {
return new Promise((resolve, reject) => {
// 打开
const loading = Loading.service({
text: '正在下载数据...',
background: 'rgba(0, 0, 0, 0.7)'
})
http
.request({
url: url,
method: 'post',
data: data,
timeout: 1200000,
responseType: 'arraybuffer'
})
.then(res => {
loading.close()
// 文件下载
const blob = new Blob([res], {
type: 'application'
})
// 获得文件名称
let link = document.createElement('a')
link.href = URL.createObjectURL(blob)
link.setAttribute('download', fileName)
link.click()
link = null
Message.success('导出成功!')
})
.catch(err => {
loading.close()
reject(err)
})
})
}
/**
* 封装post请求
* @param url
* @param data
* @returns {Promise}
*/
export function post (url, data = {}) {
return new Promise((resolve, reject) => {
http.post(url, data).then(
response => {
resolve(response)
},
err => {
reject(err)
}
)
})
}
export default http
本文作者:春游去动物园
本文链接:https://www.cnblogs.com/chunyouqudongwuyuan/p/16788043.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步