栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【经验篇】记SpringBoot+Swagger下载Excel文件打开错误的问题

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【经验篇】记SpringBoot+Swagger下载Excel文件打开错误的问题

背景描述

需求描述: 实现一个报表查询功能,可以根据查询条件导出Excel文件。
技术栈: SpringBoot 2.1.3 + Swagger 2.7.2 + poi 4.0.1

代码示例
public void exportExcel(UserQuery query, HttpServletResponse response) {
	// 1. 查询数据
	List userStageList = sevice.getUserStageList(query);
	// 2. 生成Excel
	Workbook workbook = ExcelExportUtils.exportExcel(userStageList);
	// 3. 设置response参数,可以打开下载页面
	ServletOutputStream out = null;
	try {
		String fileName = "用户阶段详情.xlsx";
		String encodeFileName = new String(StrUtil.bytes("用户阶段详情.xlsx", CharsetUtil.CHARSET_GBK), CharsetUtil.CHARSET_ISO_8859_1);
        response.setHeader("Content-Disposition", "attachment; filename=" + encodeFileName);
        response.setHeader("filename", URLEncoder.encode(fileName, CharsetUtil.UTF_8));
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/vnd.ms-excel");
        
		out = response.getOutputStream();
        workbook .write(out);
        out.flush();
	} catch (Exception e) {
		// 打印日志,抛出异常
	} finally {
		// 关闭IO
	}
问题描述

接口写完之后,通过swagger和postman进行测试发现文件无法正常打开。
// 图一:下载
// 图二:打开文件
// 图三:点击“是”

问题定位:

  1. 起初以为是Jar包版本冲突,在分析之后,排除这种可能。
  2. 怀疑是内置Tomcat依赖版本问题,在更新版本以及替换成servlet-api之后,问题依然存在
  3. 找到《java通过poi生成excel并下载出现文件打不开、文件格式和文件扩展名无效问题的分析与解决》文章,可能是Swagger问题,于是使用其他方式,导出成功。
解决方案 [GET]方式一,无需修改代码

直接在浏览器中直接输入url的方式,就得到了正常的可打开且格式正确的excel
// 图4

[GET]方式二,无需修改代码

使用F12,打开浏览器console方式,执行以下指令:

//触发方法下载后
var url = 'http://localhost:8088/api/download-file?userId=' + {id};
fetch(url,{
	method: 'GET',
	mode: 'cors',	// no-cors, cors, *same-origin
	headers: new Headers({
		'Content-Type': 'application/json',
		// 'Authorization': `Bearer ${token}`
	})
}
).then(res => res.blob().then(blob => {
	var a = document.createElement('a');
	var url = window.URL.createObjectURL(blob);
	var filename = res.headers.get('content-disposition').split(';')[1].split('=')[1]
	a.href = url;
	a.download = filename;
	a.click();
	window.URL.revokeObjectURL(url);
}))
[POST]方式,无需修改代码

使用F12,打开浏览器console方式,执行以下指令:

//触发方法下载后
var url = 'http://localhost:8088/api/download-file';
fetch(url,{
	method: 'POST',
	mode: 'cors',	// no-cors, cors, *same-origin
	body: window.JSON.stringify(params),
	headers: new Headers({
		'Content-Type': 'application/json',
		// 'Authorization': `Bearer ${token}`
	})
}
).then(res => res.blob().then(blob => {
	var a = document.createElement('a');
	var url = window.URL.createObjectURL(blob);
	var filename = res.headers.get('content-disposition').split(';')[1].split('=')[1]
	a.href = url;
	a.download = filename;
	a.click();
	window.URL.revokeObjectURL(url);
}))
修改代码,使用Swagger测试

在api代码上增加以下注释:

@ApiOperation(value = "导出用户阶段详情", notes = "export", produces = "application/octet-stream")

@RequestMapping 里面也有produces 和consumes
produces ==> 指定返回值类型,不但可以设置返回值类型还可以设定返回值的字符编码
consumes ==> 指定处理请求的提交内容类型(Content-Type),例如application/json, text/html;

加了上面得到注解后,对于那种查询一些数据,然后导出到excel 进行下载是可以正常打开的。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/340292.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号