要做一个导出报告的功能。
前台传参带数据,后台接收处理,把选择的文件打成zip压缩包,再下载到本地。
后台处理到是很好完成。关键在返回数据 和前台接收的时候有点小坑。不太熟悉。记录一下前端和后台的模板。
一、前端
1.vue界面调用导出按钮的方法:
import { exportReport } from "@/api/***/***";
export default {
/*********/
methods: {
exportProjectReport() {
/*********/
let params = {传参};
exportReport(params);
/*********/
}
}
/*********/
}
2.调用api接口的JS文件:
import { getToken } from '@/utils/auth'
import axios from 'axios'
// 导出项目报告
export function exportReport(data) {
let baseUrl = process.env.VUE_APP_BASE_API
axios({
method: 'post',
//后台接口,记得拼接前缀
url: baseUrl + '/***/***',
data: data,
responseType: 'blob',
//看自己项目是否后台带token验证
headers: { 'Authorization': 'Bearer ' + getToken() }
}).then(res => {
//取blob
let blob = new Blob([res.data])
//生成一个url
let objectUrl = URL.createObjectURL(blob);
//此处做了一个当前日期 可不需要
let nowDate = new Date();
let date = {
year: nowDate.getFullYear(),
month: nowDate.getMonth() + 1,
date: nowDate.getDate(),
}
//这种写法挺简单 判断日期是否补零
date.date = date.date < 10 ? 0 + date.date.toString() : date.date
let systemDate = date.year + '-' + 0 + date.month + '-' + date.date;
//开始下载
downloadFile(objectUrl, data.projectName + '_' + systemDate + '.zip')
})
}
//下载
export function downloadFile(content, filename) {
let a = document.createElement('a')
a.href = content
a.download = filename
a.click()
}
二、后端
1.Controller层
参数用Map来接,注意用Post请求,才能用@RequestBody注解。
HttpServletRequest request并没用到,可去。
/**
* 导出报告
*/
@PostMapping("/exportReport")
public void exportReport(@RequestBody Map map, HttpServletRequest request, HttpServletResponse response) throws FileNotFoundException{
try {
projectService.exportReport(map, request, response);
} catch (IOException e) {
e.printStackTrace();
}
}
2.Service impl层
/**
* 导出报告
* @param map
* @param request
* @param response
* @throws IOException
*/
@Override
public void exportReport(Map map, HttpServletRequest request, HttpServletResponse response) throws IOException{
//拿到map里的数据,此项省去
//处理数据 得到压缩文件
//path就是已经压缩好的zip文件路径
//文件下载
File file = new File(path +"\\"+ 文件名字+ ".zip");
//下面可套用传输下载
response.setContentType("multipart/form-data");
response.setHeader("Content-Disposition", "attachment; filename= file");
InputStream in = null;
OutputStream os = response.getOutputStream();
try {
// 一次读一个字节
in = new FileInputStream(file);
int tempbyte;
while ((tempbyte = in.read()) != -1) {
os.write(tempbyte);
}
} finally {
os.flush();
os.close();
in.close();
}
}
前端js文件不太熟悉,不单单可以写API接口,一样可以写方法处理。
关键是 axios 请求要加上下面声明是blob文件
responseType: 'blob',
返回数据的取blob处理
let blob = new Blob([res.data])
//生成一个url
let objectUrl = URL.createObjectURL(blob);
downloadFile(objectUrl,fileName)
下载界面的方法处理
export function downloadFile(content, filename) {
let a = document.createElement('a')
a.href = content
a.download = filename
a.click()
}
从vue界面到调用API接口方法 ,和js文件处理,后台接收参数,到处理,再到下载 。
整体模板就是这个样子,下载有传参需求可以套用。