欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

easyexcel讀取excel合并單元格數(shù)據(jù)的操作代碼

 更新時間:2023年05月04日 10:05:56   作者:luffy5459  
這篇文章主要介紹了easyexcel讀取excel合并單元格數(shù)據(jù)的操作代碼,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下

    普通的excel列表,easyexcel讀取是沒有什么問題的。但是,如果有合并單元格,那么它讀取的時候,能獲取數(shù)據(jù),但是數(shù)據(jù)是不完整的。如下所示的單元格數(shù)據(jù):

    我們通過簡單的異步讀取,最后查看數(shù)據(jù)內容:

  ExcelData.java

package com.example.model;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ExcelData {
    @ExcelProperty("學生姓名")
    private String name;
    @ExcelProperty("年齡")
    private int age;
    @ExcelProperty("性別")
    private String gender;
    @ExcelProperty({"課程", "課程名稱"})
    private String courseName;
    @ExcelProperty({"課程", "分數(shù)"})
    private double score;
}

    ExcelRead.java

package com.example.service;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.example.model.ExcelData;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
import java.util.List;
@Slf4j
public class ExcelRead {
    private static final String FILEPATH = "e:\\test\\student.xlsx";
    public List<ExcelData> list() {
        List<ExcelData> excelDataList = new ArrayList<>();
        EasyExcel.read(FILEPATH, ExcelData.class, new AnalysisEventListener<ExcelData>() {
            @Override
            public void invoke(ExcelData excelData, AnalysisContext analysisContext) {
                log.info("read data {}", excelData);
                excelDataList.add(excelData);
            }
            @Override
            public void doAfterAllAnalysed(AnalysisContext analysisContext) {
            }
        }).sheet().doRead();
        return excelDataList;
    }
}

   ExcelTest.java

package com.example.service;
import com.example.model.ExcelData;
import java.util.List;
public class ExcelTest {
    public static void main(String[] args) {
        ExcelRead excelRead = new ExcelRead();
        List<ExcelData> list = excelRead.list();
        System.out.println(list.size());
    }
}

    運行程序,打印日志信息如下:

   獲取了6個數(shù)據(jù)沒錯,但是每一個合并單元格記錄里面都有一個數(shù)據(jù)獲取是空的。

    解決辦法就是需要在異步讀取數(shù)據(jù)監(jiān)聽器里面讀取合并單元格的額外數(shù)據(jù),并把這部分數(shù)據(jù)給補充上。

    需要修改的地方:

    1、實體需要增加注解索引值:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class ExcelData {
    @ExcelProperty(value = "學生姓名", index = 0)
    private String name;
    @ExcelProperty(value = "年齡", index = 1)
    private int age;
    @ExcelProperty(value = "性別", index = 2)
    private String gender;
    @ExcelProperty(value = {"課程", "課程名稱"}, index = 3)
    private String courseName;
    @ExcelProperty(value = {"課程", "分數(shù)"}, index = 4)
    private double score;
}

   2、自定義監(jiān)聽器,讀取合并單元格數(shù)據(jù):

package com.example.service;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.enums.CellExtraTypeEnum;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.metadata.CellExtra;
import com.example.model.ExcelData;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
import java.util.List;
@Slf4j
public class CustomAnalysisEventListener extends AnalysisEventListener<ExcelData> {
    private int headRowNum;
    public CustomAnalysisEventListener(int headRowNum) {
        this.headRowNum = headRowNum;
    }
    private List<ExcelData> list = new ArrayList<>();
    private List<CellExtra> cellExtraList = new ArrayList<>();
    @Override
    public void invoke(ExcelData excelData, AnalysisContext analysisContext) {
        log.info(" data -> {}", excelData);
        list.add(excelData);
    }
    @Override
    public void extra(CellExtra extra, AnalysisContext context) {
        CellExtraTypeEnum type = extra.getType();
        switch (type) {
            case MERGE: {
                if (extra.getRowIndex() >= headRowNum) {
                    cellExtraList.add(extra);
                }
                break;
            }
            default:{
            }
        }
    }
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
    }
    public List<ExcelData> getList() {
        return list;
    }
    public List<CellExtra> getCellExtraList() {
        return cellExtraList;
    }
}

    3、通過監(jiān)聽器讀取數(shù)據(jù),通過監(jiān)聽器獲取數(shù)據(jù)和合并單元格數(shù)據(jù),然后設置單元格數(shù)據(jù)。

 
package com.example.service;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.enums.CellExtraTypeEnum;
import com.alibaba.excel.metadata.CellExtra;
import com.example.model.ExcelData;
import lombok.extern.slf4j.Slf4j;
import java.lang.reflect.Field;
import java.util.List;
@Slf4j
public class ExcelRead {
    private static final int HEAD_ROW_NUM = 2;
    private static final String FILEPATH = "e:\\test\\student.xlsx";
    public List<ExcelData> list() {
        List<ExcelData> excelDataList;
        CustomAnalysisEventListener listener = new CustomAnalysisEventListener(HEAD_ROW_NUM);
        EasyExcel.read(FILEPATH, ExcelData.class, listener).extraRead(CellExtraTypeEnum.MERGE).sheet().doRead();
        excelDataList = listener.getList();
        List<CellExtra> cellExtraList = listener.getCellExtraList();
        if (cellExtraList != null && cellExtraList.size() > 0) {
            mergeExcelData(excelDataList, cellExtraList, HEAD_ROW_NUM);
        }
        return excelDataList;
    }
    private void mergeExcelData(List<ExcelData> excelDataList, List<CellExtra> cellExtraList, int headRowNum) {
        cellExtraList.forEach(cellExtra -> {
            int firstRowIndex = cellExtra.getFirstRowIndex() - headRowNum;
            int lastRowIndex = cellExtra.getLastRowIndex() - headRowNum;
            int firstColumnIndex = cellExtra.getFirstColumnIndex();
            int lastColumnIndex = cellExtra.getLastColumnIndex();
            //獲取初始值
            Object initValue = getInitValueFromList(firstRowIndex, firstColumnIndex, excelDataList);
            //設置值
            for (int i = firstRowIndex; i <= lastRowIndex; i++) {
                for (int j = firstColumnIndex; j <= lastColumnIndex; j++) {
                    setInitValueToList(initValue, i, j, excelDataList);
                }
            }
        });
    }
    private void setInitValueToList(Object filedValue, Integer rowIndex, Integer columnIndex, List<ExcelData> data) {
        ExcelData object = data.get(rowIndex);
        for (Field field : object.getClass().getDeclaredFields()) {
            field.setAccessible(true);
            ExcelProperty annotation = field.getAnnotation(ExcelProperty.class);
            if (annotation != null) {
                if (annotation.index() == columnIndex) {
                    try {
                        field.set(object, filedValue);
                        break;
                    } catch (IllegalAccessException e) {
                        log.error("設置合并單元格的值異常:{}", e.getMessage());
                    }
                }
            }
        }
    }
    private Object getInitValueFromList(Integer firstRowIndex, Integer firstColumnIndex, List<ExcelData> data) {
        Object filedValue = null;
        ExcelData object = data.get(firstRowIndex);
        for (Field field : object.getClass().getDeclaredFields()) {
            field.setAccessible(true);
            ExcelProperty annotation = field.getAnnotation(ExcelProperty.class);
            if (annotation != null) {
                if (annotation.index() == firstColumnIndex) {
                    try {
                        filedValue = field.get(object);
                        break;
                    } catch (IllegalAccessException e) {
                        log.error("設置合并單元格的初始值異常:{}", e.getMessage());
                    }
                }
            }
        }
        return filedValue;
    }
}

    有個小細節(jié)需要注意,我們在通過監(jiān)聽器讀取的時候,還需要額外讀取合并單元格部分。

EasyExcel.read(FILEPATH, ExcelData.class, listener).extraRead(CellExtraTypeEnum.MERGE).sheet().doRead();   

    還有個小細節(jié),就是我們的表格一般都是有頭的,頭的內容可能是2行,可能是1行,在進行合并單元格處理的時候,需要考慮這個行數(shù)。我們定義了一個常量HEAD_ROW_NUM來記錄這個行數(shù),最后進行單元格值計算的時候傳入。 

    我在處理excel數(shù)據(jù)中發(fā)現(xiàn),如果這個單元格合并,是由我們的程序自己做的,那么它讀取的時候,是沒有問題的。在上面為null的地方,它其實都有值:

    但是在實際中,我們的excel不能保證不被人為編輯,那么就很有可能,我們在進行合并單元格的時候,把有值和無值合并到一起,最后就出現(xiàn)前面提到的讀取合并單元格出現(xiàn)數(shù)據(jù)缺失的問題。 而我們期望,合并單元格部分他們的數(shù)據(jù)應該是一樣的。所以今天的解決方案是一種保險的做法,不管你的表格是否有合并單元格,是否人為修改,最終都能把合并單元格缺失的數(shù)據(jù)進行恢復。

到此這篇關于easyexcel讀取excel合并單元格數(shù)據(jù)的操作代碼的文章就介紹到這了,更多相關easyexcel合并單元格數(shù)據(jù)內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 使用java模擬簡單的tomcat的方法詳解

    使用java模擬簡單的tomcat的方法詳解

    這篇文章主要為大家詳細介紹了java模擬簡單的tomcat的方法,使用數(shù)據(jù)庫,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • IDEA編譯亂碼Build Output提示信息亂碼

    IDEA編譯亂碼Build Output提示信息亂碼

    IDEA編譯的時候亂碼,Build Output提示信息亂碼,本文就詳細的介紹一下解決方法,有需要的同學可以了解一下
    2021-06-06
  • 詳解Java線性結構中的鏈表

    詳解Java線性結構中的鏈表

    除了一些算法之外,我們還有掌握一些常見的數(shù)據(jù)結構,比如數(shù)組、鏈表、棧、隊列、樹等結構,所以接下來就給大家詳細講解一下線性結構中的鏈表,需要的朋友可以參考下
    2023-07-07
  • SpringBoot配置數(shù)據(jù)庫密碼加密的方法

    SpringBoot配置數(shù)據(jù)庫密碼加密的方法

    由于系統(tǒng)安全的考慮,配置文件中不能出現(xiàn)明文密碼的問題,本文就給大家詳細介紹下springboot配置數(shù)據(jù)庫密碼加密的方法,下面話不多說了,來一起看看詳細的介紹吧,需要的朋友可以參考下
    2023-08-08
  • Centos中yum方式安裝java的實現(xiàn)示例

    Centos中yum方式安裝java的實現(xiàn)示例

    這篇文章主要介紹了Centos中yum方式安裝java的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-04-04
  • IDEA 插件 mapper和xml互相跳轉操作

    IDEA 插件 mapper和xml互相跳轉操作

    這篇文章主要介紹了IDEA 插件 mapper和xml互相跳轉操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • SpringBoot 多線程事務回滾的實現(xiàn)

    SpringBoot 多線程事務回滾的實現(xiàn)

    本文是基于springboot的@Async注解開啟多線程,并通過自定義注解和AOP實現(xiàn)的多線程事務,避免繁瑣的手動提交/回滾事務,感興趣的可以了解一下
    2024-02-02
  • java jdk動態(tài)代理詳解

    java jdk動態(tài)代理詳解

    動態(tài)代理類的Class實例是怎么生成的呢,是通過ProxyGenerator類來生成動態(tài)代理類的class字節(jié)流,把它載入方法區(qū)
    2013-09-09
  • Java垃圾回收之分代收集算法詳解

    Java垃圾回收之分代收集算法詳解

    今天小編就為大家分享一篇關于Java垃圾回收之分代收集算法詳解,小編覺得內容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-10-10
  • Spring的BeanFactoryPostProcessor接口示例代碼詳解

    Spring的BeanFactoryPostProcessor接口示例代碼詳解

    這篇文章主要介紹了Spring的BeanFactoryPostProcessor接口,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-02-02

最新評論