赞
踩
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 文檔補充:
提取了公用的代碼,編輯了一個比較通用的工具類,代碼如下(僅供參考哦):
- import com.alibaba.excel.EasyExcel;
- import com.alibaba.excel.ExcelWriter;
- import com.alibaba.excel.write.metadata.WriteSheet;
-
- import java.io.OutputStream;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.List;
-
- /**
- * EasyExcel自定義工具類
- */
- public class EasyExcelUtils {
-
- /**
- * 创建一个Excel文件并写入数据。
- *
- * @param outputStream 输出流,通常从HttpServletResponse获取
- * @param sheetName 工作表名称
- * @param headTitle 头部标题
- * @param noDataMessage 无数据时显示的消息
- */
- public static void writeExcelWithNoData(OutputStream outputStream, String headTitle, String sheetName, String noDataMessage) {
- // 创建ExcelWriter
- // ExcelWriterBuilder writerBuilder = EasyExcel.write(outputStream); 最好不要用ExcelWriterBuilder,因爲發現用了這個導出來的文件也是破損的,不知道是不是easyexcle的每個版本都不同的原因,具體不得而知,博主用的是2.2.6
- // 至於outputStream,其實write還有一個入參是String pathName,傳的是路徑名,那麽使用输出流的方法其實则更加灵活,適合在於生成Excel并直接作为HTTP响应返回给客户端的時候使用,具體結合自己實際去更改
- ExcelWriter excelWriter = EasyExcel.write(outputStream).build();
-
- // 构建头部信息(應該會有人好奇爲什麽要List<List<String>> head 這樣定義這個List集合,其實看一下下面的head方法的源碼就知道了,源碼提供的head方法重載之後提供了兩個入參的方法,一個入參是List<List<String>> ,另一個是Class,
- // 當然我們也可以新建一個實體類來進行構建它的表頭信息,這也是最常用的方法,
- // 這裏單純是不想創建多一個實體類才用的List<List<String>> 這樣的形式)
- List<List<String>> head = new ArrayList<>();
- head.add(Arrays.asList(headTitle));
-
- // 构建工作表
- WriteSheet writeSheet = EasyExcel.writerSheet(sheetName).head(head).build();
-
- // 创建无数据时的行信息(統一的用於解釋原因的模板信息)
- List<List<Object>> rows = new ArrayList<>();
- List<Object> row = new ArrayList<>();
- row.add(noDataMessage);
- // 實際上rows就是一個二維列表,主要也是用來對應上述表頭格式的,否則數據填充的位置就對不准表頭了,所以不用把這裏想的太複雜,沒什麽太深奧的意義
- rows.add(row);
-
- // 写入数据到Excel
- excelWriter.write(rows, writeSheet);
-
- // 关闭writer,释放内存
- excelWriter.finish();
- }
- }
注意事項,代碼注釋中也有提及,但還是單獨拿出來講講:
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()
寫到最後,一起看下調用的截圖和效果圖:
工具類的方法實際上就等同於注釋掉的代碼,效果是一樣的
- // ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).build();
- // List<List<String>> head = new ArrayList<>();
- // head.add(Arrays.asList("檢索結果"));
- // WriteSheet writeSheet = EasyExcel.writerSheet("學校數據").head(head).build();
- // List<List<Object>> rows = new ArrayList<>();
- // List<Object> row = new ArrayList<>();
- // row.add("在當前查詢條件下,暫無對應檢索數據");
- // rows.add(row);
- // excelWriter.write(rows,writeSheet);
- // excelWriter.finish();
-
- EasyExcelUtils.writeExcelWithNoData(response.getOutputStream(),"檢索結果","學校數據","在當前查詢條件下,暫無對應檢索數據");
下方是excle文件的效果圖,對代碼沒有太大概念的同學可以結合excle的效果來慢慢理解代碼:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。