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

使用Easyexcel實現(xiàn)不同場景的數(shù)據(jù)導(dǎo)出功能

 更新時間:2024年03月07日 15:41:22   作者:super.aladdin  
這篇文章主要為大家詳細介紹了如何在不同場景下使用Easyexcel實現(xiàn)數(shù)據(jù)導(dǎo)出功能,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

導(dǎo)出的數(shù)據(jù)包含有圖片

導(dǎo)出excel表格的數(shù)據(jù)包含有圖片,這種場景比較少。通Easyexcel實現(xiàn)這樣的需求,我認為最簡便的方法就是使用前面提到的自定義轉(zhuǎn)換器(com.alibaba.excel.converters.Converter);假如有這樣一個場景,導(dǎo)出員工的信息,還要包括員工的一寸照。通常情況下,數(shù)據(jù)庫并不會真的存一張圖片,而是圖片存儲位置的相對路徑。

1、新建一個類EmpHeadPhotoConverter,實現(xiàn)com.alibaba.excel.converters.Converter接口,并重寫convertToExcelData()方法;

2、在重寫convertToExcelData()方法中,根據(jù)圖片的相同路徑或網(wǎng)絡(luò)地址讀取出圖片的字節(jié)流作為構(gòu)建WriteCellData對象的參數(shù)然后返回;

3、在員工信息的實體類Employee的照片列引入自定義的類型轉(zhuǎn)換器(EmpHeadPhotoConverter)

4、使用EasyExcel的工廠方法把數(shù)據(jù)寫出到excel表格中;

注:這里是使用默認的樣式,所以看起來可能點丑;@ContentRowHeight()用于調(diào)節(jié)數(shù)據(jù)行的高度;@ColumnWidth用于調(diào)節(jié)數(shù)據(jù)列的寬度;

public class EmpHeadPhotoConverter implements Converter<String> {
    @Override
    public WriteCellData<?> convertToExcelData(String value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {
        //根據(jù)圖片的相對路徑或網(wǎng)絡(luò)地址讀取圖片到byte輸出流(ByteArrayOutputStream)
        ByteArrayOutputStream byteArrayOutputStream = null;
        InputStream inputStream=null;
        try {
             inputStream = ClassLoader.getSystemResourceAsStream(value);
            byteArrayOutputStream = new ByteArrayOutputStream();
            int len=-1;
            byte[] bytes = new byte[1024];
            while ((len=inputStream.read(bytes))!=-1){
                byteArrayOutputStream.write(bytes);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (byteArrayOutputStream != null) {
                byteArrayOutputStream.close();
            }
            if (inputStream != null) {
                inputStream.close();
            }
        }
        //把輸出流中的圖片字節(jié)數(shù)組作為參數(shù)構(gòu)建writeCellData對象并返回
        //WriteCellData是EasyExcel對單元格數(shù)據(jù)的封裝
        return  new WriteCellData<>(byteArrayOutputStream.toByteArray());
    }
}
@Data
@ContentRowHeight(50)//數(shù)據(jù)行的高度
public class Employee implements Serializable {
    @ExcelProperty("姓名")
    private String realName;
    @ExcelProperty("員工編號")
    private String empNo;
    @ExcelProperty("性別")
    private String sex;
    @ExcelProperty("家庭地址")
    private String address;
    @ExcelProperty("聯(lián)系電話")
    private String phone;
    @ExcelProperty("電子郵箱")
    private String email;
    @ExcelProperty(value = "照片",converter = EmpHeadPhotoConverter.class)
    @ColumnWidth(10)//列寬
    private String headPhoto;
}
@Test
public void writeImage(){
    String exportPath=this.getExportPath();
    String exportFile=exportPath+File.separator+"員工基本信息(包含照片).xlsx";
    List<Employee> list = new ArrayList<>();
    for (int i = 0; i < 3; i++) {
        Employee employee = new Employee();
        employee.setRealName("張三"+i);
        employee.setEmpNo("CH"+(i+1));
        employee.setAddress("北京");
        employee.setEmpNo("zhangsan@163.com");
        employee.setSex("女");
        employee.setPhone("17777xxxxxx");
        //這里是示例,因為我把示例圖片放在了classpath下,后面可以根據(jù)圖片名字在classpath下找到
        //在實際的業(yè)務(wù)開發(fā)過程中,這里應(yīng)該是圖片的相對路徑或網(wǎng)絡(luò)地址
        employee.setHeadPhoto("zhangsan.jpeg");
        list.add(employee);
    }
    EasyExcel.write(exportFile,Employee.class).sheet().doWrite(list);
}

導(dǎo)出表格指定列寬行高

上面其實是已經(jīng)說過了,通過注解可以簡單的指定導(dǎo)出Excel表格的行、列的高度和寬度:

@ContentRowHeight()用于指定數(shù)據(jù)行的高度;

@HeadRowHeight()用于指定表頭行的高度;

@ColumnWidth()用于指定數(shù)據(jù)列的寬度;

導(dǎo)出表格自定義樣式

我比較喜歡使用easyexcel的一個很重要的原因就是,easyexcel在poi的基礎(chǔ)上,封裝的比較友好。就比如,在導(dǎo)出的時候,很多情況下需要自定義表格的樣式,easyexcel就提供了多種的實現(xiàn)方式。主要有三種:

1、通過注解;

2、編程式;

3、自定義類型轉(zhuǎn)換器。

不同的方式,側(cè)重的場景也有所不同,下面通過示例梳理一下使用方法:

編程式自定義樣式

通過編程式來自定義導(dǎo)出表格的樣式中,有一個非常關(guān)鍵類HorizontalCellStyleStrategy。

1、通過HorizontalCellStyleStrategy可以配置好表頭的樣式和數(shù)據(jù)行的樣式;

2、使用Easyexcel的工廠方法寫出數(shù)據(jù)前,把通過HorizontalCellStyleStrategy構(gòu)建好的樣式策略注冊到表格寫出構(gòu)建器里;

3、使用使用Easyexcel的工廠方法寫出數(shù)據(jù);

總結(jié):這種方法的優(yōu)點就是比較簡單,且容易理解構(gòu)建樣式的過程;缺點就是不太靈活;比較適合那些導(dǎo)出表格前可以明確知道導(dǎo)出的表格的樣式特點;

@Test
public void writeWithStyle2() {
    String exportPath = this.getExportPath();
    String exportFile = exportPath + File.separator + "員工基本信息v2.xlsx";
    List<Employee> list = new ArrayList<>();
    Employee employee = new Employee();
    employee.setRealName("張三");
    employee.setEmpNo("CH001");
    employee.setSex("女");
    Employee employee2 = new Employee();
    employee2.setRealName("李四");
    employee2.setEmpNo("CH002");
    employee2.setSex("男");
    list.add(employee);
    list.add(employee2);
    // 頭的策略
    WriteCellStyle headWriteCellStyle = new WriteCellStyle();
    // 背景設(shè)置為紅色
    headWriteCellStyle.setFillForegroundColor(IndexedColors.RED.getIndex());
    WriteFont headWriteFont = new WriteFont();
    headWriteFont.setFontHeightInPoints((short)20);
    headWriteCellStyle.setWriteFont(headWriteFont);
    // 內(nèi)容的策略
    WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
    // 這里需要指定 FillPatternType 為FillPatternType.SOLID_FOREGROUND 不然無法顯示背景顏色.頭默認了 FillPatternType所以可以不指定
    contentWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
    // 背景綠色
    contentWriteCellStyle.setFillForegroundColor(IndexedColors.GREEN.getIndex());
    WriteFont contentWriteFont = new WriteFont();
    // 字體大小
    contentWriteFont.setFontHeightInPoints((short)20);
    contentWriteCellStyle.setWriteFont(contentWriteFont);
    // 這個策略是 頭是頭的樣式 內(nèi)容是內(nèi)容的樣式 其他的策略可以自己實現(xiàn)
    HorizontalCellStyleStrategy horizontalCellStyleStrategy =
            new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);

    // 這里 需要指定寫用哪個class去寫,然后寫到第一個sheet,名字為模板 然后文件流會自動關(guān)閉
    EasyExcel.write(exportFile, Employee.class)
            .registerWriteHandler(horizontalCellStyleStrategy)
            .sheet()
            .doWrite(list);
}

注解形式自定義樣式

通過注解的形式來自定義導(dǎo)出表格的樣式,和編程式的比較類似,明顯的區(qū)別是一個需要通過在編寫代碼來定義樣式并應(yīng)用這個樣式;另一個是需要 使用注解定義好表格樣式,應(yīng)用樣式的過程easyexcel內(nèi)部已經(jīng)實現(xiàn)了,不用自己編寫代碼來實現(xiàn)??傮w上特點是一樣的:使用簡單,且比較好理解,缺點就是不靈活,不能動態(tài)的設(shè)置導(dǎo)出表格內(nèi)單元格的樣式。比較常用的注解有以下(有的是作用在類上,有的是作用在屬性上,注解需要設(shè)置哪些屬性可以點以注解的源里一看就很清楚):

作用在類上:

@HeadStyle(fillPatternType = FillPatternType.SOLID_FOREGROUND, fillForegroundColor = 10)
// 頭字體設(shè)置成20
@HeadFontStyle(fontHeightInPoints = 20)
// 內(nèi)容的背景設(shè)置成綠色 IndexedColors.GREEN.getIndex()
@ContentStyle(fillPatternType = FillPatternType.SOLID_FOREGROUND, fillForegroundColor = 17)
// 內(nèi)容字體設(shè)置成20
@ContentFontStyle(fontHeightInPoints = 20)

作用在屬性上

// 字符串的頭背景設(shè)置成粉紅 IndexedColors.PINK.getIndex()
@HeadStyle(fillPatternType = FillPatternType.SOLID_FOREGROUND, fillForegroundColor = 14)
// 字符串的頭字體設(shè)置成20
@HeadFontStyle(fontHeightInPoints = 30)
// 字符串的內(nèi)容的背景設(shè)置成天藍 IndexedColors.SKY_BLUE.getIndex()
@ContentStyle(fillPatternType = FillPatternType.SOLID_FOREGROUND, fillForegroundColor = 40)
// 字符串的內(nèi)容字體設(shè)置成20
@ContentFontStyle(fontHeightInPoints = 30)

自定義類型轉(zhuǎn)換器形式定義樣式

前兩種的樣式定義方法,都比較固定,不能根據(jù)導(dǎo)出數(shù)據(jù)的規(guī)則來動態(tài)設(shè)置表格內(nèi)單元格的樣式,如導(dǎo)出員工信息表格里如果性別是女的員工數(shù)據(jù)行,則使用紅色字體,如果是男性,則是使用藍色;因為導(dǎo)出數(shù)據(jù)通常是從數(shù)據(jù)源里動態(tài)取出的,在導(dǎo)出前沒辦法確定哪些行是男性,哪些員工是女性,所以需要動態(tài)的設(shè)置導(dǎo)出表格的樣式,自定義類型轉(zhuǎn)換器就可以很好的解決這個問題。

1、新建一個類SexColourConverter,實現(xiàn)com.alibaba.excel.converters.Converter接口,并重寫convertToExcelData()方法;

2、重寫convertToExcelData()方法中,根據(jù)單元格的內(nèi)容設(shè)置不同的樣式,示例中:如果性別是男,則字體為藍色;如果性別是女,則字體顏色是紅色;

3、在員工信息的實體類Employee的性別(sex)屬性上,通過@ExcelProperty()引入自定義的類型轉(zhuǎn)換器SexColourConverter;

4、使用Easyexcel的工廠方法實現(xiàn)表格數(shù)據(jù)的寫出;

總結(jié):這種方法很靈活,非常適合一些報表中,要求導(dǎo)出表格中數(shù)據(jù)達到在不同規(guī)則就要求有不同的樣式的場景。在我做過的項目里,有不少導(dǎo)出都有類似的規(guī)則:某個屬性達到預(yù)警閾值時,要導(dǎo)出數(shù)據(jù)的單元格格式標成紅色。

public class SexColourConverter implements Converter<String> {
    @Override
    public WriteCellData<?> convertToExcelData(String value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {
        WriteCellStyle writeCellStyle = new WriteCellStyle();
        WriteFont writeFont = new WriteFont();
        if ("男".equals(value)) {
            writeFont.setColor((short) 12);
        }
        if ("女".equals(value)) {
            writeFont.setColor((short) 10);
        }
        writeCellStyle.setWriteFont(writeFont);
        WriteCellData<Object> cellData = new WriteCellData<>();
        cellData.setWriteCellStyle(writeCellStyle);
        cellData.setType(CellDataTypeEnum.STRING);
        cellData.setStringValue(value);
        return cellData;
    }
}
@Data
public class Employee implements Serializable {
    @ExcelProperty("姓名")
    private String realName;
    @ExcelProperty("員工編號")
    private String empNo;
    @ExcelProperty(value = "性別",converter = SexColourConverter.class)
    private String sex;
}
@Test
public void writeWithStyle() {
    String exportPath = this.getExportPath();
    String exportFile = exportPath + File.separator + "員工基本信息v2.xlsx";
    List<Employee> list = new ArrayList<>();
    Employee employee = new Employee();
    employee.setRealName("張三");
    employee.setEmpNo("CH001");
    employee.setSex("女");
    Employee employee2 = new Employee();
    employee2.setRealName("李四");
    employee2.setEmpNo("CH002");
    employee2.setSex("男");
    list.add(employee);
    list.add(employee2);
    EasyExcel.write(exportFile, Employee.class).sheet().doWrite(list);
}

在設(shè)置單元格背景或字體的顏色的時候,顏色會對應(yīng)一個short類型的數(shù)據(jù)

復(fù)雜表頭的導(dǎo)出

特別是一些財務(wù)類型的報表導(dǎo)出,表頭往往是復(fù)合表頭,比較復(fù)雜

easyexcel對于這種場景提供了兩種方法,一種是注解;另外一種是通過一種特殊的數(shù)據(jù)結(jié)構(gòu)List<list>;根據(jù)我的感受,我是推薦使用注解的;

第一種:

如果是所在列是復(fù)合表頭,則使用@ExcelProperty()注解,從上到下標明表頭組成;如果是普通表頭,按普通的用法標明表頭名稱即可;是不是很簡單?

@Data
public class EmpSalary  {
    @ExcelProperty({"基本信息","姓名"})
    private String realName;
    @ExcelProperty({"基本信息","員工編號"})
    private String empNo;
    //,converter = SalaryDateConverter.class
    @ExcelProperty(value = "工資日期")
    private String salaryDate;
    @ExcelProperty({"工資構(gòu)成","基本工資"})
    private Float baseAmount;
    @ExcelProperty({"工資構(gòu)成","全勤獎"})
    private Float fullAttendAmount;
    @ExcelProperty({"工資構(gòu)成","五險一金"})
    private Float insurance;
    //特別資金
    @ExcelIgnore
    private Float specialAmount;
}
@Test
public void writeHead() {
    String exportPath = this.getExportPath();
    String exportFile = exportPath + File.separator + "員工工資表v3.xlsx";
    EasyExcel.write(exportFile, EmpSalary.class).sheet().doWrite(this.empSalaryData(10));
}

第二種:

使用List<list>結(jié)構(gòu)來組織表頭數(shù)據(jù),開始的時候還不是很理解表頭的數(shù)據(jù)結(jié)構(gòu)為什么這么奇怪,到這里是不是明白了。對于普通表頭List肯定就可以了,但是在一些復(fù)雜的場景就不行了。這么制定的話,什么場景都不在話下,關(guān)鍵還可以動態(tài)生成表頭,這一點確實比注解的方式要靈活一些;所以具體使用哪種,要根據(jù)業(yè)務(wù)場景決定了。

@Test
public void writeHead() {
    String exportPath = this.getExportPath();
    String exportFile = exportPath + File.separator + "員工工資表v4.xlsx";
    List<List<String>> headList = new ArrayList<>();
    List<String> head1 = new ArrayList<>();
    head1.add("基本信息");
    head1.add("姓名");
    headList.add(head1);
    List<String> head2 = new ArrayList<>();
    head2.add("基本信息");
    head2.add("員工編號");
    headList.add(head2);
    List<String> head3 = new ArrayList<>();
    head3.add("工資日期");
    headList.add(head3);
    List<String> head4 = new ArrayList<>();
    head4.add("工資構(gòu)成");
    head4.add("基本工資");
    headList.add(head4);
    List<String> head5 = new ArrayList<>();
    head5.add("工資構(gòu)成");
    head5.add("全勤獎");
    headList.add(head5);
    List<String> head6 = new ArrayList<>();
    head6.add("工資構(gòu)成");
    head6.add("保險");
    headList.add(head6);
    EasyExcel.write(exportFile).head(headList).sheet().doWrite(this.empSalaryData(10));
}

日期、數(shù)字、自定義格式的導(dǎo)出

自定義格式的導(dǎo)出可以參考上一篇《Spring Boot:基于Easyexcel實現(xiàn)導(dǎo)入功能》中的日期、數(shù)字及其他自定義格式的轉(zhuǎn)換部分,SalaryDateConverter#convertToExcelData(),導(dǎo)出時候的數(shù)據(jù)格式轉(zhuǎn)換邏輯可以寫在這里面;SalaryDateConverter#convertToJavaData()導(dǎo)入時候的數(shù)據(jù)格式轉(zhuǎn)換的實現(xiàn)邏輯可以寫在這里;SalaryDateConverter是com.alibaba.excel.converters.Converter的實現(xiàn)類;

除了實現(xiàn)com.alibaba.excel.converters.Converterr接口,easyexcel也預(yù)置了一些常用的注解來實現(xiàn)格式轉(zhuǎn)換,導(dǎo)入導(dǎo)出的時候都能用,如@DateTimeFormat、@NumberFormat;

這里特別注意別導(dǎo)錯類了:

com.alibaba.excel.annotation.format.DateTimeFormat;

com.alibaba.excel.annotation.format.NumberFormat;

@Data
public class EmpSalary  {
    @ExcelProperty({"基本信息","姓名"})
    private String realName;
    @ExcelProperty({"基本信息","員工編號"})
    private String empNo;
    @DateTimeFormat("yyyy年MM月")
    @ExcelProperty(value = "工資日期")
    private Date salaryDate;
    @ExcelProperty({"工資構(gòu)成","基本工資"})
    private Float baseAmount;
    @ExcelProperty({"工資構(gòu)成","全勤獎"})
    private Float fullAttendAmount;
    @ExcelProperty({"工資構(gòu)成","五險一金"})
    private Float insurance;
    //特別資金
    @ExcelIgnore
    @NumberFormat
    private Float specialAmount;
    @NumberFormat("#.##%")
    @ExcelProperty("績效完成百分比")
    private Double jixiao;
}
@Test
public void writeByConverter(){
    String exportPath = this.getExportPath();
    String exportFile = exportPath + File.separator + "員工工資表v5.xlsx";
    List<EmpSalary> list=new ArrayList<>();
    EmpSalary empSalary = new EmpSalary();
    empSalary.setEmpNo("CH" + ( 1));
    empSalary.setRealName("張三" + ( 1));
    empSalary.setSalaryDate(new Date());
    empSalary.setBaseAmount(5000f);
    empSalary.setFullAttendAmount(500f);
    empSalary.setInsurance(300f);
    empSalary.setJixiao(0.9877);
    list.add(empSalary);
    EasyExcel.write(exportFile, EmpSalary.class).sheet("12月").doWrite(list);
}

讀取全部的sheet頁

這里需要注意兩個地方:1、讀取shee頁的數(shù)據(jù)結(jié)構(gòu)是一樣的;2、excel的列與接收數(shù)據(jù)類的屬性是一一對應(yīng)的,如果不對應(yīng),可參考讀取到指定列部分,使用@ExcelProperty(index=xx)顯性的指定對應(yīng)關(guān)系;

@Data
public class Student implements Serializable {
    private Integer id;
    private String stuCode;
    private String stuName;
    private String sex;
    private String born;
    private Integer age;
    private String address;
    private String motherName;
    private String fatherName;
    private Integer grade;
    private Integer classNum;
}
@Test
public void readAllSheet(){
    String userDir = System.getProperty("user.dir");
    String importPath = userDir + File.separator + "import";
    File dir = new File(importPath);
    if (!dir.exists()) {
        dir.mkdirs();
    }
    String importFile = importPath + File.separator + "學(xué)生信息表.xlsx";
    StudentReadListener studentReadListener = new StudentReadListener();
    EasyExcel.read(importFile, Student.class, studentReadListener).doReadAll();
    List<Student> students = studentReadListener.getStudents();
    for (Student student : students) {
        System.out.println(student.getStuName());
    }
}

日期、數(shù)字及其他自定義格式的轉(zhuǎn)換

在導(dǎo)入或者導(dǎo)出excel的時候,如果想對某一列的數(shù)據(jù)格式作調(diào)整轉(zhuǎn)換,可以自定義一個轉(zhuǎn)換器(com.alibaba.excel.converters.Converter),然后這個個轉(zhuǎn)換器通過@ExcelProperty(converter=xxxxx.class)標記在接收參數(shù)的類型的屬性上;

這種轉(zhuǎn)換數(shù)據(jù)格式的需求,有時候是主動的,有時候是被動的。什么是主動的的呢?假如前數(shù)據(jù)為庫存儲的日期格式是yyyyMMdd,導(dǎo)出的時候想要的是xxxx年xx月xx日,然后你就可以實現(xiàn)一個類型轉(zhuǎn)換器(Converter)主動完成這個事。下面舉個被動的例子,excel中關(guān)于日期的一個坑,繞不過的坑,所以是“被動”滴。

excel中單元格式格式是日期的,easyexcel解析后是一個數(shù)字,這不是解析錯誤了,而是excel中對于日期存儲的格式就是數(shù)字,這個數(shù)字代表的是1900年1月1日,到單元格式內(nèi)日期的天數(shù),所以解析結(jié)果中是一個數(shù)字并不難理解,但是這不是我我們想要的結(jié)果呀。更惡心的是,java中的Date的時間起點1970年1月1日,所以被動的需求就產(chǎn)生了,需要把一個以1900-1-1為起天的天數(shù)代表的日期,轉(zhuǎn)換為以1970-1-1為起點的java.util.Date。標準的不統(tǒng)一,產(chǎn)生的結(jié)果就是這么惡心。

public class SalaryDateConverter implements Converter<String> {
    @Override
    public Class<?> supportJavaTypeKey() {
        return String.class;
    }
    @Override
    public CellDataTypeEnum supportExcelTypeKey() {
        return CellDataTypeEnum.STRING;
    }
    //導(dǎo)入的時候會走這個方法,導(dǎo)入的轉(zhuǎn)換邏輯可以在這個方法里實現(xiàn)
    @Override
    public String convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {
        BigDecimal numberValue = cellData.getNumberValue();
        //平時不要動不動就搞個util工具類,我曾經(jīng)目睹一個新同事,用上用不上的也不管,上來在工程里導(dǎo)入了幾十個工具類,搞得maven依賴沖突
        // org.apache.poi.ss.usermodel.DateUtil是POI的工具類,
        // DateUtil.getJavaDate()的功能就是把以1900-1-1為起點的日期天數(shù)轉(zhuǎn)換成java.util.Date,直接拿來用就好了,基本不用擔心里面有bug
        Date javaDate = DateUtil.getJavaDate(numberValue.doubleValue());
        //com.alibaba.excel.util.DateUtils是easyexcel封裝的日期轉(zhuǎn)換工具類,能用就用上唄,基本也不用擔心有bug
        String format = DateUtils.format(javaDate, DateUtils.DATE_FORMAT_10);
        return format;
    }
    //導(dǎo)出的時候會走這個方法,導(dǎo)出的轉(zhuǎn)換邏輯可以在這個方法里實現(xiàn)
    @Override
    public WriteCellData<?> convertToExcelData(String value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {
        return null;
    }
}
@Data
public class EmpSalary  {
    @ExcelProperty("姓名")
    private String realName;
    @ExcelProperty("員工編號")
    private String empNo;
    @ExcelProperty(value = "工資日期",converter = SalaryDateConverter.class)
    private String salaryDate;
    @ExcelProperty("工資數(shù)額")
    private Float amount;
}
@Test
public void readByConvert(){
    String userDir = System.getProperty("user.dir");
    String importPath = userDir + File.separator + "import";
    File dir = new File(importPath);
    if (!dir.exists()) {
        dir.mkdirs();
    }
    String importFile = importPath + File.separator + "員工工資表.xlsx";
    EmpSalaryReadListener empSalaryReadListener = new EmpSalaryReadListener();
    EasyExcel.read(importFile, EmpSalary.class, empSalaryReadListener).sheet().doRead();
    List<EmpSalary> empSalaries = empSalaryReadListener.getEmpSalaries();
    System.out.println(empSalaries.size());
}

表頭有多行的讀取

easyexcel在讀取表格內(nèi)容的時候,默認是從第二行開始讀的,因為第一行通常是表頭,所以上面沒有指定從第幾行開始讀也沒有問題。但是遇到下圖樣式的復(fù)合表頭的時候,表頭是占了兩行,數(shù)據(jù)是從第三行開始的,那么在讀取的時候讀取監(jiān)聽器、接收數(shù)據(jù)的類沒有變化,而是在讀取的時候要顯性指定從第幾行開始讀,實際指定的時候是索引,從0開始,第三行的索引就是2;

@Test
public void readManyRow(){
    String userDir = System.getProperty("user.dir");
    String importPath = userDir + File.separator + "import";
    File dir = new File(importPath);
    if (!dir.exists()) {
        dir.mkdirs();
    }
    String importFile = importPath + File.separator + "員工工資表 - 副本.xlsx";
    EmpSalaryReadListener empSalaryReadListener = new EmpSalaryReadListener();
    //數(shù)據(jù)從第三行開始,索引是2
    EasyExcel.read(importFile, EmpSalary.class, empSalaryReadListener).sheet().headRowNumber(2).doRead();
    List<EmpSalary> empSalaries = empSalaryReadListener.getEmpSalaries();
    System.out.println(empSalaries.size());
}
@Data
public class EmpSalary  {
    private String realName;
    private String empNo;
    @ExcelProperty(value = "工資日期",converter = SalaryDateConverter.class)
    private String salaryDate;
    private Float baseAmount;
    private Float fullAttendAmount;
    private Float insurance;
}

表頭的讀取

有時候也會有這樣的需求,就是除了讀取表格的數(shù)據(jù)外,表頭的數(shù)據(jù)也要讀取出來,easyexcel的讀取監(jiān)聽器里的實現(xiàn)類里重寫invokeHead()方法即可,下面以讀取多行表頭,寫一個示例:

public class EmpSalaryReadListener implements ReadListener<EmpSalary> {
    private List<EmpSalary> empSalaries=new ArrayList<>();
    public List<EmpSalary> getEmpSalaries() {
        return empSalaries;
    }
    @Override
    public void invoke(EmpSalary data, AnalysisContext context) {
        empSalaries.add(data);
    }
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
    }
    @Override
    public void invokeHead(Map<Integer, ReadCellData<?>> headMap, AnalysisContext context) {
        for (Integer key : headMap.keySet()) {
            System.out.println("key:"+key+","+headMap.get(key).getStringValue());
        }
        System.out.println("---------");
    }
}

表頭信息也是逐行讀取的,即每讀取一行就會回調(diào)一下監(jiān)聽器的表頭讀取回調(diào)方法(invokeHead()),表頭信息結(jié)果是存儲在一個map中,map的key為excel表格列上的索引,value是表頭信息。對于多行合并單元格后,合并單元格后的內(nèi)容在第一個格里,其他單元格也會占一個位置但是是空的;

以上就是使用Easyexcel實現(xiàn)不同場景的數(shù)據(jù)導(dǎo)出功能的詳細內(nèi)容,更多關(guān)于Easyexcel數(shù)據(jù)導(dǎo)出的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • java封裝全局異常處理深入詳解

    java封裝全局異常處理深入詳解

    這篇文章主要為大家介紹了java封裝全局異常處理的深入詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-09-09
  • 從0到1學(xué)SpringCloud之SpringCloud?gateway網(wǎng)關(guān)路由配置示例詳解

    從0到1學(xué)SpringCloud之SpringCloud?gateway網(wǎng)關(guān)路由配置示例詳解

    Spring?Cloud?Gateway的目標提供統(tǒng)一的路由方式且基于Filter?鏈的方式提供了網(wǎng)關(guān)基本的功能,?例如:安全、監(jiān)控、指標和限流?,這篇文章主要介紹了從0到1學(xué)SpringCloud之SpringCloud?gateway網(wǎng)關(guān)路由配置示例詳解,需要的朋友可以參考下
    2023-04-04
  • Spring?MVC跨域問題及解決

    Spring?MVC跨域問題及解決

    這篇文章主要介紹了Spring?MVC跨域問題及解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-03-03
  • SpringBoot實現(xiàn)文件斷點續(xù)傳功能詳解

    SpringBoot實現(xiàn)文件斷點續(xù)傳功能詳解

    在處理大文件傳輸或網(wǎng)絡(luò)不穩(wěn)定的情況下,文件斷點續(xù)傳功能顯得尤為重要,本文將詳細介紹如何使用Spring Boot實現(xiàn)文件的斷點續(xù)傳功能,需要的可以了解下
    2025-04-04
  • 關(guān)于try 和 throw 簡單使用示例

    關(guān)于try 和 throw 簡單使用示例

    每過一段時間,就總是會對try有點生疏,特別寫了個程序來測試以下,有時候 throw是底層拋出來的,你不處理,默認就throw了
    2013-08-08
  • OGNL表達式基本語法與用法詳解

    OGNL表達式基本語法與用法詳解

    這篇文章主要介紹了OGNL表達式基本語法與用法詳解,具有一定參考價值。需要的朋友可以了解下。
    2017-09-09
  • 新建Maven工程出現(xiàn)Process?Terminated的問題解決

    新建Maven工程出現(xiàn)Process?Terminated的問題解決

    當Maven出現(xiàn)"Process terminated"錯誤時,這通常是由于配置文件或路徑錯誤導(dǎo)致的,本文主要介紹了新建Maven工程出現(xiàn)Process?Terminated的問題解決,感興趣的可以了解一下
    2024-04-04
  • Springboot Mybatis Plus自動生成工具類詳解代碼

    Springboot Mybatis Plus自動生成工具類詳解代碼

    mybatis-plus 是一個 Mybatis 的增強工具,在 Mybatis 的基礎(chǔ)上只做增強不做改變,為簡化開發(fā)、提高效率而生,這篇文章帶你使用Springboot Mybatis Plus自動生成工具類
    2021-11-11
  • 詳解Java中@Override的作用

    詳解Java中@Override的作用

    這篇文章主要介紹了詳解Java中@Override的作用的相關(guān)資料,希望通過本文能幫助到大家,讓大家理解這部分內(nèi)容,需要的朋友可以參考下
    2017-10-10
  • 使用Java實現(xiàn)加密之AES加解密

    使用Java實現(xiàn)加密之AES加解密

    這篇文章主要介紹了使用Java實現(xiàn)加密之AES加解密,AES為最常見的對稱加密算法,對稱加密算法也就是加密和解密用相同的密鑰,需要的朋友可以參考下
    2023-05-05

最新評論