一次解决Easypoi导出Excel文件打开乱码问题的过程

一次解决Easypoi导出Excel文件打开乱码问题的过程

前言

项目中使用Easypoi来导出Excel,上线后是正常的,过了段时间,测试反馈导出的Excel文件打开乱码,打开Excel文件时提示“文件格式和扩展名不匹配…文件可能已损坏或不安全”。

导出Excel过程:

  1. 前端发起一个POST请求;

  2. 后端响应请求,在导出Excel文件时,在HTTP头部设置Content-Typeapplication/vnd.ms-excel,并且设置字符集为UTF-8, 并通过设置Content-Dispositionattachment;filename=...来让浏览器下载附件。

后端代码示例:

Workbook workbook = ExcelExportUtil.exportExcel(exportParams, pojoClass, list);

response.setCharacterEncoding("UTF-8");
response.setContentType("application/vnd.ms-excel; charset=utf-8");
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));

workbook.write(response.getOutputStream());

解决问题过程

排查最近的变更

最近做了什么代码变更?

  1. 排查了后端代码,没有改动过导出部分的代码;
  2. 前端也反馈,没有改动过导出部分的代码。

最近做了什么配置变更?

团队反馈最近没有做过什么“可疑”的变更。

定位问题

前端问题还是后端问题?

因为通过Postman的Send and download测试,导出的Excel也有同样的问题。

因此可以排除是前端问题。

Maven依赖冲突问题?

团队反馈最近在parent项目中的pom.xml有引入xxl-tools,而xxl-tools也有Excel导出功能,会不会和Easypoi的导出功能有冲突?

但是这个项目中并没有xxl-tools依赖,用IDEA查看Maven依赖图也证实了这一点。

并且parent项目中是以dependencyManagement来引入xxl-tools,也就是只有子项目明确引入了xxl-tools,才会有xxl-tools依赖。

因此可以排除是Maven依赖冲突问题。

Linux环境问题?

运行echo $LANGlocale命令比较了几台测试服务器的Linux环境配置,没有发现异常。

在项目中编写测试代码,导出文件时直接生成Excel文件并保存在服务器上,再手工从服务器上下载Excel文件到本地打开,没有问题。

因此可以排除是Linux环境问题。

Easypoi问题?

项目中引入的Easypoi已经指定了特定版本,并且之前导出是正常的,Easypoi的嫌疑不大。

稳妥起见,改成用原始的Apache Poi来导出,一样有问题。

因此可以排除是Easypoi库的问题。

网关问题?

前端发起请求时,会先通过网关,再由网关转发到后端来处理,所以网关也有嫌疑。

测试不经过网关,直接调用项目的导出Excel接口,果然没有问题。

网关是我们基于Spring Cloud Gateway定制的,里面定义了几个拦截器(filter)来对HTTP request和HTTP response做了日志记录、格式转换和异常处理等。

查看网关代码,最近并没有可疑的改动。

但是看到一个记录日志的拦截器代码中在某些情况时会对HTTP response重写,重点怀疑。

通过开关,关闭该拦截器后,测试正常。

终于抓到真凶了。

虽然该拦截器代码最近并没有改动过,但是之前环境上该拦截器没有开启,所以导出是正常的,后来不知道什么时候开启了这个拦截器,就影响到导出功能了。

解决问题

修改有问题的拦截器,根据接口URL来判断,对导出文件时直接跳过该拦截器。

测试通过。

小结

本文通过一次排查导出Excel文件问题的过程,描述了在导出文件过程的前端、网关和后端服务(接口、库、服务器)的各个阶段都可能存在的故障点,提供了排查类似问题的参考。

参考文档

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章