1. 首页
  2. 后端

EasyExcel的常用方法封装

  EasyExcel的常用方法封装

================

由于工作中时不时会遇到使用EasyExcel导出的场景,而每次遇到这类场景都需要重新复习一遍EasyExcel去处理,因此本文特地记录下自己对EasyExcel常用方法的一些封装,以方便日后提升工作效率。

为什么使用EasyExcel

总结下来就是一句话:性能好,功能强!

easyexcel重写了poi对07版Excel的解析,一个3M的excel用POI sax解析依然需要100M左右内存,改用easyexcel可以降低到几M,并且再大的excel也不会出现内存溢出;03版依赖POI的sax模式,在上层做了模型转换的封装,让使用者更加简单方便。

官网地址:easyexcel.opensource.alibaba.com/docs/curren…

依赖导入

首先导入maven依赖,下边我还引入了一些其他依赖,方便测试使用使用。

<dependencies>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>easyexcel</artifactId>
        <version>3.3.1</version>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.73</version>
        <scope>test</scope>
    </dependency>
</dependencies>

功能设计

然后是excel的工具类封装,工具内部封装了常用的导出功能,不过这里我全部都是采用了同步导出,代码逻辑处理起来其实并不复杂,只是api长期不用容易忘记,所以就整理了一些常用的功能给大家。

  • excel全页导入
  • excel指定页,指定头部导入
  • excel单页导出
  • excel指定页,指定头部导出
package qiyu.framework.excel.service;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.read.builder.ExcelReaderBuilder;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.metadata.WriteSheet;
import qiyu.framework.excel.config.ExportSheetInfo;
import qiyu.framework.excel.config.ImportSheetInfo;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author idea
 * @Date: Created in 22:01 2024/6/22
 * @Description
 */
public class ExcelExportUtils {

    /**
     * 导入数据到excel第一页中
     *
     * @param fileName
     * @param path
     * @param sheetInfo
     * @throws IOException
     */
    public static <T> void exportExcel(String fileName, String path, ExportSheetInfo sheetInfo) {
        File exportFile = new File(path + "/" + fileName);
        try (ExcelWriter excelWriter = EasyExcel.write(exportFile).build()) {
            WriteSheet writeSheet;
            writeSheet = EasyExcel.writerSheet(sheetInfo.getSheetName()).head(sheetInfo.getHeadClass()).build();
            excelWriter.write(sheetInfo.getDataList(), writeSheet);
            excelWriter.finish();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 分页导出excel
     *
     * @param fileName
     * @param path
     * @param sheetDataList
     * @throws IOException
     */
    public static <T> void exportExcel(String fileName, String path, List<ExportSheetInfo> sheetDataList) {
        File exportFile = new File(path + "/" + fileName);
        try (ExcelWriter excelWriter = EasyExcel.write(exportFile).build()) {
            WriteSheet writeSheet;
            for (ExportSheetInfo sheetInfo : sheetDataList) {
                writeSheet = EasyExcel.writerSheet(sheetInfo.getSheetName()).head(sheetInfo.getHeadClass()).build();
                excelWriter.write(sheetInfo.getDataList(), writeSheet);
            }
            excelWriter.finish();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 默认读取第一页excel内容
     *
     * @param file
     * @param headClass
     * @param <T>
     * @return 第一页的数据内容
     * @throws IOException
     */
    public static <T> List<T> read(File file, Class<T> headClass) throws IOException {
        ExcelReaderBuilder excelReaderBuilder = EasyExcel.read(new FileInputStream(file), headClass, null);
        excelReaderBuilder.excelType(ExcelTypeEnum.XLSX);
        excelReaderBuilder.autoCloseStream(true);
        return excelReaderBuilder.doReadAllSync();
    }

    /**
     * 读取指定页excel的数据内容
     *
     * @param file
     * @param importSheetInfoList
     * @return 每一页数据内容,map格式
     */
    public static Map<String, List> read(File file, List<ImportSheetInfo> importSheetInfoList) {
        try {
            Map<String, List> excelDataMap = new HashMap<>();
            ExcelReaderBuilder excelReaderBuilder = EasyExcel.read(file);
            for (ImportSheetInfo importSheetInfo : importSheetInfoList) {
                List currentSheetDataList = excelReaderBuilder.sheet(importSheetInfo.getSheetName()).head(importSheetInfo.getHeadClass()).doReadSync();
                excelDataMap.put(importSheetInfo.getSheetName(), currentSheetDataList);
            }
            return excelDataMap;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

}

上边工具针对多Sheet的导入导出封装了特定的对象,代码如下:

package qiyu.framework.excel.config;


/**
 * @Author idea
 * @Date: Created in 10:19 2024/6/23
 * @Description 导入数据使用的参数
 */
public class ImportSheetInfo<T> {

    private String sheetName;
    private Class<T> headClass;

    public String getSheetName() {
        return sheetName;
    }

    public void setSheetName(String sheetName) {
        this.sheetName = sheetName;
    }

    public Class<T> getHeadClass() {
        return headClass;
    }

    public void setHeadClass(Class<T> headClass) {
        this.headClass = headClass;
    }
}
package qiyu.framework.excel.config;

import java.util.List;

/**
 * @Author idea
 * @Date: Created in 10:14 2024/6/23
 * @Description 导出数据使用参数
 */
public class ExportSheetInfo<T> {

    private String sheetName;
    private List<T> dataList;
    private Class<T> headClass;

    public String getSheetName() {
        return sheetName;
    }

    public void setSheetName(String sheetName) {
        this.sheetName = sheetName;
    }

    public List<T> getDataList() {
        return dataList;
    }

    public void setDataList(List<T> dataList) {
        this.dataList = dataList;
    }

    public Class<T> getHeadClass() {
        return headClass;
    }

    public void setHeadClass(Class<T> headClass) {
        this.headClass = headClass;
    }
}

代码测试

接下来我们可以定义一些实体对象,用于测试导出导入的逻辑。下边是我的两个实体对象,分别代表了订单数据和用户数据的含义。实体对象里面的ExcelProperty注解就是导出的excel头部文案,ColumnWidth是该字段的宽度,这两个属性经常会使用到。

package qiyu.framework.excel.model;

import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import lombok.Data;

import java.math.BigDecimal;
import java.util.Date;

/**
 * @Author idea
 * @Date: Created in 21:57 2024/6/22
 * @Description 订单实体对象
 */
@Data
public class OrderModel {

    @ExcelProperty("订单金额")
    private BigDecimal num;

    @ExcelProperty("订单id")
    private String orderId;

    @ExcelProperty("备注")
    @ColumnWidth(50)
    private String remark;

    @ExcelProperty("创建时间")
    @ColumnWidth(50)
    private Date createTime;

    @ExcelProperty("更新时间")
    @ColumnWidth(50)
    private Date updateTime;
}
package qiyu.framework.excel.model;

import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import lombok.Data;

import java.math.BigDecimal;
import java.util.Date;

/**
 * @Author idea
 * @Date: Created in 21:57 2024/6/22
 * @Description 用户实体对象
 */
@Data
public class UserModel {

    @ExcelProperty("用户姓名")
    @ColumnWidth(50)
    private String name;

    @ExcelProperty("性别")
    private Integer sex;

    @ExcelProperty("创建时间")
    @ColumnWidth(50)
    private Date createTime;

    @ExcelProperty("更新时间")
    @ColumnWidth(50)
    private Date updateTime;
}

最后是基于junit4的测试用例代码,大家可以修改导出导入的文件地址方便测试:

package qiyu.framework.excel.test;

import com.alibaba.fastjson.JSON;
import org.junit.Before;
import org.junit.Test;
import qiyu.framework.excel.config.ExportSheetInfo;
import qiyu.framework.excel.config.ImportSheetInfo;
import qiyu.framework.excel.model.OrderModel;
import qiyu.framework.excel.model.UserModel;
import qiyu.framework.excel.service.ExcelExportUtils;

import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;

/**
 * @Author idea
 * @Date: Created in 22:08 2024/6/22
 * @Description
 */
public class TestExcelExportUtilsSuite {


    private List<OrderModel> orderModelList = new ArrayList<>();
    private List<UserModel> userModelList = new ArrayList<>();

    //excel文件的所在目录
    private String exportFilePath = "/Users/tester/IdeaProjects/qiyu-framework-gitee/qiyu-framework/qiyu-framework-excel/src/main/resources";
    //excel文件名
    private String exportFileName = "测试excel导出文件1.xlsx";

    @Before
    public void setUp() {
        for (int i = 0; i < 100; i++) {
            OrderModel orderModel = new OrderModel();
            orderModel.setOrderId(UUID.randomUUID().toString());
            orderModel.setNum(new BigDecimal(i));
            orderModel.setRemark("这是一条备注");
            orderModel.setCreateTime(new Date());
            orderModel.setUpdateTime(new Date());
            orderModelList.add(orderModel);
        }
        for (int i = 0; i < 100; i++) {
            UserModel userModel = new UserModel();
            userModel.setSex(1);
            userModel.setName(UUID.randomUUID().toString());
            userModel.setCreateTime(new Date());
            userModel.setUpdateTime(new Date());
            userModelList.add(userModel);
        }
    }

    @Test
    public void testExport() throws IOException {
        ExportSheetInfo exportSheetInfo = new ExportSheetInfo();
        exportSheetInfo.setSheetName("sheet-1");
        exportSheetInfo.setDataList(orderModelList);
        exportSheetInfo.setHeadClass(OrderModel.class);
        ExcelExportUtils.exportExcel(exportFileName, exportFilePath, exportSheetInfo);
        System.out.println("导出结束");
    }

    @Test
    public void testExcelExport() throws IOException {
        List<ExportSheetInfo> exportSheetInfoList = new ArrayList<>();
        ExportSheetInfo orderSheetInfo = new ExportSheetInfo();
        orderSheetInfo.setSheetName("sheet-1");
        orderSheetInfo.setDataList(orderModelList);
        orderSheetInfo.setHeadClass(OrderModel.class);

        ExportSheetInfo userSheetInfo = new ExportSheetInfo();
        userSheetInfo.setSheetName("sheet-2");
        userSheetInfo.setDataList(userModelList);
        userSheetInfo.setHeadClass(UserModel.class);
        exportSheetInfoList.add(orderSheetInfo);
        exportSheetInfoList.add(userSheetInfo);
        ExcelExportUtils.exportExcel(exportFileName, exportFilePath, exportSheetInfoList);
    }

    @Test
    public void testReadExcel() throws IOException {
        List<OrderModel> orderModels = ExcelExportUtils.read(new File(exportFilePath + "/" + exportFileName), OrderModel.class);
        System.out.println(JSON.toJSONString(orderModels));
    }

    @Test
    public void testMultiSheetReadExcel() {
        List<ImportSheetInfo> importSheetInfoList = new ArrayList<>();
        ImportSheetInfo orderModelSheet = new ImportSheetInfo();
        orderModelSheet.setHeadClass(OrderModel.class);
        orderModelSheet.setSheetName("sheet-1");
        ImportSheetInfo userModelSheet = new ImportSheetInfo();
        userModelSheet.setHeadClass(UserModel.class);
        userModelSheet.setSheetName("sheet-2");

        importSheetInfoList.add(orderModelSheet);
        importSheetInfoList.add(userModelSheet);

        Map<String,List> excelDataResultMap = ExcelExportUtils.read(new File(exportFilePath + "/" + exportFileName), importSheetInfoList);
        System.out.println(JSON.toJSONString(excelDataResultMap));
    }
}

导出文件测试效果:

多sheet导出正常

image.png

指定sheet导入加载正常

image.png

小节

easyexcel还有很多丰富的api,你可以结合复杂的逻辑对excel的样式进行各种调整,这里我只整理了最常用的几种api,以帮助大家提升工作效率。像异步导出,监听器,极速模式这些大家可以到官网再去查询下。

easyexcel官网:easyexcel.opensource.alibaba.com/qa/

原文链接: https://juejin.cn/post/7382979793740431400

文章收集整理于网络,请勿商用,仅供个人学习使用,如有侵权,请联系作者删除,如若转载,请注明出处:http://www.cxyroad.com/17258.html

QR code