文章目錄
一次解決Easypoi導出Excel文件打開亂碼問題的過程
前言
項目中使用Easypoi來導出Excel,上線後是正常的,過了段時間,測試反饋導出的Excel文件打開亂碼,打開Excel文件時提示“文件格式和擴展名不匹配…文件可能已損壞或不安全”。
導出Excel過程:
-
前端發起一個
POST
請求; -
後端響應請求,在導出Excel文件時,在HTTP頭部設置
Content-Type
爲application/vnd.ms-excel
,並且設置字符集爲UTF-8
, 並通過設置Content-Disposition
爲attachment;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());
解決問題過程
排查最近的變更
最近做了什麼代碼變更?
- 排查了後端代碼,沒有改動過導出部分的代碼;
- 前端也反饋,沒有改動過導出部分的代碼。
最近做了什麼配置變更?
團隊反饋最近沒有做過什麼“可疑”的變更。
定位問題
前端問題還是後端問題?
因爲通過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 $LANG
和locale
命令比較了幾臺測試服務器的Linux環境配置,沒有發現異常。
在項目中編寫測試代碼,導出文件時直接生成Excel文件並保存在服務器上,再手工從服務器上下載Excel文件到本地打開,沒有問題。
因此可以排除是Linux環境問題。
Easypoi問題?
項目中引入的Easypoi已經指定了特定版本,並且之前導出是正常的,Easypoi的嫌疑不大。
穩妥起見,改成用原始的Apache Poi來導出,一樣有問題。
因此可以排除是Easypoi庫的問題。
網關問題?
前端發起請求時,會先通過網關,再由網關轉發到後端來處理,所以網關也有嫌疑。
測試不經過網關,直接調用項目的導出Excel接口,果然沒有問題。
網關是我們基於Spring Cloud Gateway定製的,裏面定義了幾個攔截器(filter)來對HTTP request和HTTP response做了日誌記錄、格式轉換和異常處理等。
查看網關代碼,最近並沒有可疑的改動。
但是看到一個記錄日誌的攔截器代碼中在某些情況時會對HTTP response重寫,重點懷疑。
通過開關,關閉該攔截器後,測試正常。
終於抓到真兇了。
雖然該攔截器代碼最近並沒有改動過,但是之前環境上該攔截器沒有開啓,所以導出是正常的,後來不知道什麼時候開啓了這個攔截器,就影響到導出功能了。
解決問題
修改有問題的攔截器,根據接口URL來判斷,對導出文件時直接跳過該攔截器。
測試通過。
小結
本文通過一次排查導出Excel文件問題的過程,描述了在導出文件過程的前端、網關和後端服務(接口、庫、服務器)的各個階段都可能存在的故障點,提供了排查類似問題的參考。