当前位置:   article > 正文

關於使用EasyExcle,進行數據導出后,文件無法打開,提示文件已損壞等一系列問題排查記錄_easyexcel导出文件损坏

easyexcel导出文件损坏

1. 排除掉編碼方面的問題,排查的重點是各個數據查詢語句是否有數據的存在,也就是說,查詢語句對應的數據庫表,是否有數據的存在,數據是否正常返回給到你的後端對象?如果!你需要輸出到excle文件中的數據,在數據庫表中並不存在,或者説你根本查不到數據,那麽如果你的代碼中存在對數據是否爲空的判斷的時候,你需要查看

excelWriter.write()方法是否沒有被調用,也就是它沒有往表中寫入數據。

2. 注意!一般情況下,沒有查到數據,不調用excelWriter.write()方法進行寫入似乎是合理的邏輯,但是可能是EasyExcle本身的bug,在不寫入數據的時候EXCLE文件默認你的文件是不完整從而導致失敗。

3. 解決的方法可以使用模板範文,填入固定提示文字數據,如(代碼僅供參考,需要結合自己代碼進行相應實現)

if (CollectionUtils.isNotEmpty(students)) {
        // 查詢數據不爲空,執行方法體(具體自己代碼實現)
    }
} else {
    // 查詢數據爲空,進行模板數據填入,避免文件損壞,無法打開
    List<List<Object>> rows = new ArrayList<>();
    List<Object> row = new ArrayList<>();
    for (int i = 0; i < heads.size(); i++) {
        row.add("暫無數據");
    }
    rows.add(row);
    excelWriter.write(rows, writeSheet);
}

代碼不唯一,最重要是能結合業務場景解決問題即可

--------------------------------------------------  分界綫   ------------------------------------------------------------------

2024.4.22 文檔補充:

提取了公用的代碼,編輯了一個比較通用的工具類,代碼如下(僅供參考哦):

  1. import com.alibaba.excel.EasyExcel;
  2. import com.alibaba.excel.ExcelWriter;
  3. import com.alibaba.excel.write.metadata.WriteSheet;
  4. import java.io.OutputStream;
  5. import java.util.ArrayList;
  6. import java.util.Arrays;
  7. import java.util.List;
  8. /**
  9. * EasyExcel自定義工具類
  10. */
  11. public class EasyExcelUtils {
  12. /**
  13. * 创建一个Excel文件并写入数据。
  14. *
  15. * @param outputStream 输出流,通常从HttpServletResponse获取
  16. * @param sheetName 工作表名称
  17. * @param headTitle 头部标题
  18. * @param noDataMessage 无数据时显示的消息
  19. */
  20. public static void writeExcelWithNoData(OutputStream outputStream, String headTitle, String sheetName, String noDataMessage) {
  21. // 创建ExcelWriter
  22. // ExcelWriterBuilder writerBuilder = EasyExcel.write(outputStream); 最好不要用ExcelWriterBuilder,因爲發現用了這個導出來的文件也是破損的,不知道是不是easyexcle的每個版本都不同的原因,具體不得而知,博主用的是2.2.6
  23. // 至於outputStream,其實write還有一個入參是String pathName,傳的是路徑名,那麽使用输出流的方法其實则更加灵活,適合在於生成Excel并直接作为HTTP响应返回给客户端的時候使用,具體結合自己實際去更改
  24. ExcelWriter excelWriter = EasyExcel.write(outputStream).build();
  25. // 构建头部信息(應該會有人好奇爲什麽要List<List<String>> head 這樣定義這個List集合,其實看一下下面的head方法的源碼就知道了,源碼提供的head方法重載之後提供了兩個入參的方法,一個入參是List<List<String>> ,另一個是Class,
  26. // 當然我們也可以新建一個實體類來進行構建它的表頭信息,這也是最常用的方法,
  27. // 這裏單純是不想創建多一個實體類才用的List<List<String>> 這樣的形式)
  28. List<List<String>> head = new ArrayList<>();
  29. head.add(Arrays.asList(headTitle));
  30. // 构建工作表
  31. WriteSheet writeSheet = EasyExcel.writerSheet(sheetName).head(head).build();
  32. // 创建无数据时的行信息(統一的用於解釋原因的模板信息)
  33. List<List<Object>> rows = new ArrayList<>();
  34. List<Object> row = new ArrayList<>();
  35. row.add(noDataMessage);
  36. // 實際上rows就是一個二維列表,主要也是用來對應上述表頭格式的,否則數據填充的位置就對不准表頭了,所以不用把這裏想的太複雜,沒什麽太深奧的意義
  37. rows.add(row);
  38. // 写入数据到Excel
  39. excelWriter.write(rows, writeSheet);
  40. // 关闭writer,释放内存
  41. excelWriter.finish();
  42. }
  43. }

注意事項,代碼注釋中也有提及,但還是單獨拿出來講講:

1.  List<List<String>> head 爲什麽要這樣子定義這個List集合

答:在下圖中,head方法是有兩個不同的入參形式,其實我們這個形式就相當於在動態構建參數,而沒有借助對象來入參,所以,看下源碼就知道爲什麽要這樣定義這個集合了

2.  List<List<Object>> rows = new ArrayList<>();   List<Object> row = new ArrayList<>();  的定義

答:實際上就是在構建一個二維的列表,主要是用來對應上述表頭格式的位置的,不這麽寫數據填充的位置就對不准表頭了,所以不用把這裏想的太複雜,沒什麽太深奧的意義

3.  入參爲什麽會有一個 OutputStream outputStream?

答:同樣也可以從源碼來理解,write方法同樣也提供了兩個重載形式,實際上也可以使用

String pathName這種入參形式,但outputStream 這種使用输出流的方法其實则更加灵活,適合在於生成Excel并直接作为HTTP响应返回给客户端的時候使用,但是具體還是結合自己實際情況去更改即可

4.   outputStream 的值從哪裏獲取?

答: 實際上你在MVC的層面可以接收一個參數叫:HttpServletResponse response

outputStream 實際上就是等同於 response.getOutputStream()

寫到最後,一起看下調用的截圖和效果圖:

工具類的方法實際上就等同於注釋掉的代碼,效果是一樣的

  1. // ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).build();
  2. // List<List<String>> head = new ArrayList<>();
  3. // head.add(Arrays.asList("檢索結果"));
  4. // WriteSheet writeSheet = EasyExcel.writerSheet("學校數據").head(head).build();
  5. // List<List<Object>> rows = new ArrayList<>();
  6. // List<Object> row = new ArrayList<>();
  7. // row.add("在當前查詢條件下,暫無對應檢索數據");
  8. // rows.add(row);
  9. // excelWriter.write(rows,writeSheet);
  10. // excelWriter.finish();
  11. EasyExcelUtils.writeExcelWithNoData(response.getOutputStream(),"檢索結果","學校數據","在當前查詢條件下,暫無對應檢索數據");

下方是excle文件的效果圖,對代碼沒有太大概念的同學可以結合excle的效果來慢慢理解代碼:

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/代码探险家/article/detail/998886
推荐阅读
  

闽ICP备14008679号