抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

读文件

前言

在网上找了许多文档,大多数都太老了又或者都是互相复制。就连官方的文档也是写的对新手不够友好,因此将学习过程记录下来。

使用环境部署

这个步骤网上绝大部分都没有说,建议先和我使用相同的版本,熟悉后在更换最新版本。
在这里我使用maven管理器来管理包。

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
// pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>org.example</groupId>
<artifactId>easyExcelDemo</artifactId>
<version>1.0-SNAPSHOT</version>

<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
<dependencies>
<!--关键加上这两个包开始-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-simple</artifactId>
  <version>1.7.25</version>
  <scope>compile</scope>
</dependency>
<!--关键加上这两个包结束-->
</dependencies>
</project>

导入后的包
博客EasyExcel导入库

一个简单的读取Excel文件

新建ExcelReaderBuilder读取流

1
ExcelReaderBuilder readerBuilder = EasyExcel.read();

给文件流传入Excel路径或者File对象

1
2
3
readerBuilder.file("C:\\***\\2021学生信息.xlsx");
// 或
readerBuilder.file(new File("C:\\***.xlsx"));

指定sheet名字,或者下标

1
readerBuilder.sheet("Sheet1");

为了节省内存,在这里应该加上自动关闭文件流

1
readerBuilder.autoCloseStream(true);

因为Excel有多个版本,需要指定版本

1
readerBuilder.excelType(ExcelTypeEnum.XLSX);

到了这里,已经将Excel配置到了。接下来我们来监听读取文件流。
registerReadListener会一行一行的回调到invoke函数,只要调用返回的参数即可。读取完全部文件后会调用doAfterAllAnalysed

1
2
3
4
5
6
7
8
9
10
11
12
13
readerBuilder.registerReadListener(new AnalysisEventListener() {
@Override
public void invoke(Object o, AnalysisContext analysisContext) {
// 读完一行的回调函数操作
System.out.println(o);
}

@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
// 读完所有的数据后的回调函数操作
System.out.println("读完所有的数据后的回调函数操作");
}
});

到了这里,其实还不能读取到数据,因为该工作流并没有启动,我们需要构建读取器。

1
2
ExcelReader reader = readerBuilder.build();
// 构建读取器

再启动,读取全部数据

1
2
reader.readAll();
// 读取全部数据

关闭读取器

1
2
reader.finish();
// 关闭读取器

全部代码

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
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.read.builder.ExcelReaderBuilder;
import com.alibaba.excel.support.ExcelTypeEnum;

import java.io.File;

public class Test {
public static void main(String[] args) {
ExcelReaderBuilder readerBuilder = EasyExcel.read();
// 创建一个 ExcelReader 对象
readerBuilder.file("C:\\Users\\zy\\Desktop\\Porject\\School-Assignment\\Java\\GetStudentGrades\\src\\resources\\2021学生信息.xlsx");
// 获取文件对象
readerBuilder.sheet("Sheet1");
// 指定sheet名称
readerBuilder.autoCloseStream(true);
// 自动关闭流
readerBuilder.excelType(ExcelTypeEnum.XLSX);
// 设置excel类型
readerBuilder.registerReadListener(new AnalysisEventListener() {
@Override
public void invoke(Object o, AnalysisContext analysisContext) {
// 读完一行的回调函数操作
System.out.println(o);
}

@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
// 读完所有的数据后的回调函数操作
System.out.println("读完所有的数据后的回调函数操作");
}
});
ExcelReader reader = readerBuilder.build();
// 构建读取器
reader.readAll();
// 读取全部数据
reader.finish();
// 关闭读取器fanxing
}
}

优化代码

由于invoke回调函数默认传入的Object对象,在这里建议使用泛型来限定类型,重写readerBuilder.registerReadListener方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
readerBuilder.registerReadListener(new AnalysisEventListener<Map<Integer, String>>() {
// 将接口的泛型指定为实体类型
@Override
public void invoke(Map<Integer, String> integerStringMap, AnalysisContext analysisContext) {
// 指定传入的实体类型为Map<Integer, String>
Set<Integer> keySet = integerStringMap.keySet();
// 获取map的key
Iterator<Integer> iterator = keySet.iterator();
// 获取map的key的迭代器
while (iterator.hasNext()) {
Integer next = iterator.next();
System.out.println(next + ":" + integerStringMap.get(next));
}
}

@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
...
}
});

简化代码

以上的代码是该类的正常写法,但是显得过于繁重,应此可以向下面那样简化代码。

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
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;

import java.util.*;

public class Test2 {
public static void main(String[] args) {
List<Map<Integer, String>> list = new LinkedList<>();
// 定义一个集合来接收解析出来的数据
EasyExcel.read("C:\\Users\\zy\\Desktop\\Porject\\School-Assignment\\Java\\GetStudentGrades\\src\\resources\\2021学生信息.xlsx")
.sheet()
// 指定读取的sheet,不写则读全部
.registerReadListener(new AnalysisEventListener<Map<Integer, String>>() {
@Override
public void invoke(Map<Integer, String> integerStringMap, AnalysisContext analysisContext) {
list.add(integerStringMap);
// 指定传入的实体类型为Map<Integer, String>
}

@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
System.out.println("读完所有的数据了");
}
}).doRead();
for (Map<Integer, String> map : list) {
Set<Integer> keySet = map.keySet();
Iterator<Integer> iterator = keySet.iterator();
while (iterator.hasNext()) {
Integer next = iterator.next();
System.out.println(next + ":" + map.get(next));
}
}
}
}

使用ExcelProperty注解

我们可以使用该注解来限制对象的属性对应的列

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;

@Data
@Getter
@Setter
public class ExcelData {
@ExcelProperty(value = "姓名")
// 此注解可以指定读取的列
private String name;
@ExcelProperty(value = "班级")
private String className;
}

自定义一个对象来存储Excel

现在,已经掌握了大部分的方法,话不多说直接上代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// ExcelData
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;

@Data
@Getter
@Setter
public class ExcelData {
@ExcelProperty(value = "姓名")
// 此注解可以指定读取的列
private String name;
@ExcelProperty(value = "班级")
private String className;
}
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
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;

import java.util.*;

public class Test2 {
public static void main(String[] args) {
List<ExcelData> list = new LinkedList<>();
// 定义一个集合来接收解析出来的数据
EasyExcel.read("C:\\Users\\zy\\Desktop\\Porject\\School-Assignment\\Java\\GetStudentGrades\\src\\resources\\2021学生信息.xlsx")
.head(ExcelData.class)
// 根据指定的实体类去解析Excel转为LinkedHashMap
.sheet()
// 指定读取的sheet,不写则读全部
.registerReadListener(new AnalysisEventListener<ExcelData>() {
@Override
public void invoke(ExcelData excelData, AnalysisContext analysisContext) {
list.add(excelData);
}

@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
System.out.println("读完所有的数据了");
}
}).doRead();
for (ExcelData excelData : list) {
System.out.println(excelData);
}
}
}

写文件

使用EasyExcel.write()来写入文件。

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
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.support.ExcelTypeEnum;

import java.util.*;

public class Test2 {
public static void main(String[] args) {
List<ExcelData> dataList = parseData();
// 读取的数据,拿来写
EasyExcel.write("E:\\测试写入副本.xlsx")
.head(ExcelData.class)
.excelType(ExcelTypeEnum.XLSX)
.sheet("测试表")
.doWrite(dataList);
}

/* 将读取的数据再次利用来写文件 */
public static List<ExcelData> parseData(){
List<ExcelData> list = new LinkedList<>();
// 定义一个集合来接收解析出来的数据
EasyExcel.read("C:\\Users\\zy\\Desktop\\Porject\\School-Assignment\\Java\\GetStudentGrades\\src\\resources\\2021学生信息.xlsx")
.head(ExcelData.class)
// 根据指定的实体类去解析Excel转为LinkedHashMap
.sheet()
// 指定读取的sheet,不写则读全部
.registerReadListener(new AnalysisEventListener<ExcelData>() {
@Override
public void invoke(ExcelData excelData, AnalysisContext analysisContext) {
list.add(excelData);
}

@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
System.out.println("读完所有的数据了");
}
}).doRead();
return list;
}
}

评论




站点访问量 Loading… 站点访客数 Loading…