EasyExcel的列操作

一、只导出特定的列

案例:只导出员工的序号、员工号、员工姓名和性别信息,其他内容(年龄、生日)不需要输出。

实体类Employee、工具类EmployeeUtils已经准备好:点我查看

导出的Excel文件显示效果如下图所示:

方式一:在实体类属性上添加@ExcelIgnore注解

@ExcelProperty注解一样,@ExcelIgnore注解也是标注在类属性上,这个注解的作用是在导出Excel文件时默认忽略这个列。由于我们不需要输出年龄age和生日birthday两列,只需要在这两个属性上标记上@ExcelIgnore注解即可,实现代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package com.icode504.entity;

import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.*;

import java.util.Date;

/**
* 员工--实体类
*
* @author iCode504
* @date 2024-03-18
*/
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@ToString
public class Employee {

// 序号
@ExcelProperty("序号")
private Integer id;

// 员工号
@ExcelProperty("员工号")
private String employeeId;

// 员工姓名
@ExcelProperty("员工姓名")
private String employeeName;

// 年龄
@ExcelIgnore
@ExcelProperty("年龄")
private Integer age;

// 性别(男/女)
@ExcelProperty("性别")
private String gender;

// 生日
@ExcelIgnore
@ExcelProperty("生日")
private Date birthday;

// 构造器、getter、setter已省略...
}

这里我使用EasyExcel的链式方法导出Excel文件:

1
2
3
4
5
6
7
8
@Test
public void test() {
String filePath = EmployeeUtils.getFilePath();
EasyExcel.write(filePath, Employee.class)
.sheet("测试工作表")
.doWrite(EmployeeUtils.getDataList());
System.out.println("数据成功写出到Excel文件中");
}

导出的Excel文件符合案例的预期:

方式二:调用includeColumnFieldNames方法实现导出特定的列

方式一虽然能实现导出特定的列,但是后续如果我们还要使用年龄age和生日birthday两个属性,还需要将@ExcelIgnore注解去除,这并不是一个好办法。

EasyExcel框架中有一个抽象类AbstractExcelWriterParameterBuilder,这个类提供了includeColumnFieldNames方法,可以传入字符串类型的集合,它的作用是将字符串集合中的数据列输出到Excel文件中。

1
2
3
4
5
6
7
/**
* Only output the custom columns.
*/
public T includeColumnFieldNames(Collection<String> includeColumnFieldNames) {
parameter().setIncludeColumnFieldNames(includeColumnFieldNames);
return self();
}

我们只需要创建一个字符串列表,把导出的数据对应的属性名称存储到这个列表中,然后将这个列表作为参数传入上述方法中。以下是实现代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Test
public void test() {
String filePath = EmployeeUtils.getFilePath();

// 创建一个列表,这个列表中存储要导出的列对应的属性名称
List<String> list = new ArrayList<>();
list.add("id");
list.add("employeeId");
list.add("employeeName");
list.add("gender");

EasyExcel.write(filePath, Employee.class)
// 调用includeColumnFieldNames方法,传入上述的列表
.includeColumnFieldNames(list)
.sheet("测试工作表")
.doWrite(EmployeeUtils.getDataList());

System.out.println("数据成功写出到Excel文件中");
}

输出的Excel文件符合预期:

方式三:调用excludeColumnFieldNames方法实现导出特定的列

和方式二实现方式相反,抽象类AbstractExcelWriterParameterBuilder也提供了excludeColumnFieldNames方法,它也可以传入字符串集合,只不过作用和方式二相反,传入的字符串集合不会输出到Excel文件中。

1
2
3
4
5
6
7
/**
* Ignore the custom columns.
*/
public T excludeColumnFieldNames(Collection<String> excludeColumnFieldNames) {
parameter().setExcludeColumnFieldNames(excludeColumnFieldNames);
return self();
}

创建一个列表,用于存储不导出列对应的属性名称(即年龄age、生日birthday),然后将这个列表作为参数传入到excludeColumnFieldNames方法中,实现代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Test
public void test() {
String filePath = EmployeeUtils.getFilePath();

// 创建一个列表,这个列表中存储不需要导出的列对应的属性名称
List<String> list = new ArrayList<>();
list.add("age");
list.add("birthday");

EasyExcel.write(filePath, Employee.class)
// 调用excludeColumnFieldNames方法,传入上述的列表
.excludeColumnFieldNames(list)
.sheet("测试工作表")
.doWrite(EmployeeUtils.getDataList());

System.out.println("数据成功写出到Excel文件中");
}

输出的Excel文件效果和前两种方式效果相同:

二、将数据导出到Excel文件的特定列

案例:使用EasyExcel实现数据隔列输出(每个数据列之间存在一个空列)

实体类Employee、工具类EmployeeUtils已经准备好:点我查看

导出的Excel文件显示效果如下图所示:

要想实现上述效果,我们对EasyExcel对Excel文件数据列的操作。

Excel文件中,横向(从左到右)是行,竖向(从上到下)是列。如下图所示,由于每一列有自己的名称:列A、列B、列C……

前面我们使用过@ExcelProperty注解,这个注解中有一个属性index,它的默认值是-1,此时列输出的顺序按照Java实体类中属性进行输出;

如果我们在注解中指定了index属性,默认从0开始,以上述表格为例,列A对应的index值是0,列B对应的index值是1,列C对应的index值是2,依次类推。

要想实现案例中的效果,我们需要在@ExcelProperty注解上额外指定index值,“序号”列对应的index值是0,“员工号”列对应的值是2,“姓名”列对应的值是4,以此类推,实体类Employee对应的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package com.icode504.entity;

import com.alibaba.excel.annotation.ExcelProperty;
import lombok.*;

import java.util.Date;

/**
* 员工--实体类
*
* @author iCode504
* @date 2024-03-18
*/
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@ToString
public class Employee {

// 序号
// 由于我们既要输出表头,又要指定输出到特定的列,这里注解对应的属性名必须标记上
@ExcelProperty(value = "序号", index = 0)
private Integer id;

// 员工号
@ExcelProperty(value = "员工号", index = 2)
private String employeeId;

// 员工姓名
@ExcelProperty(value = "员工姓名", index = 4)
private String employeeName;

// 年龄
// @ExcelIgnore
@ExcelProperty(value = "年龄", index = 6)
private Integer age;

// 性别(男/女)
@ExcelProperty(value = "性别", index = 8)
private String gender;

// 生日
// @ExcelIgnore
@ExcelProperty(value = "生日", index = 10)
private Date birthday;

// 构造器、getter、setter已省略...
}

使用EasyExcel输出文件的代码如下:

1
2
3
4
5
6
7
8
9
10
@Test
public void test() {
String filePath = EmployeeUtils.getFilePath();

EasyExcel.write(filePath, Employee.class)
.sheet("测试工作表")
.doWrite(EmployeeUtils.getDataList());

System.out.println("数据成功写出到Excel文件中");
}

执行上述代码,输出的Excel文件符合案例要求:

说明:

  1. 如果你打开Excel文件时,“生日”一栏显示######,只需要将鼠标移动到生日一列,向右拉动即可查看日期信息。
  2. 上图员工号和员工姓名并不是相邻的,向右拉动员工号一列,就会发现员工号和员工姓名二者是隔开的。

三、知识点总结

EasyExcel的列操作的知识点总结如下图所示: