读文件
前言
在网上找了许多文档,大多数都太老了又或者都是互相复制。就连官方的文档也是写的对新手不够友好,因此将学习过程记录下来。
使用环境部署
这个步骤网上绝大部分都没有说,建议先和我使用相同的版本,熟悉后在更换最新版本。
在这里我使用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>
|
导入后的包

一个简单的读取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 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(); readerBuilder.file("C:\\Users\\zy\\Desktop\\Porject\\School-Assignment\\Java\\GetStudentGrades\\src\\resources\\2021学生信息.xlsx"); readerBuilder.sheet("Sheet1"); readerBuilder.autoCloseStream(true); readerBuilder.excelType(ExcelTypeEnum.XLSX); 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(); } }
|
优化代码
由于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) { Set<Integer> keySet = integerStringMap.keySet(); Iterator<Integer> iterator = keySet.iterator(); 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() .registerReadListener(new AnalysisEventListener<Map<Integer, String>>() { @Override public void invoke(Map<Integer, String> integerStringMap, AnalysisContext analysisContext) { list.add(integerStringMap); }
@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
| 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) .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) .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; } }
|