EasyExcel的使用

EasyExcel的使用

一、EasyExcel

传统Excel操作或者解析都是利用Apach POI进行操作,但是使用过这个框架的人都知道,这个框架并不完美,有较多的缺陷:

  • 使用步骤繁琐
  • 动态写出Excel操作非常麻烦
  • 对于新手来说,很难在短时间内上手
  • 读写时需要占用较大的内容,当数据量大时容器发生OOM

注:OOM (Out Of Menmory Error): 内存不足错误

基于上述原因,阿里开源出一款易上手,且比较节省内存的Excel操作框架:EasyExcel

官方文档

1.1 对比Apach POI

  • Apach POI

    当利用Apach POI去读取Excel文件时,首先先将数据全部加载到内存当中(**主要原因**),然后返回给调用者,当数据量比较大的时候,就会发生OOM

  • EasyExcel

    当利用EasyExcel进行转换的时候,主要是采用SAX模式,进行一行一行解析,并且将每一行的解析结果以行为单位用观察者模式通知处理,所以即使数据量比较大的时候也不会发生``OOM`

1.2 写操作

准备工作

添加maven依赖

<!-- 阿里 EasyExcel依赖 -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>2.2.7</version>
</dependency>
1.2.1 写入操作
/**
 * Created by IntelliJ IDEA.
 * User: LvHaoIT (asus)
 * Date: 2022/1/21
 * Time: 13:33
 */
@Data
@TableName("WBCX_APPLYSOURCE")
@ApiModel(value = "WBCX_APPLYSOURCE扫描单次记录表", description = "WBCX_APPLYSOURCE扫描单次记录表")
public class SingleOneScan implements Serializable {

    @TableId(type = IdType.AUTO)
    @ApiModelProperty(value = "id")
    private Integer id;

    @ApiModelProperty(value = "类别 二维码0 数据包1")
    private int orCategory;

    @ApiModelProperty(value = "当前页")
    private int nowPage;

    @ApiModelProperty(value = "总共页数")
    private int pageCount;

    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd hh:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd hh:mm:ss")
    @ApiModelProperty(value = "添加时间")
    private Date scanTime;

    @ApiModelProperty(value = "添加人id")
    private String userId;

    @ApiModelProperty(value = "添加人姓名")
    private String userName;
}

生成Excel方法 ,通过使用EasyExcel这个工具类,可以完成操作

public List<SingleOneScan> getData() {
    List<SingleOneScan> list = new ArrayList<>();
    for(int i = 0; i <= 10; i++) {
       SingleOneScan singleOneScan = new SingleOneScan();
       singleOneScan.setId(i + 1);
        singleOneScan.setUserName("张三");
		//.... 添加数据,动态数据这里增加即可
        list.add(singleOneScan);
    }
    return list;
}

 EasyExcel.write("单次扫描表.xlsx", SingleOneScan.class).sheet().doWrite(getData());


如下

在这里插入图片描述

  • 代码解释

  • EasyExcel.write("单次扫描表.xlsx", SingleOneScan.class)

    EasyExcel.write表示创建一个Excel写对象,两个参数

    • 第一个参数:写出表格的文件名
    • 写出到表格数据类型的class对象
  • 观察源码

    public class EasyExcelFactory {
        /**
         * 构建一个Excel写对象
         *
         * @return
         */
        public static ExcelWriterBuilder write() {
            return new ExcelWriterBuilder();
        }
    
        /**
         * 构建一个Excel写对象
         *
         * @param file 用来写出文件对象
         *            
         * @return Excel writer builder
         */
        public static ExcelWriterBuilder write(File file) {
            return write(file, null);
        }
    
        /**
         * 构建 Excel写对象
         *
         * @param file
         *           用来写出的文件对象
         * @param head
         *          写出的数据类型的class对象
         * @return Excel writer builder
         */
        public static ExcelWriterBuilder write(File file, Class head) {
            ExcelWriterBuilder excelWriterBuilder = new ExcelWriterBuilder();
            excelWriterBuilder.file(file);
            if (head != null) {
                excelWriterBuilder.head(head);
            }
            return excelWriterBuilder;
        }
    
        /**
         * 构建Excel 写对象
         *   
         * @param pathName
         *           写出的文件路径名
         * @return Excel writer builder
         */
        public static ExcelWriterBuilder write(String pathName) {
            return write(pathName, null);
        }
    
        /**
         * 构建excel 写对象
         *
         * @param pathName
         *            写出的文件路径名
         * @param head
         *            写出数据的数据类型的class对象
         * @return Excel writer builder
         */
        public static ExcelWriterBuilder write(String pathName, Class head) {
            ExcelWriterBuilder excelWriterBuilder = new ExcelWriterBuilder();
            excelWriterBuilder.file(pathName);
            if (head != null) {
                excelWriterBuilder.head(head);
            }
            return excelWriterBuilder;
        }
    
        /**
         * 构建excel写对象
         *
         * @param outputStream
         *            写出的输出流对象
         * @return Excel writer builder
         */
        public static ExcelWriterBuilder write(OutputStream outputStream) {
            return write(outputStream, null);
        }
    
        /**
         * 构建excel写对象
         *
         * @param outputStream
         *           写出的输出流
         * @param head
         *           写出数据的数据类型的class对象
         * @return Excel writer builder
         */
        public static ExcelWriterBuilder write(OutputStream outputStream, Class head) {
            ExcelWriterBuilder excelWriterBuilder = new ExcelWriterBuilder();
            excelWriterBuilder.file(outputStream);
            if (head != null) {
                excelWriterBuilder.head(head);
            }
            return excelWriterBuilder;
        }
    }
    
    • 多种创建方式,可考虑具体使用情况
  • sheet() 表示需要在 Excel 的哪一个 sheet(页) 里面写入数据,如果不指定,默认在第一个sheet页写入数据,值为0

  • 观察源码

    public class ExcelWriterBuilder extends AbstractExcelWriterParameterBuilder<ExcelWriterBuilder, WriteWorkbook> {
      
        /*
            选中第一个sheet页
            写操作 sheet 页的值为 0
        */
        public ExcelWriterSheetBuilder sheet() {
            return sheet(null, null);
        }
    
        /*
            选中 第一个的 sheet页
            sheet 页的名字 为 sheetNo
        */  
        public ExcelWriterSheetBuilder sheet(Integer sheetNo) {
            return sheet(sheetNo, null);
        }
    
        /*
            选中第一个的 sheet页
            sheet 页的名字 为 sheetName
        */  
        public ExcelWriterSheetBuilder sheet(String sheetName) {
            return sheet(null, sheetName);
        }
    
        /*
            选中第一个 sheet页
            sheet 页的名字 为 sheetNo 或者 sheetName
        */
        public ExcelWriterSheetBuilder sheet(Integer sheetNo, String sheetName) {
            ExcelWriter excelWriter = build();
            ExcelWriterSheetBuilder excelWriterSheetBuilder = new ExcelWriterSheetBuilder(excelWriter);
            if (sheetNo != null) {
                excelWriterSheetBuilder.sheetNo(sheetNo);
            }
            if (sheetName != null) {
                excelWriterSheetBuilder.sheetName(sheetName);
            }
            return excelWriterSheetBuilder;
        }
    }
    

    可以看到可以写入两个参数,指定 页的名称

  • doWrite表示需要写出的数据,写出的数据为一个List集合

1.2.2 复杂写入
  • 自定义表头

    之前不做设置的情况下,表头均为属性名称,并且排列的顺序为类中属性排列顺序,但是实际需求中,表头为自定义信息,并且顺序也不一定按照属性的顺序来

  • 利用注解来自定义表头@ExcelProperty

    	@ExcelProperty("自定义表头名称")
        private int orCategory;
    
  • 自定义排列顺序 order的值越大,表项越往右边

    	@ExcelProperty(value="自定义表头名称",order = 10)
        private int orCategory;
    
  • 多级表头

    	@ExcelProperty(value={"自定义表头名称1","子表头1"})
        private int orCategory;
    
    	@ExcelProperty(value={"自定义表头名称1","子表头2"})
        private int count;
    

    如图

    在这里插入图片描述

  • 设置单元格宽高

  • 1.统一设置(简单,但是宽度不美观)

    @HeadRowHeight(value = 35) // 表头行高
    @ContentRowHeight(value = 25) // 内容行高
    @ColumnWidth(value = 50) // 列宽
    public class User{
        //...
    }
    
  • 2.设置自适应宽度

    //1.去掉列宽注解
    @HeadRowHeight(value = 35) // 表头行高
    @ContentRowHeight(value = 25) // 内容行高
    public class User{
        //...
    }
    
    //2.修改生成代码
     EasyExcel.write("单次扫描表.xlsx", SingleOneScan.class)
    //自适应宽度
    .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
         .sheet().doWrite(getData());
    
  • 生成表项**日期格式化 ** @DateTimeForMat(yyyy-MM-dd)

  •    @com.alibaba.excel.annotation.format.DateTimeFormat
        private Date applyDateEnd;
    

    区分spring框架中提供的DateTimeFormat

  • 忽略写入表项 @ExcelIgnore

    可以把不需要生成的表项进行忽略

        @ExcelIgnore
        private Date applyDateEnd;
    
  • 指定写入 .includeColumnFiledNames(set)

  • 这种方式可以在忽视注解的情况下,指定需要哪些表项进行生成。

    //1.创建一个hashSet 里面存放需要导出列的属性名称
    //必须要和类中的属性名称相同
        Set<String> set = new HashSet<>();
        set.add("id");
        set.add("userName");
    
    //2.在生成的时候增加.includeColumnFiledNames(set)
     EasyExcel.write("单次扫描表.xlsx", SingleOneScan.class)
    //指定写入
    .includeColumnFiledNames(set) 
    //自适应宽度
    .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
         .sheet().doWrite(getData());
    

1.3 读操作

简介:读取在实际开发中也占据了较大地位,但是读取并不是读取任意的一个Excel文件,而是读取按照事先提供好的Excel模板,用户在模块版上修改数据的Excel

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LvhaoIT

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值