EasyExcel-最簡單的讀寫excel工具類

前言:
easyExcel 的官網文檔給的示例非常全,可以參考https://easyexcel.opensource.alibaba.com/docs/current/quickstart/read
在此我貼出自己的工具類,可以直接用

導包

		<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.1.0</version></dependency>

讀excel

1:最簡單讀-使用demo對象

創建對象bean

package com.wkl.testdemo.excel;import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;/*** @author wangkanglu* @version 1.0* @description* @date 2023-12-08 17:28*/
@Data
public class DemoBean {/*** 用名字去匹配,這里需要注意,如果名字重復,會導致只有一個字段讀取到數據*/@ExcelProperty("姓名")private String name;/*** 強制讀取第二個 這里不建議 index 和 name 同時用,要么一個對象只用index,要么一個對象只用name去匹配*/@ExcelProperty(index = 1)private String sex;
}

創建讀取器

package com.wkl.testdemo.excel;import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.exception.ExcelDataConvertException;
import com.alibaba.excel.util.ListUtils;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;import java.util.List;/*** @author wangkanglu* @version 1.0* @description* @date 2023-12-08 17:27*/
@Data
public class DemoListener extends AnalysisEventListener<DemoBean> {/*** 每隔5條存儲數據庫,實際使用中可以100條,然后清理list ,方便內存回收*/private static final int BATCH_COUNT = 100;/*** 緩存的數據*/private List<DemoBean> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);/*** 假設這個是一個DAO,當然有業務邏輯這個也可以是一個service。當然如果不用存儲這個對象沒用。*/private DemoBean demoDAO;public DemoListener() {// 這里是demo,所以隨便new一個。實際使用如果到了spring,請使用下面的有參構造函數demoDAO = new DemoBean();}@Overridepublic void onException(Exception exception, AnalysisContext context) throws Exception {if (exception instanceof ExcelDataConvertException) {Integer columnIndex = ((ExcelDataConvertException) exception).getColumnIndex() + 1;Integer rowIndex = ((ExcelDataConvertException) exception).getRowIndex() + 1;String message = "第" + rowIndex + "行,第" + columnIndex + "列,數據格式有誤,請核實";System.out.println("導入數據轉換出現錯誤: " + message);} else if (exception instanceof RuntimeException) {System.out.println("導入錯誤:" + exception);if (exception.getMessage().contains("列與模板上順序不符,請勿修改表頭模板")) {throw new RuntimeException(exception.getMessage());}}}@Overridepublic void invoke(DemoBean data, AnalysisContext analysisContext) {System.out.println("解析到一條數據:{}"+data);cachedDataList.add(data);// 達到BATCH_COUNT了,需要去存儲一次數據庫,防止數據幾萬條數據在內存,容易OOMif (cachedDataList.size() >= BATCH_COUNT) {saveData();// 存儲完成清理 listcachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);}}@Overridepublic void doAfterAllAnalysed(AnalysisContext analysisContext) {// 這里也要保存數據,確保最后遺留的數據也存儲到數據庫saveData();System.out.println("解析完了");}/*** 加上存儲數據庫*/private void saveData() {System.out.println("{}條數據,開始存儲數據庫!"+ cachedDataList.size());
//        demoDAO.save(cachedDataList);System.out.println("存儲數據庫成功!");}}

測試程序

package com.wkl.testdemo.excel;import com.alibaba.excel.EasyExcel;import java.util.List;/*** @author wangkanglu* @version 1.0* @description* @date 2023-12-08 17:45*/
public class SimpleTest {public static void main(String[] args) {String path = "C:\\Users\\Desktop\\demo.xlsx";DemoListener listener = new DemoListener();EasyExcel.read(path,DemoBean.class,listener).sheet().doRead();List<DemoBean> cachedDataList = listener.getCachedDataList();System.out.println("end----");}
}

2:讀取多個sheet

 public static void main(String[] args) {String path = "C:\\Users\\wenge\\Desktop\\demo.xlsx";DemoListener listener = new DemoListener();//生成讀取對象ExcelReader excelReader = EasyExcel.read(path).build();//生成一個sheetReadSheet build = EasyExcel.readSheet(0).head(DemoBean.class).registerReadListener(listener).build();//讀取多個sheetExcelReader read = excelReader.read(Arrays.asList(build));List<DemoBean> cachedDataList = listener.getCachedDataList();System.out.println("end----");

3:復雜頭的讀取

如果遇到這樣的excel
在這里插入圖片描述

創建對象bean

package com.wkl.testdemo.excel;import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;/*** @author wangkanglu* @version 1.0* @description* @date 2023-12-08 17:28*/
@Data
public class DemoBeanheads {/*** 用名字去匹配,這里需要注意,如果名字重復,會導致只有一個字段讀取到數據*/@ExcelProperty({"大學","姓名"})private String name;/*** 強制讀取第二個 這里不建議 index 和 name 同時用,要么一個對象只用index,要么一個對象只用name去匹配*/@ExcelProperty({"大學","性別"})private String sex;
}

讀取器不變

測試程序

public static void main(String[] args) {String path = "C:\\Users\\Desktop\\demo.xlsx";DemoHeadListener listener = new DemoHeadListener();//生成讀取對象ExcelReader excelReader = EasyExcel.read(path).build();//生成一個sheetReadSheet build = EasyExcel.readSheet(0).head(DemoBeanheads.class).registerReadListener(listener).headRowNumber(2).build();//讀取多個sheetExcelReader read = excelReader.read(Arrays.asList(build));List<DemoBeanheads> cachedDataList = listener.getCachedDataList();System.out.println("end----");}

4:不創建對象的對

讀取器

package com.wkl.testdemo.excel;import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.exception.ExcelDataConvertException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.ObjectUtils;import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;@Slf4j
public class NoHeadMapListener extends AnalysisEventListener<Map<Integer, String>> {private List<Map<Integer, String>> list = new ArrayList<>();private static final SimpleDateFormat sdfFormat = new SimpleDateFormat("yyyy-MM-dd");//表頭private List<String> headList = Arrays.asList("姓名","性別");@Overridepublic void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {if (headMap==null){throw new RuntimeException("文件表頭為空,請勿上傳非法excel文件,請先下載對應的導入模板文件" );}if (headMap.size()!=headList.size()){throw new RuntimeException("文件表頭列與模板不符,請勿上傳非法excel文件,請先下載對應的導入模板文件" );}for (int i = 0; i < headList.size(); i++) {String tableHead = headMap.get(i);String head = headList.get(i);if (!head.equals(tableHead)) {throw new RuntimeException("表頭中'" + tableHead + "'列與模板上順序不符,請勿修改模板表頭");}}}@Overridepublic void invoke(Map<Integer, String> integerStringMap, AnalysisContext analysisContext) {
//        log.info("解析到一條數據:{}", JSON.toJSONString(integerStringMap));List<String> picList = new ArrayList<>();if (!ObjectUtils.isEmpty(integerStringMap)) {list.add(integerStringMap);}}@Overridepublic void doAfterAllAnalysed(AnalysisContext analysisContext) {log.info("所有數據解析完成!");}@Overridepublic void onException(Exception exception, AnalysisContext context) throws Exception {if (exception instanceof ExcelDataConvertException) {Integer columnIndex = ((ExcelDataConvertException) exception).getColumnIndex() + 1;Integer rowIndex = ((ExcelDataConvertException) exception).getRowIndex() + 1;String message = "第" + rowIndex + "行,第" + columnIndex + "列,數據格式有誤,請核實";log.error("導入數據轉換出現錯誤: " + message);} else if (exception instanceof RuntimeException) {log.error("導入錯誤:" + exception);if (exception.getMessage().contains("列與模板上順序不符,請勿修改表頭模板")) {throw new RuntimeException(exception.getMessage());}}}public List<String> getHeadList() {return headList;}public void setHeadList(List<String> headList) {this.headList = headList;}public List<Map<Integer, String>> getList() {return list;}}

測試程序

 public static void main(String[] args) {String path = "C:\\Users\\Desktop\\demo.xlsx";NoHeadMapListener listener = new NoHeadMapListener();EasyExcel.read(path, listener).sheet().doRead();List<String> headList = listener.getHeadList();List<Map<Integer, String>> list = listener.getList();System.out.println("end");}

讀取后的得到的數據列表:
在這里插入圖片描述

寫excel

1:最簡單的寫

創建對象

@Getter
@Setter
@EqualsAndHashCode
public class DemoData {@ExcelProperty("字符串標題")private String string;@ExcelProperty("日期標題")private Date date;@ExcelProperty("數字標題")private Double doubleData;/*** 忽略這個字段*/@ExcelIgnoreprivate String ignore;
}

測試程序

List<DemoData> data = new ArrayList();
fileName = TestFileUtil.getPath() + "simpleWrite" + System.currentTimeMillis() + ".xlsx";// 這里 需要指定寫用哪個class去寫,然后寫到第一個sheet,名字為模板 然后文件流會自動關閉// 如果這里想使用03 則 傳入excelType參數即可EasyExcel.write(fileName, DemoData.class).sheet("模板").doWrite(data);

測試程序-導出指定列

List<DemoData> data = new ArrayList();
fileName = TestFileUtil.getPath() + "simpleWrite" + System.currentTimeMillis() + ".xlsx";// 根據用戶傳入字段 假設我們要忽略 name列Set<String> excludeColumnFiledNames = new HashSet<String>();excludeColumnFiledNames.add("name");// 這里 需要指定寫用哪個class去寫,然后寫到第一個sheet,名字為模板 然后文件流會自動關閉EasyExcel.write(fileName, DemoData.class).excludeColumnFiledNames(excludeColumnFiledNames).sheet("模板").doWrite(data);// 根據用戶傳入字段 假設我們只要導出 name列Set<String> includeColumnFiledNames = new HashSet<String>();includeColumnFiledNames.add("name");// 這里 需要指定寫用哪個class去寫,然后寫到第一個sheet,名字為模板 然后文件流會自動關閉EasyExcel.write(fileName, DemoData.class).includeColumnFiledNames(includeColumnFiledNames).sheet("模板").doWrite(data);

2:數據寫到不同的sheet

fileName = TestFileUtil.getPath() + "repeatedWrite" + System.currentTimeMillis() + ".xlsx";// 這里 指定文件try (ExcelWriter excelWriter = EasyExcel.write(fileName, DemoData.class).build()) {// 去調用寫入,這里我調用了五次,實際使用時根據數據庫分頁的總的頁數來。這里最終會寫到5個sheet里面for (int i = 0; i < 5; i++) {// 每次都要創建writeSheet 這里注意必須指定sheetNo 而且sheetName必須不一樣WriteSheet writeSheet = EasyExcel.writerSheet(i, "模板" + i).build();// 分頁去數據庫查詢數據 這里可以去數據庫查詢每一頁的數據List<DemoData> data = data();excelWriter.write(data, writeSheet);}}

3:動態表頭寫入web

private List<List<String>> head() {List<List<String>> list = new ArrayList<List<String>>();List<String> head0 = new ArrayList<String>();head0.add("字符串" + System.currentTimeMillis());List<String> head1 = new ArrayList<String>();head1.add("數字" + System.currentTimeMillis());List<String> head2 = new ArrayList<String>();head2.add("日期" + System.currentTimeMillis());list.add(head0);list.add(head1);list.add(head2);return list;}private List<DemoData> data() {List<DemoData> list = ListUtils.newArrayList();for (int i = 0; i < 10; i++) {DemoData data = new DemoData();data.setString("字符串" + i);data.setDate(new Date());data.setDoubleData(0.56);list.add(data);}return list;}@GetMapping("download")public void download(HttpServletResponse response) throws IOException {// 這里注意 有同學反應使用swagger 會導致各種問題,請直接用瀏覽器或者用postmanresponse.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");response.setCharacterEncoding("utf-8");// 這里URLEncoder.encode可以防止中文亂碼 當然和easyexcel沒有關系String fileName = URLEncoder.encode("測試", "UTF-8").replaceAll("\\+", "%20");response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");EasyExcel.write(response.getOutputStream(), DownloadData.class).sheet("模板").doWrite(data());}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/207376.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/207376.shtml
英文地址,請注明出處:http://en.pswp.cn/news/207376.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

機器學習第15天:GBDT模型

??主頁 Nowl &#x1f525;專欄《機器學習實戰》 《機器學習》 &#x1f4d1;君子坐而論道&#xff0c;少年起而行之 ?? 文章目錄 GBDT模型介紹 Boosting 殘差 GBDT的缺點 python代碼實現 代碼 模型參數解釋 結語 GBDT模型介紹 GBDT&#xff08;Gradient Boos…

vivado $clog2函數

對于.v文件在vivado中是不支持&#xff0c;但是可以修改為.sv或更改文件屬性使用sytemverilog來支持。 /*** Math function: $clog2 as specified in Verilog-2005** clog2 0 for value 0* ceil(log2(value)) for value > 1** This implementatio…

php+mysql期末作業小項目

目錄 1、登錄界面 2、注冊界面 3、主界面 4、學生表界面 5 、查詢學生界面?編輯 6、修改學生信息界面?編輯 7、刪除學生信息界面 8、添加學生信息界面 9、后臺數據庫?編輯 一個簡單的php?mysql項目學生信息管理系統&#xff0c;用于廣大學子完成期末作業的參考&…

測試架構工程師需要具備哪些能力 ?

前言 相比于我們常見的研發架構師&#xff0c;測試架構師是近幾年才出現的一個崗位&#xff0c;當然崗位title其實沒有特殊的含義&#xff0c;在我看來測試架構師其實更像對某一類人的抽象稱呼和對其復合能力的期待及認可。 在聊這篇文章的主題之前&#xff0c;先來看這樣一個…

算法訓練營Day4(鏈表)

語言 采用的Java語言&#xff0c;一些分析也是用于Java&#xff0c;請注意。 24. 兩兩交換鏈表中的節點 24. 兩兩交換鏈表中的節點 - 力扣&#xff08;LeetCode&#xff09; 解題 這道題就是考驗鏈表的基礎操作&#xff0c;但是有個語言方面的知識需要去掌握&#xff0c;就是|…

TCP通信

第二十一章 網絡通信 本章節主要講解的是TCP和UDP兩種通信方式它們都有著自己的優點和缺點 這兩種通訊方式不通的地方就是TCP是一對一通信 UDP是一對多的通信方式 接下來會一一講解 TCP通信 TCP通信方式呢 主要的通訊方式是一對一的通訊方式&#xff0c;也有著優點和缺點…

如何在Android平板上遠程連接Ubuntu服務器使用code-server代碼開發

目錄 1.ubuntu本地安裝code-server 2. 安裝cpolar內網穿透 3. 創建隧道映射本地端口 4. 安卓平板測試訪問 5.固定域名公網地址 6.結語 1.ubuntu本地安裝code-server 準備一臺虛擬機,Ubuntu或者centos都可以&#xff0c;這里以VMwhere ubuntu系統為例 下載code server服務…

el-table 表格多選(后端接口搜索分頁)實現已選中的記憶功能。實現表格數據和已選數據(前端分頁)動態同步更新。

實現效果&#xff1a;&#xff08;可拉代碼下來看&#xff1a;vue-demo: vueDemo&#xff09; 左側表格為點擊查詢調用接口查詢出來的數據&#xff0c;右側表格為左側表格所有選擇的數據&#xff0c;由前端實現分頁。 兩個el-table勾選數據聯動更新 實現邏輯&#xff1a; el-…

低代碼開發到底是補品還是垃圾食品?

2023&#xff0c;低代碼徹底火了&#xff0c;甚至火到沒有點相關經驗&#xff0c;都不好意思出去面試的程度。 從業者對低代碼的發展充滿了想象&#xff0c;都認為未來低代碼的商業價值不可估量。 據Gartner的最新報告顯示&#xff0c;2023年全球低代碼開發技術市場規模預計將…

內部文件上傳以及渲染-接口API

文件上傳 地址http://172.16.0.118:8090/api/pm/base/affix/upload請求類型POSTContent-Type:text/plain;charsetutf-8參數 prjData {"prjId":"", "jobId":"3031b2c8-c809-4110-8e88-22c80a9c1ec0721aca89-96a1-4346-9b6e-022331d221d1Nec…

【EMNLP 2023】面向Stable Diffusion的自動Prompt工程算法BeautifulPrompt

近日&#xff0c;阿里云人工智能平臺PAI與華南理工大學朱金輝教授團隊合作在自然語言處理頂級會議EMNLP2023上發表了BeautifulPrompt的深度生成模型&#xff0c;可以從簡單的圖片描述中生成高質量的提示詞&#xff0c;從而使文生圖模型能夠生成更美觀的圖像。BeautifulPrompt通…

【MATLAB】MODWT分解+FFT+HHT組合算法

有意向獲取代碼&#xff0c;請轉文末觀看代碼獲取方式~也可轉原文鏈接獲取~ 1 基本定義 MODWT分解FFTHHT組合算法是一種綜合性的信號處理方法&#xff0c;它結合了經驗小波變換&#xff08;Empirical Wavelet Transform&#xff0c;EWT&#xff09;、快速傅里葉變換&#xff…

25.Oracle的回收站

oracle基礎系統學習目錄 01.CentOS7靜默安裝oracle11g 02.Oracle的啟動過程 03.從簡單的sql開始 04.Oracle的體系架構 05.Oracle數據庫對象 06.Oracle數據備份與恢復 07.用戶和權限管理 08.Oracle的表 09.Oracle表的分區 10.Oracle的同義詞與序列 11.Oracle的視圖 12.Oracle的…

愛智EdgerOS之深入解析如何應用愛智的視頻流模塊完成拉流

一、ONVIF 規范和常見視頻流傳輸協議 ① ONVIF 規范 隨著視頻監控產業鏈的成熟&#xff0c;市面上陸陸續續出現了各式各樣的網絡攝像設備&#xff0c;這些設備都需要通訊協議才能進行數據傳輸。早期廠商都采用私有協議&#xff0c;但是現在廠商分工明確&#xff0c;有的負責生…

程序員的技術成長攻略

推薦語&#xff1a;偶爾在公眾號看到的一篇文章&#xff0c;寫的非常好&#xff0c;在此分享給各位程序員兄弟&#xff0c;不光是對技術成長有幫助&#xff0c;其他領域也是同樣適用的&#xff01;建議反復閱讀&#xff0c;形成一套自己的技術成長策略。 原文地址&#xff1a;…

數據結構與算法:python棧和隊列的用法

python的棧和隊列其實都算作一個數組&#xff0c;棧從最后一個元素開始推出&#xff0c;隊列從第一個元素開始推出 # pop(0)刪除時間復雜度O(n) s [] #棧 q [] #隊列 s.append(1)#1入棧 q.append(1)#1入隊 s.pop()#出棧 q.pop(0)#出隊由于從第一個元素刪除需要挪動數組&…

【EI會議征稿】2024年粵港澳大灣區數字經濟與人工智能國際學術會議(DEAI2024)

2024年粵港澳大灣區數字經濟與人工智能國際學術會議(DEAI2024) 2024 Guangdong-Hong Kong-Macao Greater Bay Area International Conference on Digital Economy and Artificial Intelligence(DEAI2024) 2024年粵港澳大灣區數字經濟與人工智能國際學術會議(DEAI2024)由廣東科…

探索鴻蒙 TextInput組件

TextInput 根據組件名字&#xff0c;可以得知他是一個文本輸出框。 聲明代碼&#x1f447; TextInput({placeholder?:ResourceStr,text?:ResourceStr}); placeholder: 就是提示文本&#xff0c;跟網頁開發中的placeholder一樣的 text&#xff1a;輸入框當前的文本內容 特殊屬…

ChatGPT的進化史

真正的人工智能可以變現的完全與人類一樣思考時&#xff0c;世界會發生什么變化&#xff1f; ChatGPT就如它的名字一樣&#xff0c;人類創造它最初的目的只是一個聊天機器人。聊天嘛&#xff0c;只要你和他對話時他的回答像人類一樣自然就行了&#xff0c;看起來并沒什么了不起…

Linux服務器磁盤占用過高解決思路

服務器在運行時&#xff0c;經常出現磁盤占用過高&#xff0c;可能有如下原因&#xff1a; 1、是否有產生過大的日志文件&#xff0c;或者大文件中的log過大&#xff0c;導致磁盤占用過高&#xff1b; 2、查看磁盤占用情況&#xff0c;分析哪個目錄中文件占比最大&#xff1b; …