记EasyExcel的初次使用 (生成简单文件和动态表头)

前言

年后回来到三月底一直忙于项目,前段时间才稍微空闲下来。在这个项目中遇到了很多之前没有接触过的东西(虽然不是多高级的东西,但是也算是自己第一次使用),因此打算逐一记录下来,以便以后回看这段时光。

本篇内容主要记录对于EasyExcel的初次使用。

正篇

提到EasyExcel,大多数人都知道是用于生成Excel文件的,而无论是在项目中直接生成还是生成后提供下载,邮件发送等等场景,可以看到首先最重要的就是要生成一个Excel文件。所以,掌握文件的生成至关重要。

EasyExcel简单介绍: EasyExcel是一个基于Java的简单、省内存的读写Excel的开源项目。在尽可能节约内存的情况下,它支持读写百M级别的Excel文件。相较于其他Java领域的Excel解析、生成框架(如Apache POI、jxl等),EasyExcel以其使用简单和节省内存的特点而著称。

(没错,答案来自文心一言,别问我为什么是文心一言,因为不用每次都用登录~)

官方文档地址:easyexcel.opensource.alibaba.com/docs/curren...

Github地址:github.com/alibaba/eas...

使用EasyExcel去生成具体的Excel文件可以有多种方式,下面记录我所用到的几种方式

1、使用注解生成

使用注解生成的方式很简单,根据要生成的文件定义不同的实体,在实体的不同属性上灵活运用相关注解就能达到目的,例如以下的列子:

目标生成文件内容截图

可以看到,表头是姓名,年龄,性别等,而表格里有两条记录。因此,结合官方文档,能够很容易得写出这个生成的代码,根据表头定义Person实体类

Person类

java 复制代码
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person {
    @ExcelProperty("姓名")
    private String name;

    @ExcelProperty("住址")
    private String address;

    @ExcelProperty("性别")
    private String gender;

    @ExcelProperty("年龄")
    private int age;

    @ExcelProperty("工作单位")
    private String workPlace;
}  

上述代码可以看到每一个属性上面都有一个@ExcelProperty注解,结合表格的内容,可以看到注解的属性就是我们的表头的值

那么,如何结合这个生成一个文件呢,示例代码如下

java 复制代码
public static void main(String[] args) {

    String fileName = "demoExcel.xlsx";
    EasyExcel.write(fileName, Person.class)
            .sheet()
            .doWrite(getPersonInfo());
}

public static List<Person> getPersonInfo() {
    List<Person> personList = Lists.newArrayList();
    Person person1 = new Person();
    person1.setName("张三");
    person1.setAge(23);
    person1.setGender("男");
    person1.setAddress("中国北京市");
    person1.setWorkPlace("保密单位");
    personList.add(person1);

    Person person2 = new Person();
    person2.setName("李四");
    person2.setAge(28);
    person2.setGender("男");
    person2.setAddress("中国上海市");
    person2.setWorkPlace("互联网公司");
    personList.add(person2);

    return personList;
}

生成效果如下:

当然,你会发现这里的表头样式和宽度等等都和最开始的模板不一致,这是因为EasyExcel在生产表头时有默认的规则和宽度,我们可以使用相关组件或内容去修改这些内容,例如,我们可以使用@ColumnWidth注解来指定当前表头所在的列的宽度是多少,例如:

java 复制代码
@ExcelProperty("工作单位")
@ColumnWidth(15)
private String workPlace;

可以看到,最后一列的宽度得到了改变。什么?你发现列的顺序与模板的不一致 ,很好办,调整实体类的顺序就可以了。

这个时候有的人可能就会问到我已经有一个Person类了, 但是我里面有一些其他属性,在文件模板中又不想展示这个字段应该怎么办? 这点EasyExcel已经替我们想到了,使用@ExcelIgnore注解,该注解的作用就是在文件生成head(表头)的时候忽略该字段,不进行填充,例如在Person类中新增了一个属性salary,你会发现,如果我们不标记任何注解,那么生成出来的内容是下面这个

而我们又不想标识出来薪水,因此可以使用@ExcelIgnore注解来实现,例如

java 复制代码
@ExcelIgnore
private String salary;

效果如下

好了,到这里,就介绍了简单形式的Excel的文件生成,当然,这里生成的是xlsx格式,我们也可以使用EasyExcel提供的ExcelTypeEnum来生产多种格式的文件,例如csv。只是文件格式不同,而根本上的生成文件的方式则是相同的

java 复制代码
EasyExcel.write(fileName, Person.class).excelType(ExcelTypeEnum.CSV)
        .sheet()
        .doWrite(getPersonInfo());

2、动态表头生成

上面的内容提到过,如果我已经有一个实体类了,里面有一些字段能满足我目标生产文件的表头要求,但是有一些不需要,同时我也不能使用@ExcelIgnore注解,因为有其他场景也需要用到这些字段。

举个具体的例子,对于Person类,A场景需要使用到name,address,gender字段,而B场景需要用到name,age,wordPlace字段,因此不能简单的将不需要的字段标记@ExcelIgnore字段。这个时候可能有人想到的是那我多定义几个实体类,在生成文件时用不同的实体类去映射就行了,这么做固然可行,但是场景少还行,如果场景多,需要使用到的字段又比较零散,那么通过这种方式就要定义很多实体类,维护起来很麻烦,这个时候可以用到动态生成表头,下面是一个简单的示例

java 复制代码
public static void main(String[] args) {
    String fileAName = System.currentTimeMillis() + "demoAExcel.xlsx" ;
    String fileBName = System.currentTimeMillis() + "demoBExcel.xlsx" ;
    // 定义场景A所需要的表头
    List<List<String>> headsA = Lists.newArrayList();
    List<String> columnsA1 = Lists.newArrayList("姓名");
    List<String> columnsA2 = Lists.newArrayList("住址");
    List<String> columnsA3 = Lists.newArrayList("性别");
    headsA.add(columnsA1);
    headsA.add(columnsA2);
    headsA.add(columnsA3);

    // 定义场景B所需要的表头
    List<List<String>> headsB = Lists.newArrayList();
    List<String> columnsB1 = Lists.newArrayList("姓名");
    List<String> columnsB2 = Lists.newArrayList("年龄");
    List<String> columnsB3 = Lists.newArrayList("工作单位");
    headsB.add(columnsB1);
    headsB.add(columnsB2);
    headsB.add(columnsB3);

    // 构造场景A所需要的数据
    List<List<String>> dataA = Lists.newArrayList();
    List<String> rowA1 = Lists.newArrayList("张三", "中国北京市", "男");
    List<String> rowA2 = Lists.newArrayList("李四", "中国上海市", "男");
    dataA.add(rowA1);
    dataA.add(rowA2);

    // 构造场景B所需要的数据
    List<List<String>> dataB = Lists.newArrayList();
    List<String> rowB1 = Lists.newArrayList("张三", "23", "保密单位");
    List<String> rowB2 = Lists.newArrayList("李四", "28", "互联网公司");
    dataB.add(rowB1);
    dataB.add(rowB2);

    // 生成场景A的文件
    EasyExcel.write(fileAName).sheet().head(headsA).doWrite(dataA);
    // 生成场景B的文件
    EasyExcel.write(fileBName).sheet().head(headsB).doWrite(dataB);
}

下面是两个场景的输出结果

A场景:

B场景:

可以看到根据不同的条件我们生成了不同的文件,避免了因过多创建不同的实体类而带来的维护问题。 当然这只是一个例子,真实使用中,我们需要通过待组装的列去对实体类进行反射,拿到具体的value,在组装成文件。

结尾

上述内容其实也不算复杂,只是由于本人第一次使用EasyExcel去完成某个具体的需求,因此记录下来当时的想法,并且也没有用到EasyExcel中多复杂的功能,希望能给那些第一次使用EasyExcel的朋友一点经验 。也希望能看到本文章的大佬给一些指导建议,不胜感激!

后续会再整理一篇文章,用于记录使用EasyExcel来生成多sheet,稍微复杂点的文件。

不积跬步,无以至千里,不积小流,无以成江海。

相关推荐
2201_757830877 分钟前
条件分页查询
java·开发语言
重生之我是Java开发战士12 分钟前
【数据结构】Java对象的比较
java·jvm·数据结构
橘子1318 分钟前
Linux线程——一些概念(七)
java·redis·缓存
magic_kid_201022 分钟前
IDEA 复制到 Windows 远程桌面失败的原因与解决方案
java·ide·intellij-idea
风月歌24 分钟前
基于微信小程序的学习资料销售平台源代码(源码+文档+数据库)
java·数据库·mysql·微信小程序·小程序·毕业设计·源码
巴拉巴拉~~27 分钟前
KMP 算法通用步进器组件:KmpStepperWidget 横向 / 纵向 + 匹配进度 + 全样式自定义
java·服务器·开发语言
贺今宵28 分钟前
使用idea启动一个springboot项目
java·ide·intellij-idea
AAA简单玩转程序设计35 分钟前
Java传参还在瞎传?这3个进阶基础技巧少走1年弯路
java
伍一5140 分钟前
芋道框架下的进销存升级(三):Yudao-ERP2异步导出/导入Excel的设计与实现
java·excel·异步导出excel
胡闹5440 分钟前
【EasyExcel】字段赋值错乱问题
java·开发语言