目录
Easy Excel
所需依赖
准备一个excel文件
对excel的读取
创建对应的实体类
创建EasyExcelUtil类
修改实体类
对excel的写入
在EasyExcelUtil类中加入写方法
对excel的填充
在EasyExcelUtil类中加入填充方法
整合为工具类
EasyExcel是一个基于Java的、快速、简洁、解决大文件内存溢出的Excel处理工具。
他能让你在不用考虑性能、内存的等因素的情况下,快速完成Excel的读、写等功能。
org.springframework.boot
spring-boot-starter
org.springframework.boot
spring-boot-starter-test
test
org.projectlombok
lombok
1.18.24
provided
com.alibaba
easyexcel
2.1.6
org.slf4j
slf4j-log4j12
1.7.30
内容如下:
id | 姓名 | 年龄 |
1 | 小明 | 12 |
2 | 小红 | 13 |
3 | 小刚 | 13 |
4 | 小美 | 11 |
5 | 小智 | 10 |
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private String id;
private String name;
private Integer age;
}
如果没有导入lombok依赖需要手动加入get,set方法和构造方法
package com.li.utils;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.SyncReadListener;
import com.li.pojo.DemoData;
import com.li.pojo.User;
import java.util.ArrayList;
import java.util.List;
public class EasyExcelUtil {
public static void main(String[] args) {
EasyExcelUtil.read1();
}
private static void read1() {
final List list = new ArrayList();
//使用EasyExcel读取test1.xlsx文件
EasyExcel.read("C:\\Users\\lenovo\\Desktop\\user.xlsx", User.class, new SyncReadListener() {
//EasyExcel在读取excel表格时,每读取到一行,就会调用一次这个方法,
//并且将读取到的行数据,封装到指定类型(User)的对象中,传递给我们(Object object)
/*
此问题可能出现在低版本的easyExcel中,出现时可以按照下列方式解决
如果表格数据不是顶行写的,需要通过headRowNumber指定表头行的数量
如果表格数据不是顶列写的,需要在封装的实体属性上通过@ExcelProperty将实体属性和表格列名进行对应
*/
@Override
public void invoke(Object object, AnalysisContext context) {
System.out.println(object);
list.add(object);
}
}).doReadAll();
//获取读取到的数据
for (Object object : list) {
User user = (User) object;
System.out.println(user);
}
}
}
运行main后效果如下:
添加一个方法后再次运行
package com.li.utils;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.event.SyncReadListener;
import com.li.pojo.DemoData;
import com.li.pojo.User;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class EasyExcelUtil {
public static void main(String[] args) {
EasyExcelUtil.read2();
}
private static void read1() {
final List list = new ArrayList();
//使用EasyExcel读取test1.xlsx文件
EasyExcel.read("C:\\Users\\lenovo\\Desktop\\user.xlsx", User.class, new SyncReadListener() {
//EasyExcel在读取excel表格时,每读取到一行,就会调用一次这个方法,
//并且将读取到的行数据,封装到指定类型(User)的对象中,传递给我们(Object object)
/*
此问题可能出现在低版本的easyExcel中,出现时可以按照下列方式解决
如果表格数据不是顶行写的,需要通过headRowNumber指定表头行的数量
如果表格数据不是顶列写的,需要在封装的实体属性上通过@ExcelProperty将实体属性和表格列名进行对应
*/
@Override
public void invoke(Object object, AnalysisContext context) {
System.out.println(object);
list.add(object);
}
}).doReadAll();
//获取读取到的数据
for (Object object : list) {
User user = (User) object;
System.out.println(user);
}
}
private static void read2() {
final List list = new ArrayList();
//使用EasyExcel读取test1.xlsx文件
EasyExcel.read("C:\\Users\\lenovo\\Desktop\\user.xlsx", User.class, new AnalysisEventListener() {
//重写子类方法
@Override
public void invoke(User user, AnalysisContext analysisContext) {
list.add(user);
}
//重写子类方法
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
}
@Override
public void invokeHeadMap(Map headMap, AnalysisContext context) {
System.out.println(headMap);
}
}
).doReadAll();
//获取读取到的数据
for (Object o : list) {
User user = (User) o;
System.out.println(user);
}
}
}
运行效果如下:
这次的方法可以获取到表头
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
@ExcelProperty(index = 0)
private String id;
@ExcelProperty("姓名")
private String name;
@ExcelProperty(index = 3)
private Integer age;
}
@ExcelProperty注解中的index表示excel表中的列,默认是0,下标从0开始。默认的name,也就是名字,表示该列的表头。
不建议 index 和 name 同时用,要么一个对象只用index,要么一个对象只用name去匹配。
用名字去匹配,需要注意,如果名字重复,会导致只有一个字段读取到数据。
如果有一个index的列向后移动了一列,那么之后的属性默认会获取向后移动一列的数据
修改好后运行结果如下
这里可以看到age没有获取到值,因为我们将他的index设置的3,是没有值的列。
将其修改为2后就会恢复正常
private static void write1() {
List list = new ArrayList();
list.add(new User("1", "大明", 1));
list.add(new User("2", "大红", 1));
list.add(new User("3", "大刚", 1));
//1.
EasyExcel
.write("C:\\Users\\lenovo\\Desktop\\user.xlsx", User.class)
.sheet(1)//可以在其中写入数字,将其设置为sheet页的名称,不写默认是0
.doWrite(list);
}
public static void write2(){
List list = new ArrayList();
list.add(new User("1", "大明", 1));
list.add(new User("2", "大红", 1));
list.add(new User("3", "大刚", 1));
//2.
ExcelWriter excelWriter = null;
try {
excelWriter = EasyExcel.write("C:\\Users\\lenovo\\Desktop\\user.xlsx", User.class).build();
WriteSheet writeSheet = EasyExcel.writerSheet("sheet名称").build();
excelWriter.write(list, writeSheet);
} finally {
// 千万别忘记finish 会帮忙关闭流
if (excelWriter != null) {
excelWriter.finish();
}
}
}
然后在main方法中运行后查看excel表
运行write2()效果
在对表进行写的时候,表头默认是属性名,也可以使用注解进行更改。
private static void write_template_multi() {
List list = new ArrayList();
/*list.add(new User("1", "大明", 1));
list.add(new User("2", "大红", 1));
list.add(new User("3", "大刚", 1));*/
EasyExcel
.write("C:\\Users\\lenovo\\Desktop\\user.xlsx", User.class)
.withTemplate("C:\\Users\\lenovo\\Desktop\\user_template.xlsx")
.sheet()
.doFill(list);
}
该方法会将user_template.xlsx中的内容复制到user.xlsx中
创建一个user_template.xlsx文件,内容如下:
id | 姓名 | age |
1 | name | 18 |
然后在main中运行方法结果如下
user.xlsx的内容和user_template.xlsx一样了。
可以通过修改实体类的注解来改变表格中的样式
@Data
@AllArgsConstructor
@NoArgsConstructor
@HeadRowHeight(30) //表头行高
@ContentRowHeight(20) //数据行高
@ColumnWidth(25) //列宽
public class User {
@ExcelProperty("id")
private String id;
@ExcelProperty({"个人信息","姓名"})
private String name;
@ExcelProperty({"个人信息","年龄"})
private Integer age;
}
重新创建表格后的结果如下
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.event.SyncReadListener;
import com.alibaba.excel.write.metadata.WriteSheet;
import java.io.File;
import java.util.*;
public class EasyExcelUtil {
/**
* 读取excel表格
* @param file 目标文件
* @param head 文件读出后所对应的类
* @return 返回读出数据的集合
*/
private static List readExcel(File file,Class head) {
final List list = new ArrayList();
//使用EasyExcel读取.xlsx文件
EasyExcel.read(file, head, new SyncReadListener() {
@Override
public void invoke(Object object, AnalysisContext context) {
list.add(object);
}
}).doReadAll();
return list;
}
/**
* 读取excel表格
* @param file 目标文件
* @param head 文件读出后所对应的类
* @return 返回一个Map,其中有数据的集合list,还有一个表格中的标题map
*/
private static Map readExcelTitle(File file, Class head){
//使用EasyExcel读取.xlsx文件
List list=new ArrayList();
Map map=new HashMap<>();
EasyExcel.read(file,head, new AnalysisEventListener
以上就是使用Easy Excel对excel的快速读写