EasyExcel:快速讀寫Excel的工具類

image

EasyExcel:快速讀寫Excel的工具類

項目介紹

?EasyExcel是一個基于Java的、快速、簡潔、解決大文件內存溢出的Excel處理工具。
他能讓你在不用考慮性能、內存的等因素的情況下,快速完成Excel的讀、寫等功能。

pom地址


?

<!--exel-->
<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>4.0.3</version>
</dependency>

快速入門


簡單讀

讀取excel的操作,主要如下:

  1. 創建對應數據對象(映射表格中的列)
  2. 創建一個xxxListener類(可以使用匿名內部類替代)
  3. 創建輸入流(或者其他io方式)
  4. 調用EasyExcel方法進行讀取

test.xlsx,使用此文件進行讀取,放入resources下使用

步驟一:創建數據對象

舉例:DemoData?

@Data
public class DemoData {private Long id;private String nickName;private Double score;
}
  • ?@Data是Lombok[^1]中的方法,可以快速生成setter和getter以及toString等

步驟二:創建Listener

舉例:DemoDataListener?

@Slf4j
public class DemoDataListener implements ReadListener<DemoData> {/*** 每隔5條存儲數據庫,實際使用中可以100條,然后清理list ,方便內存回收*/private static final int BATCH_COUNT = 100;/*** 緩存的數據*/private List<DemoData> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);/*** 每讀一條數據解析就會調用此方法* @param demoData* @param analysisContext*/@Overridepublic void invoke(DemoData demoData, AnalysisContext analysisContext) {Gson gson = new Gson();log.info("解析到一條數據:{}", gson.toJson(demoData));cachedDataList.add(demoData);// 達到BATCH_COUNT了,需要去存儲一次數據庫,防止數據幾萬條數據在內存,容易OOMif (cachedDataList.size() >= BATCH_COUNT) {saveData();// 存儲完成清理listcachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);}}@Overridepublic void doAfterAllAnalysed(AnalysisContext analysisContext) {// 這里也要保存數據,確保最后遺留的數據也存儲到數據庫saveData();log.info("所有數據解析完成!");}/*** 保存數據到數據庫*/private void saveData() {log.info("{}條數據,開始存儲數據庫!", cachedDataList.size());log.info("存儲數據庫成功!");}}
  • Listener可以對解析的數據進行更高自由度的操作:如 寫入數據到數據庫?

步驟三:創建輸入流

接下來的代碼和步驟四都是一個代碼中的,此階段為調用。

創建輸入流代碼塊:

try (InputStream inputStream = getClass().getClassLoader().getResourceAsStream("test.xlsx")) {...
} 
catch (Exception e) {e.printStackTrace();
}

?

步驟四:調用方法

?

tips

這里舉例的是其中一種調用方法,詳情請參考:完整讀取代碼案例

?

EasyExcel.read(inputStream, DemoData.class, new PageReadListener<DemoData>(dataList -> {dataList.forEach(data -> {log.info("讀取到數據:{}", data);});
})).sheet().doRead();

完整讀取代碼案例

?ReadTest.java

@Slf4j
public class ReadTest {/*** 方法1:簡單讀* 1. 創建excel對應的對象 參照* 2. 由于默認一行行讀取excel,所以需要創建excel一行一行的回調監聽器* 3. 直接讀即可*/@Testpublic void simpleRead() {try (InputStream inputStream = getClass().getClassLoader().getResourceAsStream("test.xlsx")) {EasyExcel.read(inputStream, DemoData.class, new PageReadListener<DemoData>(dataList -> {dataList.forEach(data -> {log.info("讀取到數據:{}", data);});})).sheet().doRead();} catch (Exception e) {e.printStackTrace();}}/*** 方法2:簡單讀(匿名內部類)* 優化點:更多自定義空間,如:讀取過程中添加存儲到數據庫* 1. 創建excel對應的對象 參照* 2. 由于默認一行行讀取excel,所以需要創建excel一行一行的回調監聽器* 3. 直接讀即可*/@Testpublic void simpleRead2() {try (InputStream inputStream = getClass().getClassLoader().getResourceAsStream("test.xlsx")) {EasyExcel.read(inputStream, DemoData.class, new ReadListener<DemoData>() {/*** 單次緩存數據量*/private static final int BATCH_COUNT = 100;/*** 臨時存儲*/private List<DemoData> cacheDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);@Overridepublic void invoke(DemoData demoData, AnalysisContext analysisContext) {cacheDataList.add(demoData);log.info("讀取到數據:{}", demoData);if (cacheDataList.size() >= BATCH_COUNT) {saveData();// 存儲完成清理 listcacheDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);}}@Overridepublic void doAfterAllAnalysed(AnalysisContext analysisContext) {saveData();}/*** 模擬存儲數據庫*/private void saveData() {log.info("{}條數據, 開始存儲數據庫!", cacheDataList.size());log.info("數據庫存儲成功!");}}).sheet().doRead();} catch (IOException e) {log.error("IOException: {}", e.getMessage());}}/*** 其余兩個最簡單的寫法*/@Testpublic void simpleRead3() {try (InputStream inputStream = getClass().getClassLoader().getResourceAsStream("test.xlsx")) {// 寫法1// 由于流使用后會自動關閉,所以寫法1和2要分開運行
//            EasyExcel.read(inputStream, DemoData.class, new DemoDataListener()).sheet().doRead();// 寫法2try (ExcelReader excelReader = EasyExcel.read(inputStream, DemoData.class, new DemoDataListener()).build()) {// 構建一個sheet 可以指定明知或者sheetNoReadSheet sheet = EasyExcel.readSheet(0).build();// 讀取excelReader.read(sheet);}} catch (IOException e) {log.error("IOException: {}", e.getMessage());}}}

?

指定索引或列名讀取

和簡單讀差不多,主要修改在 Data 上,需要對映射的屬性使用 @ExcelProperty 進行配置。

這里使用表格:test1.xlsx

步驟一:創建數據對象

?IndexOrNameData

@Data
public class IndexOrNameData {/*** 強制讀取第三個* 一般不建議 index 和 name 同時用*/@ExcelProperty(index = 2)private Double doubleData;/*** 用名字去匹配,這里需要注意,如果名字重復,會只讀取第一個** @ExcelProperty("字符串標題")*/@ExcelProperty("字符串標題")private String string;@ExcelProperty("日期標題")private Date date;}

?

  • image

步驟二:創建Listener

?IndexOrNameDataListener

@Slf4j
public class IndexOrNameDataListener extends AnalysisEventListener<IndexOrNameData> {/*** 每隔5條存儲數據庫,實際使用中可以100條,然后清理list ,方便內存回收*/private static final int BATCH_COUNT = 5;Gson gson = new Gson();private List<IndexOrNameData> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);@Overridepublic void invoke(IndexOrNameData data, AnalysisContext context) {log.info("解析到一條數據:{}", gson.toJson(data));cachedDataList.add(data);if (cachedDataList.size() >= BATCH_COUNT) {saveData();cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);}}@Overridepublic void doAfterAllAnalysed(AnalysisContext context) {saveData();log.info("所有數據解析完成!");}/*** 加上存儲數據庫*/private void saveData() {log.info("{}條數據,開始存儲數據庫!", cachedDataList.size());log.info("存儲數據庫成功!");}
}

步驟三:創建輸入流以及調用

?

/**
* 指定列的下標或列名* 1. 創建excel對應的實體對象,并使用{@link ExcelProperty}注解* 2. 由于默認一行行的讀取excel,所以需要創建excel一行一行的回調監聽器* 3. 直接讀即可*/
@Test
public void indexOrNameRead() {try (InputStream in = getClass().getClassLoader().getResourceAsStream("test1.xlsx")) {EasyExcel.read(in, IndexOrNameData.class, new IndexOrNameDataListener()).sheet().doRead();} catch (IOException e) {log.error("IOException: {}", e.getMessage());}
}
?

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

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

相關文章

WSL Ubuntu Docker 代理自動配置教程

WSL Ubuntu Docker 代理自動配置教程 WSL Ubuntu Docker 代理自動配置教程 背景說明 在 WSL2 環境下使用 Docker 時&#xff0c;由于網絡環境限制&#xff0c;經常需要通過 Windows 主機上的代理來訪問 Docker Hub。但每次 Windows 重啟后&#xff0c;WSL 獲取到的主機 IP 地址…

踩坑實錄:Django繼承AbstractUser時遇到的related_name沖突及解決方案

一、問題現象分析 咱們在用Django開發時&#xff0c;有時候需要擴展用戶模型&#xff0c;就會去繼承AbstractUser。但這么做的時候&#xff0c;要是沒處理好groups和user_permissions這兩個多對多字段的反向查詢名稱&#xff0c;就會遇到這樣的報錯&#xff1a;主要就是這種錯誤…

push pop 和 present dismiss

push/pop 和 present/dismiss 文章目錄push/pop 和 present/dismiss前言push / poppresent普通的present多層present多層present后的父子關系問題多層彈出會遇到的問題showViewController 和 showDetailViewControllershowViewControllershowDetailViewControllerdismiss模態化…

服務器異常負載排查手冊 · 隱蔽進程篇

適用范圍 適用于 Linux 3.10 生產環境&#xff0c;發現 load 高但用戶態 CPU 接近 0 % 的場景。1. 現場凍結目標&#xff1a;在 rootkit 干預前保存易失數據。#!/bin/bash # freeze.sh TS$(date %s) mkdir -p /srv/ir/${TS} cd /srv/ir/${TS}# 1.1 進程樹&#xff08;busybox 靜…

2024理想算法崗筆試筆記

要理解指令微調&#xff08;Instruction Tuning&#xff09;&#xff0c;需要先將其置于大語言模型&#xff08;LLM&#xff09;的訓練框架中 —— 它并非模型訓練的起點&#xff0c;而是針對 “讓模型更懂人類需求” 的關鍵優化步驟。簡單來說&#xff0c;指令微調是通過讓模型…

Oracle 11g離線安裝依賴包完整解決方案

本文還有配套的精品資源&#xff0c;點擊獲取 簡介&#xff1a;Oracle 11g是一款廣泛使用的關系型數據庫管理系統&#xff0c;在離線環境下安裝時需依賴多個系統庫和工具。本“oracle11g依賴包”壓縮文件包含了在CentOS 7.7上安裝Oracle 11g可能缺失的關鍵依賴RPM包&#xf…

VBA數據結構選型:效率差5倍的生死抉擇

VBA性能生死局&#xff1a;Dictionary與Collection效率差5倍&#xff01;90%開發者用反血虧“你以為Collection是VBA的‘輕量級選手’&#xff1f;大錯特錯&#xff01;實測數據顯示&#xff1a;在10萬級數據循環中&#xff0c;Dictionary的查詢速度比Collection快5倍&#xff…

電機控制(四)-級聯PID控制器與參數整定(MATLABSimulink)

PID算法 普通PID&#xff08;Proportional-Integral-Derivative&#xff09; 通過比例&#xff08;P&#xff09;、積分&#xff08;I&#xff09;和微分&#xff08;D&#xff09;三項來進行控制 比例項&#xff08;P&#xff09;&#xff1a;根據當前誤差&#xff08;目標值…

數據結構深度解析:二叉樹的基本原理

在數據結構體系中&#xff0c;樹是一種重要的非線性層次結構&#xff0c;它通過 “節點” 與 “邊” 的連接關系&#xff0c;模擬了現實世界中樹的分支結構&#xff0c;能夠高效地解決數據的查找、插入、刪除等問題。而二叉樹作為樹結構中最簡單、應用最廣泛的類型&#xff0c;…

【React】Ant Design 5.x 實現tabs圓角及反圓角效果

需要實現的效果實現思路 利用tab頁的before和after屬性&#xff0c;添加tab頁前后的圓弧屬性&#xff0c;同時使用tab頁的shadow陰影填充右下角的圓弧空缺部分。<TabsonChange{onChange}type"card"items{getTabItems()}/>.ant-tabs-nav{margin: 0;.ant-tabs-na…

WordPress過濾文章插入鏈接rel屬性noopener noreferrer值

WordPress過濾文章插入鏈接rel屬性noopener noreferrer值在保存文章的時候&#xff0c;WordPress會自動過濾文章內容中的鏈接&#xff0c;具有target屬性的鏈接會自動添加rel"noopener noreferrer"&#xff0c;該屬性是為了預防跨站攻擊&#xff0c;站內鏈接似乎沒有…

make_shared的使用

目錄 1. make_shared 的基本概念 基本用法 2. 引入 make_shared 的主要原因 2.1 解決傳統構造方式的問題 2.2 標準委員會的動機 3. make_shared 的核心優勢 3.1 性能優勢&#xff08;最重要優點&#xff09; 內存分配優化&#xff1a; 性能提升表現&#xff1a; 3.2 異…

基于 Gemini 的 CI/CD 自動化測評 API 集成實戰教程

在現代軟件開發中&#xff0c;CI/CD 集成 已經成為必不可少的流程。它不僅能幫助團隊快速迭代&#xff0c;還能通過自動化手段提升代碼質量。而在編程培訓和團隊內部學習中&#xff0c;如何引入 自動化測評 API&#xff0c;實現提交即測評、即時反饋呢&#xff1f;本文將以 Gem…

SOME/IP-SD(Service Discovery)協議的核心協議

<摘要> 本解析以AutoSAR AP R22-11版本為基準&#xff0c;全面系統地闡述了SOME/IP-SD&#xff08;Service Discovery&#xff09;協議的核心內容。從車載網絡演進背景切入&#xff0c;詳細剖析了面向服務架構&#xff08;SOA&#xff09;下服務發現的必要性&#xff0c;…

視頻串行解串器(SerDes)介紹

視頻串行解串器&#xff08;SerDes&#xff09;是高速數據通信中的核心接口技術&#xff0c;通過串行化與解串行化實現視頻信號的高效傳輸&#xff0c;廣泛應用于汽車電子、數據中心、高清視頻傳輸等領域。 一、技術原理串行化&#xff08;Serializer&#xff09; 功能&#xf…

哈士奇vs網易高級數倉:數據倉庫的靈魂是模型、數據質量還是計算速度?| 易錯題

面試場景 面試官: (微笑,營造輕松但專業的氛圍)嗨,哈士奇,歡迎來參加網易的二面。我看你簡歷上數據倉庫的項目經驗很豐富,我們今天就深入聊聊。我這里有一個經典的問題想聽聽你的看法:在你看來,數據倉庫的靈魂是模型、數據質量還是計算速度? 哈士奇: (不假思索,…

貪心算法應用:3D打印支撐結構問題詳解

Java中的貪心算法應用&#xff1a;3D打印支撐結構問題詳解 1. 問題背景與概述 1.1 3D打印中的支撐結構問題 在3D打印過程中&#xff0c;當模型存在懸空部分&#xff08;overhang&#xff09;時&#xff0c;通常需要添加支撐結構&#xff08;support structure&#xff09;來防止…

Python爬蟲實戰:研究3D plotting模塊,構建房地產二手房數據采集和分析系統

1. 引言 1.1 研究背景 在大數據與人工智能技術快速發展的背景下,數據已成為驅動決策的核心要素。互聯網作為全球最大的信息載體,蘊含海量結構化與非結構化數據,如何高效提取并分析這些數據成為學術界與產業界的研究熱點。 網絡爬蟲技術通過自動化請求與解析網頁,實現數據…

Gradio全解10——Streaming:流式傳輸的音頻應用(7)——ElevenLabs:高級智能語音技術

Gradio全解10——Streaming&#xff1a;流式傳輸的音頻應用&#xff08;7&#xff09;——ElevenLabs&#xff1a;高級智能語音技術10.7 ElevenLabs&#xff1a;高級智能語音技術10.7.1 核心功能與可用模型1. 核心功能與產品2. 三類語音模型10.7.2 文本轉語音API1. 完整操作步驟…

【桃子同學筆記4】PCIE訓練狀態機(LTSSM)基礎

首先&#xff0c;所謂LTSSM&#xff0c;即&#xff1a;Link Training and Status State Machine&#xff08;鏈路訓練及狀態機&#xff09; 下圖為 LTSSM 的狀態機及訓練過程&#xff1a; LTSSM 包含 11 個頂層狀態&#xff1a;Detect、Polling、Configuration、Recovery、L0、…