vue请求后端接口导出excel
项目中遇到一个需求,用户下载文件,会从后端那里请求接口获得数据并下载导出excel表格
后端小哥给我返回的是二进制数据流,需要前端自己去处理这些数据
如下图,请求接口返回的数据都是乱码
这里我们可以在axios的请求里添加,这样返回的二进制数据就会被读取为Blob的数据,
responseType: ‘blob’
fetchGet1(url, params) {
return axios({
url,
method: 'get',
params,
header: {
headers: { 'Content-Type': 'application/x-download' }
},
responseType: 'blob' //指明返回格式
})
}
//下载接口
export var downLoadOrder = (orderId) => ajax.fetchGet1(`/api/order/excel/${orderId}`)
当我点击下载订单的按钮后,浏览器就自动弹出下载excel文件一栏了,要注意的是,我的电脑好像没有xlsx格式的文件,所以在定义文件名那里改成了xls的格式
调用后端接口导出excel无效果,直接访问后端url可以
controller层代码
@ApiOperation(value="导出模板")
@RequestMapping(value="/getTemplate" , method= RequestMethod.GET)
@ResponseBody
public void getTemplate(HttpServletRequest req,HttpServletResponse res) throws IOException {
standingBookService.getTemplate(req, res);
}
serviceImpl代码
public void getTemplate(HttpServletRequest req, HttpServletResponse res) throws IOException {
String templateName = "standingBookTemplate";
String exportName = "template";
ExcelUtil.downloadExcelTemplate(req, res, templateName, exportName);
}
导出模板路径
工具箱代码
public static void downloadExcelTemplate(HttpServletRequest req,HttpServletResponse res,String templateName,
String exportName) throws IOException{
String fullFileName = req.getServletContext().getRealPath("/doc/import/excelTemplate");
fullFileName += (File.separator + templateName + ".xls");
String export = "";
if(DataValidUtil.isEmpty(exportName)){
export = templateName;
}else{
export = exportName;
}
String userAgent = req.getHeader("USER-AGENT");
//文件下载乱码问题
if (StringUtils.contains(userAgent.toUpperCase(),"MSIE")||StringUtils.contains(userAgent,"Trident")) {
export = URLEncoder.encode(export, "UTF-8");
} else {
export = new String(export.getBytes("UTF-8"), "ISO8859-1");
}
//设置Content-Disposition
res.setHeader("Content-disposition","attachment; filename="+export+".xls");
//设置文件MIME类型
//res.setContentType("application/vnd.ms-excel");
//前端框架自定义类型
res.setContentType("application/export.file");
OutputStream out = res.getOutputStream();
FileInputStream in = new FileInputStream(fullFileName);
res.setCharacterEncoding("UTF-8");
byte[] b = new byte[1024];
int n = -1;
while((n=in.read(b))!=-1){
out.write(b, 0, n);
}
in.close();
out.close();
}
vue前端写法
//模板下载
getTemplate(){
const that = this;
window.location='/test/test/getTemplate';//正确写法,直接访问你的请求路径
//这种写法会导致后台不报错,但是前端无导出效果
},
以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。