最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java實(shí)現(xiàn)讀取Excel文件功能(EasyExcel初使用)

 更新時(shí)間:2024年07月23日 09:40:49   作者:Java雪荷  
EasyExcel是一款基于Java語言的開源Excel解析工具,可以幫助我們快速、高效地讀取和寫入Excel文件,這篇文章主要給大家介紹了關(guān)于Java實(shí)現(xiàn)讀取Excel文件功能的相關(guān)資料,使用的是EasyExcel,需要的朋友可以參考下

前言

在我們項(xiàng)目的開發(fā)中啊,前端有時(shí)候會(huì)傳送 Excel 文件給后端(Java)去解析,那我們作為后端該如何實(shí)現(xiàn)對(duì) Excel 文件的解析和數(shù)據(jù)讀取呢?說到這我就不得不推薦 EasyExcel 了!

EasyExcel 介紹

引用下官方對(duì)于 EasyExcel 介紹:EasyExcel是一個(gè)基于Java的、快速、簡(jiǎn)潔、解決大文件內(nèi)存溢出的Excel處理工具。他能讓你在不用考慮性能、內(nèi)存的等因素的情況下,快速完成Excel的讀、寫等功能。

官方網(wǎng)址:EasyExcel官方文檔 - 基于Java的Excel處理工具 | Easy Excel

快速上手 EasyExcel

前置工作

先創(chuàng)建一個(gè) Spring Boot 工程,并在 pom.xml 文件添加 EasyExcel 和 Lombok 依賴。

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
            <version>3.1.1</version>
        </dependency>

知道表頭

如果我們知道 Excel 數(shù)據(jù)的表頭,即每列數(shù)據(jù)的類型包括有多少列時(shí)就可以用此方法讀取 Excel 文件數(shù)據(jù)。

我們以下圖數(shù)據(jù)為例,對(duì)改 Excel 中的數(shù)據(jù)進(jìn)行獲取和處理。

方法一:

首先我們創(chuàng)建一個(gè)名為 ExcelData 的 Java 對(duì)象,共有兩個(gè)屬性,分別是 date(日期列數(shù)據(jù))和 useNum(用戶列數(shù)據(jù)),每個(gè)屬性對(duì)應(yīng) Excel 每列某一行中的數(shù)據(jù)。那么很顯而易見,每一行的數(shù)據(jù)就是一個(gè) ExcelData 對(duì)象,所有行的數(shù)據(jù)合起來就是一個(gè)泛型為 ExcelData 的 ExcelData 的集合。

@Data
public class ExcelData implements Serializable {
    /**
     * 對(duì)應(yīng)表格的日期列
     */
    private String date;
    /**
     * 對(duì)應(yīng)表格的用戶數(shù)列
     */
    private Integer userNum;
}

隨后編寫一個(gè)測(cè)試類,并在其中編寫測(cè)試方法。

EasyExcel 的 read 方法有很多中構(gòu)造方法,其中 Class head 就是表頭類型,傳入它還要傳入 ReadListener 監(jiān)聽器,以便在去讀取每行數(shù)據(jù)時(shí)做些自定義操作。我們直接傳入它的實(shí)現(xiàn)類實(shí)例,因?yàn)?PageReadListener 支持逐頁讀取數(shù)據(jù),通過讀取指定行數(shù)的數(shù)據(jù)保證占用更少的內(nèi)存。

話不多說直接上代碼:

    /**
     * 知道表頭,并形成映射關(guān)系
     */
    @Test
    public void doImportsForMapping() throws FileNotFoundException{
        // 讀取 resource 目錄下的 Excel 文件(網(wǎng)站數(shù)據(jù).xlsx)
        File file = ResourceUtils.getFile("classpath:網(wǎng)站數(shù)據(jù).xlsx");
        // 創(chuàng)建一個(gè) list 存儲(chǔ)每行的數(shù)據(jù),即 ExcelData 對(duì)象
        List<ExcelData> list = new ArrayList<>();
        // 直接使用 EasyExcel 的 read 方法,同時(shí)定義表頭的類型,以便將列中數(shù)據(jù)映射為 ExcelData 對(duì)象
        EasyExcel.read(file, ExcelData.class, new PageReadListener<ExcelData>(dataList -> {
            // 并且每行數(shù)據(jù),并將其 add 至 list 中
            for (ExcelData excelData : dataList) {
                if (excelData != null) {
                    list.add(excelData);
                }
            }
        })).excelType(ExcelTypeEnum.XLSX).sheet().doRead(); // 指定 Excel 的文件后綴,開始分析讀取
        for (ExcelData excelData : list) {
            System.out.println(excelData.getDate() + "," + excelData.getUserNum());
        }
    }

執(zhí)行結(jié)果:

方法二:

方法一是直接一次性讀取 Excel 中的數(shù)據(jù),缺少要讀取的數(shù)據(jù)行數(shù)和一些自定義操作,所以我們?cè)谶@里對(duì)上面的代碼增強(qiáng)一下。

在此方法中我們通過匿名內(nèi)部類的方式實(shí)現(xiàn) ReadListenser 接口,無需額外寫一個(gè)類去實(shí)現(xiàn) ReadListener了。我們?cè)O(shè)置了一個(gè)臨時(shí)存儲(chǔ)的列表(大小為 2),當(dāng)每次讀取的數(shù)據(jù)(執(zhí)行 invoke 方法)添加到臨時(shí)存儲(chǔ)表中。當(dāng)其長(zhǎng)度超過 2 時(shí)進(jìn)行全部刪除,在刪除前我們可以將臨時(shí)存儲(chǔ)的列表存到數(shù)據(jù)庫(kù)中,或進(jìn)行一些其他的自定義操作。

doAfterAllAnalysed 方法是分析并獲取所有的數(shù)據(jù)后會(huì)執(zhí)行的一個(gè)方法,我們可以在其中打上日志,表示 Excel 所有數(shù)據(jù)已存入數(shù)據(jù)庫(kù)中。

 /**
     * 知道表頭,并形成映射關(guān)系
     * @throws FileNotFoundException
     */
    @Test
    public void doImportsForMappingByInnerClass() throws FileNotFoundException{
        File file = ResourceUtils.getFile("classpath:網(wǎng)站數(shù)據(jù).xlsx");
        EasyExcel.read(file, ExcelData.class, new ReadListener<ExcelData>() {

            // 單次緩存的數(shù)據(jù)量
            public static final int BATCH_COUNT = 2;

            // 臨時(shí)存儲(chǔ)的列表
            private List<ExcelData> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
            @Override
            public void invoke(ExcelData excelData, AnalysisContext analysisContext) {
                cachedDataList.add(excelData);
                getData(excelData);
                if (cachedDataList.size() >= BATCH_COUNT) {
                    cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
                }
            }

            @Override
            public void doAfterAllAnalysed(AnalysisContext analysisContext) {
                System.out.println("存儲(chǔ)數(shù)據(jù)庫(kù)成功");
            }

            private void getData(ExcelData excelData) {
                System.out.println(excelData.getDate() + "," + excelData.getUserNum());
            }
        }).excelType(ExcelTypeEnum.XLSX).sheet().doRead();

    }

執(zhí)行結(jié)果:

不知道表頭

方法三:

上面的兩種方法都是我們知道表頭,包括列的類型和列數(shù)量的情況下對(duì) Excel 文件進(jìn)行數(shù)據(jù)獲取的。那我們不知道表頭信息,又該如何操作呢?

我們依賴?yán)?EasyExcel 的 read 方法,和前面的步驟大差不差,只不過這次參數(shù)少了,如果你還要獲取表頭即表格的第一行數(shù)據(jù),還可通過 headRowNumber 方法指定首行編號(hào)為 0。

此時(shí)返回的是一個(gè) List<Map<Integer, String>> 集合,其中 Map 的 鍵對(duì)應(yīng)表格的列編號(hào)(從 0 開始),值就是對(duì)應(yīng)某一行某一列的值,List 的索引代表某一行的數(shù)據(jù)。調(diào)用 Map 對(duì)象的 values() 方法即可直接獲取某一行數(shù)據(jù)的集合,List<Map<Integer, String>> 就是所有行數(shù)據(jù)的集合。我們這說可能不太直觀,我把它打印出來給你們看就很簡(jiǎn)單明了了。

[{0=日期, 1=用戶數(shù)}, {0=1號(hào), 1=10}, {0=2號(hào), 1=20}, {0=3號(hào), 1=30}, {0=4號(hào), 1=70}, {0=5號(hào), 1=20}, {0=6號(hào), 1=29}, {0=7號(hào), 1=24}, {0=8號(hào), 1=31}, {0=9號(hào), 1=40}, {0=10號(hào), 1=38}, {0=11號(hào), 1=43}]

代碼如下:

    @Test
    public void doImport() throws FileNotFoundException {
        List<Map<Integer, String>> list = null;
        File file = ResourceUtils.getFile("classpath:網(wǎng)站數(shù)據(jù).xlsx");
        try {
            list = EasyExcel.read(file)
                    .excelType(ExcelTypeEnum.XLSX)
                    .sheet()
                    .headRowNumber(0)
                    .doReadSync();
        } catch (Exception e) {
            throw new RuntimeException("讀取 Excel 文件失敗");
        }
        StringBuilder stringBuilder = new StringBuilder();
        for (int i=0;i<list.size();i++) {
            // 轉(zhuǎn)為 LinkedHashMap 主要是為了保證讀取的數(shù)據(jù)和表格順序一致
            LinkedHashMap<Integer, String> linkedHashMap = (LinkedHashMap) list.get(i);
            List<String> dataList = linkedHashMap.values().stream()
                    .filter(ObjectUtils::isNotEmpty).collect(Collectors.toList());
            stringBuilder.append(StringUtils.join(dataList, ",")).append("\n");
        }
        System.out.println(stringBuilder.toString());
    }

執(zhí)行結(jié)果:

總結(jié)

如果知道表頭并且數(shù)據(jù)量較小,就用方法一,如果數(shù)據(jù)量較大或者想添加一些自定操作就用方法二。如果不知道表頭并且想要讀取表頭的信息就用方法三。

到此這篇關(guān)于Java實(shí)現(xiàn)讀取Excel文件功能的文章就介紹到這了,更多相關(guān)Java讀取Excel文件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java時(shí)間處理詳細(xì)教程與最佳實(shí)踐案例

    Java時(shí)間處理詳細(xì)教程與最佳實(shí)踐案例

    本文系統(tǒng)講解Java時(shí)間處理,涵蓋基礎(chǔ)概念、傳統(tǒng)API(Date/Calendar/SimpleDateFormat)、Java8新API(java.time包)及高級(jí)應(yīng)用,提供代碼案例與最佳實(shí)踐,適合開發(fā)者全面掌握時(shí)間操作技巧,感興趣的朋友一起看看吧
    2025-08-08
  • Spring入門配置和DL依賴注入實(shí)現(xiàn)圖解

    Spring入門配置和DL依賴注入實(shí)現(xiàn)圖解

    這篇文章主要介紹了Spring入門配置和DL依賴注入實(shí)現(xiàn)圖解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-10-10
  • Java設(shè)計(jì)模式之觀察者模式observer?pattern詳解

    Java設(shè)計(jì)模式之觀察者模式observer?pattern詳解

    這篇文章主要介紹了Java設(shè)計(jì)模式之觀察者模式observer?pattern詳解,當(dāng)一個(gè)對(duì)象發(fā)生數(shù)據(jù)變化時(shí),通知其他相關(guān)的一系列對(duì)象,接受到通知的對(duì)象根據(jù)該對(duì)象的變化進(jìn)行相應(yīng)處理以響應(yīng)變化的過程,需要的朋友可以參考下
    2023-12-12
  • 全面解讀Java編程中的內(nèi)部類

    全面解讀Java編程中的內(nèi)部類

    這篇文章主要介紹了Java的內(nèi)部類,包括類成員訪問等Java入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-09-09
  • 使用Feign配置請(qǐng)求頭以及支持Https協(xié)議

    使用Feign配置請(qǐng)求頭以及支持Https協(xié)議

    這篇文章主要介紹了使用Feign配置請(qǐng)求頭以及支持Https協(xié)議,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • struts2.3.24+spring4.1.6+hibernate4.3.11+mysql5.5.25開發(fā)環(huán)境搭建圖文教程

    struts2.3.24+spring4.1.6+hibernate4.3.11+mysql5.5.25開發(fā)環(huán)境搭建圖文

    這篇文章主要介紹了struts2.3.24+spring4.1.6+hibernate4.3.11+mysql5.5.25開發(fā)環(huán)境搭建圖文教程,感興趣的小伙伴們可以參考一下
    2016-06-06
  • java substring(a)與substring(a,b)的使用說明

    java substring(a)與substring(a,b)的使用說明

    這篇文章主要介紹了java substring(a)與substring(a,b)的使用說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-10-10
  • spring boot線上日志級(jí)別動(dòng)態(tài)調(diào)整的配置步驟

    spring boot線上日志級(jí)別動(dòng)態(tài)調(diào)整的配置步驟

    這篇文章主要為大家介紹了spring boot線上日志級(jí)別動(dòng)態(tài)調(diào)整的配置步驟,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2022-03-03
  • Java中具有映射關(guān)系的容器:數(shù)組和Map的區(qū)別說明

    Java中具有映射關(guān)系的容器:數(shù)組和Map的區(qū)別說明

    這篇文章主要介紹了Java中具有映射關(guān)系的容器:數(shù)組和Map的區(qū)別說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • Redisson分布式鎖原理深入分析

    Redisson分布式鎖原理深入分析

    文章介紹了Redisson分布式鎖的工作原理,并詳細(xì)解釋了加鎖、續(xù)期、解鎖的核心流程,Redisson利用Redis的單線程、自動(dòng)續(xù)期和Lua腳本原子性等特點(diǎn),避免了傳統(tǒng)鎖常見的死鎖、鎖爭(zhēng)用和誤刪等問題,此外,還總結(jié)了使用Redisson分布式鎖時(shí)的注意事項(xiàng)和避坑點(diǎn)
    2026-04-04

最新評(píng)論

全州县| 霍州市| 惠州市| 南丹县| 昭觉县| 越西县| 禹州市| 揭阳市| 嘉峪关市| 临洮县| 龙陵县| 铜陵市| 塘沽区| 读书| 萍乡市| 怀远县| 泰和县| 海阳市| 宝丰县| 桐城市| 佛教| 长乐市| 长汀县| 璧山县| 九龙坡区| 黑水县| 抚顺市| 通化县| 汉寿县| 习水县| 漾濞| 灵山县| 施秉县| 二手房| 盘山县| 广东省| 平山县| 措美县| 普定县| 海口市| 肥城市|