相信小伙伴们在编写项目时需要对大量数据进行数据统一时不知怎么办才好,而将数据导出转为Excel文件则方便许多,也可以将数据以列表的形式展示出来方便阅读和操作,接下来小鱼就带着小伙伴们走进Java中如何将数据转换为Excel文件以及读取Excel文件。
转换成Excel文件的的方式有很多,为什么要使用EasyExcel呢?
java中解析excel的框架有很多种,如poi、jxl等,但是都存在一个问题,非常的消耗内存,
而使用EasyExcel即使遇到再大的Excel使用解压缩的方式也不会出现内存溢出现象,再读取Excel文件时是一行一行的读取,做业务处理时也更加灵敏,使用起来也非常的方便。
接下来就来看看怎么使用吧~
首先我们需要导入阿里的依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.3.1</version>
</dependency>
定义需要导入、导出的实体类,添加对应的注解,小鱼这里并没有将get、set、toString等方法写上去,小伙伴们别忘了要写哦
其中注解HeadRowHeight()定义的是Excel中单个单元表格的行高,ColumnWidth()定义的是行宽,为每个属性添加注解ExcelProperty(index = xxx, value = xxx),第一个参数是每个属性在表格中表头的顺序,也是索引,第二个参数是每个属性在表格中表头的名字,如果不定义则默认为属性名
//行高
@HeadRowHeight(15)
//行宽
@ColumnWidth(20)
public class User implements Serializable {
// 每列名称,不写默认为数据名 id、name、age...
@ExcelProperty(index = 0, value = "编号")
private Integer id;
@ExcelProperty(index = 1, value = "名称")
private String name;
@ExcelProperty(index = 2, value = "年龄")
private Integer age;
@ExcelProperty(index = 3, value = "性别")
private String sex;
}
@HeadRowHeight(20)
@ColumnWidth(20)
public class Book implements Serializable {
@ExcelProperty(index = 0)
private String name;
@ExcelProperty(index = 1)
private String author;
}
接下来就可以直接操作Excel文件的导出操作了,小鱼先定义了一个Service来模拟获取到多条数据的场景,代码如下
@Service
public class UserServiceImpl implements UserService {
@Override
public List<User> getAllUer() {
List<User> list = new ArrayList<>();
for (int i = 0; i < 20; i++) {
User user = new User();
user.setId(i+1);
user.setName("aaa" + i);
user.setAge(20 + i);
user.setSex("男");
list.add(user);
}
return list;
}
@Override
public List<Book> getAllBook() {
List<Book> list = new ArrayList<>();
for (int i = 0; i < 20; i++) {
Book book = new Book();
book.setName("qqq");
book.setAuthor("wwww");
list.add(book);
}
return list;
}
}
注意,每次进行完excel的读和写操作之后需要手动关闭finish(),在每次操作是会创建临时文件,需要通过finish()进行关闭,否则会导致磁盘崩溃。
一、Excel文件的导出
1.数据的单表导出
首先创建ExcelWriter 对象,第一个参数表示将文件导出到那个磁盘哪个位置,第二个参数对应数据的Class,创建表格WriteSheet,writerSheet()的参数是表格名,excelWriter.write(users,sheet)两个参数分别是写入的数据和数据写入的表,代码如下
@Test
void test() {
String path ="D:\\a\\user.xls";
ExcelWriter excelWriter = EasyExcel.write(path, User.class).build();
List<User> users = userService.getAllUer();
//writerSheet两个参数一个是表id顺序一个是表名
WriteSheet sheet = EasyExcel.writerSheet("用户信息").build();
excelWriter.write(users,sheet);
excelWriter.finish();
System.out.println("导出数据成功");
}
单表导出的简化格式
@Test
void test() {
String path ="D:\\a\\user2.xls";
EasyExcel.write(path, User.class).sheet("用户表").doWrite(userService.getAllUer());
System.out.println("导入成功");
}
2.多个数据的多表导出
和单表的导出类似,创建ExcelWriter时只需导出的文件路径即可,在创建WriteSheet时需要数据的Class。
@Test
void test(){
String path ="D:\\a\\list.xls";
ExcelWriter excelWriter = EasyExcel.write(path).build();
List<User> users = userService.getAllUer();
List<Book> books = userService.getAllBook();
WriteSheet sheet1 = EasyExcel.writerSheet("书籍信息").head(Book.class).build();
WriteSheet sheet2 = EasyExcel.writerSheet("用户信息").head(User.class).build();
excelWriter.write(books,sheet1);
excelWriter.write(users,sheet2);
excelWriter.finish();
System.out.println("导出数据成功");
}
二、Excel文件的导入
Excel文件的导入需要自定义监听器,继承AnalysisEventListener类,AnalysisEventListener类是ReadListener的实现类,ReadListener如下
public interface ReadListener<T> extends Listener {
//当监听器器出现异常时,会将异常在此抛出,并终止读取操作
default void onException(Exception exception, AnalysisContext context) throws Exception {
throw exception;
}
//读取 Excel 表头信息
default void invokeHead(Map<Integer, ReadCellData<?>> headMap, AnalysisContext context) {}
//逐行读取 Excel 表信息
void invoke(T data, AnalysisContext context);
//返回额外信息时,调用该方法
default void extra(CellExtra extra, AnalysisContext context) {}
//读取数据完后自动执行的方法
void doAfterAllAnalysed(AnalysisContext context);
//下一行是否还有数据
default boolean hasNext(AnalysisContext context) {
return true;
}
}
一般使用invoke()方法和doAfterAllAnalysed()方法就够了
1.监听器的编写
监听器里需要定义一个集合来接收从表中逐行读取的数据,方便之后的操作。自定义监听器如下
//Excel监听器
public class ExcelListener extends AnalysisEventListener<T> {
//将逐行读取出的数据封装到list中
List<T> list = new ArrayList<>();
// 逐行读取 excel 信息
@Override
public void invoke(T t, AnalysisContext analysisContext) {
list.add(t);
}
//读取 excel 表头信息
@Override
public void invokeHead(Map headMap, AnalysisContext context) {
System.out.println("表头信息:" + headMap);
}
//读取数据完毕后执行的方法
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
for (T t: list) {
System.out.println("T = " + t);
}
}
}
2.Excel单表读取
创建ExcelReader对象,与 ExcelWriter不同的时还需要一个监听器对象ExcelListener,接着通过文件执行器获取表sheetList,获取到表名之后调用EasyExcel.readSheet()方法获取表ReadSheet,代码如下
@Test
void test(){
String path ="D:\\a\\user.xls";
ExcelReader excelReader = EasyExcel.read(path, User.class, new ExcelListener()).build();
// excelExecutor() Excel 文件执行器
List<ReadSheet> sheetList = excelReader.excelExecutor().sheetList();
for (ReadSheet sheet: sheetList) {
//获取表名
String sheetName = sheet.getSheetName();
System.out.println(sheetName);
ReadSheet readSheet = EasyExcel.readSheet(sheetName).build();
//开始执行监听器
excelReader.read(readSheet);
}
excelReader.finish();
System.out.println("执行成功");
}
单表读取的简化格式
@Test
void test(){
String path ="D:\\a\\user.xls";
EasyExcel.read(path, User.class,new ExcelListener()).sheet().doRead();
}
3.Excel多表读取
多表读取与单表读取一样,只是需要创建多个监听器
@Test
void test() {
String path ="D:\\a\\list.xls";
ExcelReader excelReader = EasyExcel.read(path).build();
//创建多个监听器
ExcelListener listener01 = new ExcelListener();
ExcelListener listener02 = new ExcelListener();
//registerReadListener() 调用自定义监听器
ReadSheet readSheet1 = EasyExcel.readSheet(0).registerReadListener(listener01).build();
ReadSheet readSheet2 = EasyExcel.readSheet(1).registerReadListener(listener02).build();
//读取多个 sheet 表,否则03版的Excel会读取多次,浪费性能
excelReader.read(readSheet1,readSheet2);
//读的时候会创建临时文件,不关闭到时磁盘会崩的
excelReader.finish();
}
三、总结
以上便是EasyExcel的一些简单基本操作,在读取文件时可以在逐行读取数据时进行一些业务操作,也可在读取完所有数据后进行业务操作,当然,以上只是很简单的操作,还有很多操作像获取表中某一行某一列的数据、向表中添加图片这些操作小鱼并没有提到,希望这篇文章能够帮助到小伙伴们!