最近项目遇到个问题,就是利用swagger下载excel时,得到的文件打开总是乱码,首先怀疑是response的content-type有问题,将application试遍了,“x-msdownload”,“vnd.ms-excel”,“vnd.openxmlformats-officedocument.spreadsheetml.sheet”,“octet-stream”这些试了都不行,具体的类型对应文件参考一下链接:https://blog.csdn.net/xiaojia_boke/article/details/81140647

然后怀疑是不是写入文件后再回填response这种方式导致文件流操作有问题,因为写入本地和服务器的文件都是可以正常打开的,但是将文件写入response后就乱码了。于是将业务数据解析后的workbook直接写入response测试,结果还是乱码,排除这种猜测。

然后在网上查阅资料,发现下载excel方式都大同小异,都是解析出workbook然后写入response,差异无非就是是否通过写临时文件来缓存写入下。后来想到是不是自己代码的问题,然后从网上现扒个代码,然后在另外一个工程里直接测试,因为那个工程没有集成swagger,所以直接写了个get请求,然后通过浏览器访问,结果下载的excel可以正常打开,对比代码,实现方式没啥差异,于是把工程的下载excel功能也通过浏览器直接访问来测试,结果果然是好使的,于是果断怀疑到swagger身上。。

中间还用postman测试了下,之前没用postman测过这种下载文件的功能,这次新get到postman的2个使用技巧:

1、下载文件就在send旁边这个下拉框里,选择“send and download”,不过这里下载的文件名称都是默认的response,不是我后台代码定义的那个文件名。

2、后台下载的接口入参是@RequestBody对象的,postman在测试时在body-》raw-》选中json来填写入参,见上面的截图。

最后来说说swagger的配置修改,在注解swagger配置时,给Docket加上配置new Docket(DocumentationType.SWAGGER_2)
                .produces(Sets.newHashSet("application/octet-stream")),说明返回的是文件流即可成功下载excel。

中间也给这个Docket改过 new Docket(DocumentationType.SWAGGER_2)
                .consumes(Sets.newHashSet("application/octet-stream")),也给controller接口的@ApiOperation加过produces="application/octet-stream",后经测试发现是Docket.produces()起作用的。至于Docket的这些配置具体啥含义,需要接下来进一步研究。

最后附上后台下载的大概逻辑代码,欢迎各位提出修改意见。

1、controller的代码:

@ApiOperation(value = "下载excel接口", notes = "前端页面点击下载操作时调用接口")
    @PostMapping("/downLoadRules")
    public void downLoadRules(
            @RequestBody @ApiParam(name = "rulesToDownLoad", value = "下载excel列表", required = true) List<RuleModel> rulesToDownLoad,
            HttpServletResponse response) {

if (CollectionUtils.isEmpty(rulesToDownLoad)) {
            logger.error("待下载请求为空");
        }
        // 当前日期,用于导出文件名称
        String fileName ="Download_Rule_" + DateUtil.getDate("yyyyMMddHHmmss") + ".xlsx";
        boolean result = downLoadService.exportExcel(rulesToDownLoad, response, fileName);
    }

2、解析后的workbook写入response:

public boolean exportExcel(List<RuleModel> ruleModelList, HttpServletResponse response, String fileName){
        boolean downloadResult = false;
        response.addHeader("Content-Disposition", "attachment;filename=" + fileName);
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        XSSFWorkbook workbook = getWorkBook(ruleModelList);
        if(workbook!=null){
            try{
                //遗留问题:文件过大,可能写入效率过低,待优化
                workbook.write(response.getOutputStream());
            }
            catch(Exception e){
                logger.error("导出excel,写入workbook异常:{}", e.getLocalizedMessage());
            }finally {
                try{
                    workbook.close();
                    downloadResult = true;
                }
                catch(IOException e){
                    logger.error("导出excel,关闭workbook异常:{}", e.getLocalizedMessage());
                }
            }
        }
        return downloadResult;
    }

3、根据业务解析出workbook:

private XSSFWorkbook getWorkBook(List<RuleModel> ruleModelList) {
            //根据入参ruleModelList和模板templatePath解析出来的workbook对象
            FileInputStream excelFileInputStream = new FileInputStream(templatePath.getPath());
             XSSFWorkbook workbook = new XSSFWorkbook(excelFileInputStream);
            excelFileInputStream.close();

return workbook;
    }

后续:

前两天直接改的swagger的整体配置:

new Docket(DocumentationType.SWAGGER_2).produces(Sets.newHashSet("application/octet-stream"))

最近同事联调代码发现所有的rest请求从swagger测试请求都是流的形式,这显然是不行的,影响了别的接口功能。

后来从swagger测试,发现这里的Request Headers中Accept为“*/*”时下载的excel就不行,我在swagger配置为流"application/octet-stream"时,这里的Accept就是流的形式,然后下载的excel就是OK的。

此处怀疑swagger默认是用json还是文本或者xml给解析了,考虑是不是我能在接口层面把这个请求的Accept绑定成流的形式,然后在接口定义的@PostMapping进入源码查看有好几个属性:

感觉这个headers比较靠谱,直接给@PostMapping赋值如下:@PostMapping(value="/downLoadExcel", headers="application/octet-stream"),用swagger测试直接报错一堆js错误,还是配置不对,swagger不识别,然后在网上查阅资料,得给headers配置headers="Accept=application/octet-stream",再调试一切OK,说明这里的@PostMapping配置和swagger的配置有个对应关系,具体怎么映射,待后续研究明白了再补上~

利用swagger组件测试excel下载,打开文件乱码。相关推荐

  1. excel无法打开文件怎么解决

    excel无法打开文件怎么解决?在工作中,Excel是我们经常使用的一种办公软件,但在使用过程中难免会遇到无法打开文件的情况.这种情况一旦发生,不仅会给我们的工作带来影响,也会给我们带来一定的困扰.那 ...

  2. 通过swagger下载的文件乱码解决方法,求解

    通过swagger下载的文件乱码解决方法,求解 参考文章: (1)通过swagger下载的文件乱码解决方法,求解 (2)https://www.cnblogs.com/shuiqian/p/10568 ...

  3. 已解决Excel无法打开文件test.xIsx“,因为文件格式或文件扩展名无效。请确定文件未损坏,并且文件扩展名与文件的格式匹配。

    已解决Excel无法打开文件test.xIsx",因为文件格式或文件扩展名无效.请确定文件未损坏,并且文件扩展名与文件的格式匹配. 文章目录 报错代码 报错原因 解决方法 帮忙解决 报错代码 ...

  4. POI导出excel出现excel无法打开文件“xxx.xlsx”,因为文件格式或文件扩展名无效的问题

    POI导出excel出现excel无法打开文件"xxx.xlsx",因为文件格式或文件扩展名无效的问题 HSSFWorkbook和XSSFWorkbook混用会出现该问题 参考 h ...

  5. Excel无法打开文件新建 XLSX 工作表.xlsx,因为文件格式或文件扩展名无效。请确定文件未损坏解决办法【笔记】

    使用问题: 右键新建Microsoft Excel工作表,双击打开表格文件提示以下内容: "Excel无法打开文件新建 XLSX 工作表.xlsx,因为文件格式或文件扩展名无效.请确定文件未 ...

  6. Excel无法打开文件xxx.xlsx,因为文件格式或文件扩展名无效。请确定文件未损坏,并且文件扩展名与文件的格式匹配...

    office版本:2016  系统版本:win10 问题描述:  1.桌面新建excel表格后,打开时,提示"Excel无法打开文件xxx.xlsx,因为文件格式或文件扩展名无效.请确定文件 ...

  7. 后台导出打开Excle提示:Excel无法打开文件因为文件或文件扩展名无效

    后台导出打开Excle提示:Excel无法打开文件因为文件或文件扩展名无效 1.一定要检查SQL.特别是条件. SQL注意传值是否正确,#{}传参是否正确 查看前端响应后台导出类型和接口是否正确.我博 ...

  8. Excel无法打开文件xxx.xlsx,因为文件格式或文件扩展名无效。请确定文件未损坏,并且文件扩展名与文件的格式匹配

    office版本:2016 系统版本:win10 问题描述: 1.桌面新建excel表格后,打开时,提示"Excel无法打开文件xxx.xlsx,因为文件格式或文件扩展名无效.请确定文件未损 ...

  9. Excel表格打开文件提示内存或磁盘空间不足怎么解决

    Excel表格打开文件时,提示内存或磁盘空间不足,Microsoft Excel 无法再次打开或保存任何文档,这是很多人都会遇到的问题,该如何解决这个问题呢?如果你是用Excel表格打开某个文件时遇到 ...

最新文章

  1. 原生 AJAX的相关介绍
  2. linux中高并发socket最大连接数的优化详解
  3. JUnit 5 –设置
  4. 用Markdown写表格
  5. 百练 01 Charm Bracelet
  6. 用DELETE删除的文件怎么免费找回不用购买不用注册码
  7. SkyEye仿真ZYNQ芯片,轻松运行国产操作系统ReWorks
  8. java repaint 无效_java repaint()无效
  9. 问题六十八:着色模型(shading model)(1)——反射模型(reflection model)(1)——概述
  10. django+xadmin在线教育平台(四)
  11. 如何解决This system is not registered with RHN.
  12. Python3迅雷vip账号批量抓取导入excel中
  13. 新国标电动车怎么选?绿源INNO7了解一下吧
  14. 最新国民人均年薪出炉,你有没有拉国家的后腿?
  15. proteus仿真+keil——>制作流水灯
  16. Web安全之《SSH暴力破解》
  17. 域名解析协议-DNS
  18. CAD高版本转低版本的方法有哪些?
  19. 方便又高效,这几款远程办公软件值得学习
  20. 大数据时代 商品的数据的价值在哪

热门文章

  1. Cesium ClippingPlane剖切 改造 限高分析
  2. 说出来也许你不信,我被 Linux 终端嘲笑了…….
  3. JQ获取元素的父子兄弟级
  4. 如何制作电子印章?电脑做印章最简单的方法是什么?
  5. echars 3D地图为区域自定义颜色
  6. 线性代数(十一) : 列空间与零空间的进一步介绍
  7. 备战金9银10,精心整理:38道关于软件测试技术面试题(附带答案)
  8. 新库上线 | CnOpenData日本专利及引用被引用数据
  9. 大数据时代下,医疗行业如何实现数据安全保障?
  10. 三维点云学习(9)5-实现RANSAC Registration配准