【Spring Boot】IDEA + Maven + Spring Boot + MybatisPlus + EasyExcel

【引言】

之前项目中做导入导出功能,都是集成Apache开源框架 poi,也许我们还遇到过线上数据量过大,导致OOM。 所以,本篇博客使用的是阿里的框架EasyExcel。

【概述】

Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都存在一个严重的问题就是非常的耗内存,poi有一套SAX模式的API可以一定程度的解决一些内存溢出的问题,但POI还是有一些缺陷,比如07版Excel解压缩以及解压后存储都是在内存中完成的,内存消耗依然很大。

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

【使用】

1. 添加EasyExcel依赖,代码如下:

<!--alibaba easyexcel-->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>1.1.2-beta5</version>
</dependency>

2. 定义导出Excel数据集的数据模型,如ArticleWriteModel,代码如下:

/**
 * @Description : 导出文章Excel数据集
 * @Author : huzhiting
 * @Date: 2020-03-24 18:12
 */
@Data
public class ArticleWriteModel extends BaseRowModel {

    @ExcelProperty(value = "编号", index = 0)
    private Long id;

    @ExcelProperty(value = "编码", index = 1)
    private String code;

    @ExcelProperty(value = "标题", index = 2)
    private String title;

    @ExcelProperty(value = "关键字", index = 3)
    private String keywords;

    @ExcelProperty(value = "作者", index = 4)
    private String author;

    @ExcelProperty(value = "发布时间", index = 5)
    private String publishTime;

}

ExayExcel 提供注解的方式, 来方便的定义 Excel 需要的数据模型:

i. 定义的写入模型必须要继承自 BaseRowModel.java;

ii. 通过 @ExcelProperty 注解来指定每个字段的列名称,以及下标位置;

3. 定义导出类,添加导出Excel方法,代码如下:

public class ExportFile {

    private static final int SIZE_OF_PER_SHEET = 100;

    /**
     * 写入Excel,每页sheet默认100条数据,大于则创建新的sheet页
     * @param pathName
     * @param dataInfo
     * @param T
     * @throws Exception
     */
    public void writeExcel(String pathName, List<? extends BaseRowModel> dataInfo,Class<?> T) throws Exception {

        ExcelWriter writer = null;
        // 文件输出位置
        OutputStream out = null;
        try {
            out = new FileOutputStream(pathName);
            writer = EasyExcelFactory.getWriter(out);
            int currentSheet = 1;
            int leftRecords = dataInfo.size();
            do{
                Sheet sheet = createNewSheet(currentSheet,T);
                int fromIndex = (currentSheet - 1) * SIZE_OF_PER_SHEET;
                int toIndex = fromIndex + (leftRecords > SIZE_OF_PER_SHEET ? SIZE_OF_PER_SHEET : leftRecords);
                // 写数据到 Writer 上下文中
                // 入参1: 创建要写入的模型数据
                // 入参2: 要写入的目标 sheet
                writer.write(dataInfo.subList(fromIndex,toIndex), sheet);
                currentSheet ++ ;
                leftRecords-=SIZE_OF_PER_SHEET;
            }while (leftRecords > 0);

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            // 将上下文中的最终 outputStream 写入到指定文件中
            writer.finish();
            // 关闭流
            out.close();
        }
    }

    /**
     * 创建新的sheet页
     * @param currentSheet
     * @param T
     * @return
     */
    private Sheet createNewSheet(int currentSheet, Class T) {
        // 创建新的Sheet
        Sheet sheet = new Sheet(currentSheet, 0, T);
        // sheet 名称
        sheet.setSheetName("Sheet" + currentSheet);
        return sheet;
    }
}

4. 新建测试类,测试导出所有文章到本地指定目录下,代码如下:

@Test
public void testExportArticle() throws Exception {
    List<Article> articleList = articleService.list();
    List<ArticleWriteModel> records = new ArrayList<>();
    if(!CollectionUtils.isEmpty(articleList)){
        articleList.forEach(x -> {
            ArticleWriteModel articleWriteModel = new ArticleWriteModel();
            BeanUtils.copyProperties(x,articleWriteModel);
            articleWriteModel.setPublishTime(LocalDateUtil.formatDate(x.getPublishTime(),"yyyy-MM-dd HH:mm:ss"));
            records.add(articleWriteModel);
        });
    }
    String now = LocalDateUtil.formatDate(LocalDateTime.now(),"yyyyMMddHHmmssSSS");
    String pathName = "F:\\excel\\" + "article" + now + ".xlsx";
    exportFile.writeExcel(pathName,records,ArticleWriteModel.class);
}

测试结果如下:
在这里插入图片描述

完整代码地址:

SpringBoot-MybatisPlus整合EasyExcel

猜你喜欢

转载自blog.csdn.net/u013034223/article/details/105073602