文档必读:https://www.yuque.com/easyexcel/doc/fillhttps://www.yuque.com/easyexcel/doc/fill
1. pom.xml 依赖
<dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.2.1</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.9.2</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
</dependencies>
2. 实体类
@Data
@NoArgsConstructor
@HeadRowHeight(value= 20) //指定行高
//设置表头文本样式
@HeadFontStyle(fontName="黑体",color = 45,underline = Font.U_SINGLE)
//设置表头除了单元格文本外其他的样式
@HeadStyle(leftBorderColor = 10 ,borderLeft = BorderStyleEnum.THIN,
rightBorderColor = 13 , borderRight = BorderStyleEnum.MEDIUM_DASH_DOT,
//背景颜色 和填充方式
fillForegroundColor =17 , fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND)
@AllArgsConstructor
public class Teacher {
//value映射到excel中的表头名称 index:写入到excel中的索引从0开始
@ExcelProperty(value = "编号",index = 3)
private Integer id;
@ExcelProperty(value = "姓名")
private String name;
@ExcelProperty(value = "年龄",index=10)
private Integer age;
@ExcelProperty(value = "月薪")
//数值格式化
@NumberFormat(value = "#.##")//小数点后的#个数表示精确到小数点后的位数
private Double salary;
@ExcelProperty(value = "入职时间")
//时间日期格式化
@DateTimeFormat(value = "yyyy年MM月dd日 HH:mm:ss")
@ColumnWidth(value= 25) //指定当前列的宽度
// @ContentStyle
private Date joinDate;
@ExcelProperty(value = "个人介绍")
@ContentStyle(fillForegroundColor = 40 , fillPatternType =FillPatternTypeEnum.SOLID_FOREGROUND )
@ContentFontStyle(fontName = "隶书", color = 51)
private String link;//个人介绍网址
@ExcelProperty(value = "个人注释")
private String comment;//个人注释
}
@Data
@NoArgsConstructor
@HeadRowHeight(value= 20) //指定行高
//设置表头文本样式
@HeadFontStyle(fontName="黑体",color = 45,underline = Font.U_SINGLE)
//设置表头除了单元格文本外其他的样式
@HeadStyle(leftBorderColor = 10 ,borderLeft = BorderStyleEnum.THIN,
rightBorderColor = 13 , borderRight = BorderStyleEnum.MEDIUM_DASH_DOT,
//背景颜色 和填充方式
fillForegroundColor =17 , fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND)
@AllArgsConstructor
public class Teacher2 {
//value映射到excel中的表头名称 index:写入到excel中的索引从0开始
@ExcelProperty(value = "编号",index = 3)
private Integer id;
@ExcelProperty(value = "姓名")
private String name;
@ExcelProperty(value = "年龄",index=10)
private Integer age;
@ExcelProperty(value = "月薪")
//数值格式化
@NumberFormat(value = "#.##")//小数点后的#个数表示精确到小数点后的位数
private Double salary;
@ExcelProperty(value = "入职时间")
//时间日期格式化
@DateTimeFormat(value = "yyyy年MM月dd日 HH:mm:ss")
@ColumnWidth(value= 25) //指定当前列的宽度
// @ContentStyle
private Date joinDate;
@ExcelProperty(value = "个人介绍")
//背景颜色+全部填充
//配置复杂的内容:链接、注释、样式
private WriteCellData<String> link;//个人介绍网址
// @ContentStyle(fillForegroundColor = 40 , fillPatternType =FillPatternTypeEnum.SOLID_FOREGROUND )
@ContentFontStyle(fontName = "隶书", color = 60)
@ExcelProperty(value = "个人注释")
private WriteCellData<String> comment;//个人注释
}
3. 监听
//监听器:泛型 AnalysisEventListener读取一行数据后会自动转为该类型的对象
public class TeacherVoReadListener extends AnalysisEventListener<TeacherVo> {
private List<TeacherVo> list = new ArrayList<>();
private int limit = 100;
//每读取一行数据回调一次
@Override
public void invoke(TeacherVo data, AnalysisContext context) {
//处理读取到数据的业务代码
// System.out.println(data);
//保存数据到数据库: 单个保存性能较差,可以使用批量保存
//为了节省内存占用,批量保存的数据行数需要设置阈值
//1、保存数据到集合中
list.add(data);
//2、判断集合数据条数到达阈值批量保存
if(list.size()==limit){
System.out.println("批量保存。。。。。。。");
//3、清空保存过的集合数据
list.clear();
}
}
//整个文档解析完毕后回调
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
//如果集合中仍有数据 保存到数据库
if(list.size()>0){
System.out.println("文档解析完成:保存数据到数据库,"+list);
list.clear();
}
}
}
4. vo类
@Data
public class TeacherVo {
//value映射到excel中的表头名称 index:写入到excel中的索引从0开始
@ExcelProperty(value = "编号",index = 3)
private Integer id;
@ExcelProperty(value = "姓名")
private String name;
@ExcelProperty(value = "年龄",index=10)
private Integer age;
@ExcelProperty(value = "月薪")
//数值格式化
@NumberFormat(value = "#.##")//小数点后的#个数表示精确到小数点后的位数
private Double salary;
@ExcelProperty(value = "入职时间")
//时间日期格式化
@DateTimeFormat(value = "yyyy年MM月dd日 HH:mm:ss")
@ColumnWidth(value= 25) //指定当前列的宽度
// @ContentStyle
private Date joinDate;
@ExcelProperty(value = "个人介绍")
private String link;//个人介绍网址
@ExcelProperty(value = "个人注释")
private String comment;//个人注释
}
5. 测试写
public class TestWrite {
//测试创建新的工作簿
@Test
void test4(){
//设置样式:
//字体颜色、背景颜色、字体、边框颜色、文本添加链接地址、文本添加注释
List<Teacher2> data = new ArrayList<>();
Teacher2 teacher = new Teacher2(100000 , "桃桃2" ,
RandomUtils.nextInt(45, 60), RandomUtils.nextDouble(30000D, 60000D),
new Date(), null, null );
//需求:给一个文本设置一个超链接,点击excel中的文本时可以跳转到链接地址
WriteCellData<String> link = new WriteCellData<>("个人首页地址");//文本内容
//设置链接内容:
HyperlinkData hyperLinkData = new HyperlinkData();
hyperLinkData.setAddress("http://www.atguigu.com/teacher/new/zhangyitao.jpg");//链接地址
hyperLinkData.setHyperlinkType(HyperlinkData.HyperlinkType.URL);//链接类型
link.setHyperlinkData(hyperLinkData);
//设置单元格样式
WriteCellStyle writeCellStyle = new WriteCellStyle();
writeCellStyle.setFillForegroundColor(IndexedColors.DARK_YELLOW.getIndex());
writeCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
//link.setRichTextStringDataValue(); 设置渐变色
link.setWriteCellStyle(writeCellStyle);
teacher.setLink(link);
//需求:给文本添加备注信息
WriteCellData<String> comment = new WriteCellData<>("评价");
//批注内容:
CommentData commentData = new CommentData();
commentData.setAuthor("庞局");
commentData.setRichTextStringData(new RichTextStringData("张老师是个男老师...今年50了."));
comment.setCommentData(commentData);
teacher.setComment(comment);
data.add(teacher);
//需求:追加写入
//1、判断如果要写入数据的文件不存在,直接写入
//覆盖写入
String path = "F:/excel/teacher1" + ExcelTypeEnum.XLSX.getValue();//目标写入的文件
String tmpPath = "F:/excel/tmp_"+System.currentTimeMillis()+ ExcelTypeEnum.XLSX.getValue();//临时文件
File file = new File(path);
File tmpFile = new File(tmpPath);
if(!file.exists()){
EasyExcel.write(file)
.head(Teacher2.class)
.sheet("1")
.doWrite(data);
}else{
//2、如果写入数据的文件已存在,使用已存在的文件当做模板和本次要写入的数据 一起写入到一个临时文件中
EasyExcel.write(tmpFile) //需要指定写入到临时文件中
.withTemplate(file) //使用原来的文件当做模板复制过来继续写
.file(tmpFile) //最终写入到的文件
.inMemory(true) //在内存中操作
.sheet("2") //如果和源文件的工作簿不一样 就会新创建工作簿,一样则合并
.needHead(true) //不需要再生成表头
.head(Teacher2.class)
.doWrite(data);
}
//3、删除原来的数据文件,修改临时文件名为原来文件的名称
//如何判断是第一次创建原来文件 还是 第N次创建临时文件
if(tmpFile.exists()){
//删除原来的文件
file.delete();
//重命名临时文件
tmpFile.renameTo(file);
}
}
//测试追加写入
@Test
void test3(){
//设置样式:
//字体颜色、背景颜色、字体、边框颜色、文本添加链接地址、文本添加注释
List<Teacher2> data = new ArrayList<>();
Teacher2 teacher = new Teacher2(100000 , "桃桃2" ,
RandomUtils.nextInt(45, 60), RandomUtils.nextDouble(30000D, 60000D),
new Date(), null, null );
//需求:给一个文本设置一个超链接,点击excel中的文本时可以跳转到链接地址
WriteCellData<String> link = new WriteCellData<>("个人首页地址");//文本内容
//设置链接内容:
HyperlinkData hyperLinkData = new HyperlinkData();
hyperLinkData.setAddress("http://www.atguigu.com/teacher/new/zhangyitao.jpg");//链接地址
hyperLinkData.setHyperlinkType(HyperlinkData.HyperlinkType.URL);//链接类型
link.setHyperlinkData(hyperLinkData);
//设置单元格样式
WriteCellStyle writeCellStyle = new WriteCellStyle();
writeCellStyle.setFillForegroundColor(IndexedColors.DARK_YELLOW.getIndex());
writeCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
//link.setRichTextStringDataValue(); 设置渐变色
link.setWriteCellStyle(writeCellStyle);
teacher.setLink(link);
//需求:给文本添加备注信息
WriteCellData<String> comment = new WriteCellData<>("评价");
//批注内容:
CommentData commentData = new CommentData();
commentData.setAuthor("庞局");
commentData.setRichTextStringData(new RichTextStringData("张老师是个男老师...今年50了."));
comment.setCommentData(commentData);
teacher.setComment(comment);
data.add(teacher);
//需求:追加写入
//1、判断如果要写入数据的文件不存在,直接写入
//覆盖写入
String path = "F:/excel/teacher1" + ExcelTypeEnum.XLSX.getValue();//目标写入的文件
String tmpPath = "F:/excel/tmp_"+System.currentTimeMillis()+ ExcelTypeEnum.XLSX.getValue();//临时文件
File file = new File(path);
File tmpFile = new File(tmpPath);
if(!file.exists()){
EasyExcel.write(file)
.head(Teacher2.class)
.sheet("1")
.doWrite(data);
}else{
//2、如果写入数据的文件已存在,使用已存在的文件当做模板和本次要写入的数据 一起写入到一个临时文件中
EasyExcel.write(tmpFile) //需要指定写入到临时文件中
.withTemplate(file) //使用原来的文件当做模板复制过来继续写
.file(tmpFile) //最终写入到的文件
.inMemory(true) //在内存中操作
.sheet("1") //需要和原来文件的sheet一样
.needHead(false) //不需要再生成表头
.doWrite(data);
}
//3、删除原来的数据文件,修改临时文件名为原来文件的名称
//如何判断是第一次创建原来文件 还是 第N次创建临时文件
if(tmpFile.exists()){
//删除原来的文件
file.delete();
//重命名临时文件
tmpFile.renameTo(file);
}
}
//测试写数据到excel文件中:
@Test
void test2(){
//设置样式:
//字体颜色、背景颜色、字体、边框颜色、文本添加链接地址、文本添加注释
List<Teacher2> data = new ArrayList<>();
Teacher2 teacher = new Teacher2(100000 , "桃桃2" ,
RandomUtils.nextInt(45, 60), RandomUtils.nextDouble(30000D, 60000D),
new Date(), null, null );
//需求:给一个文本设置一个超链接,点击excel中的文本时可以跳转到链接地址
WriteCellData<String> link = new WriteCellData<>("个人首页地址");//文本内容
//设置链接内容:
HyperlinkData hyperLinkData = new HyperlinkData();
hyperLinkData.setAddress("http://www.atguigu.com/teacher/new/zhangyitao.jpg");//链接地址
hyperLinkData.setHyperlinkType(HyperlinkData.HyperlinkType.URL);//链接类型
link.setHyperlinkData(hyperLinkData);
//设置单元格样式
WriteCellStyle writeCellStyle = new WriteCellStyle();
writeCellStyle.setFillForegroundColor(IndexedColors.DARK_YELLOW.getIndex());
writeCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
//link.setRichTextStringDataValue(); 设置渐变色
link.setWriteCellStyle(writeCellStyle);
teacher.setLink(link);
//需求:给文本添加备注信息
WriteCellData<String> comment = new WriteCellData<>("评价");
//批注内容:
CommentData commentData = new CommentData();
commentData.setAuthor("庞局");
commentData.setRichTextStringData(new RichTextStringData("张老师是个男老师...今年50了."));
comment.setCommentData(commentData);
teacher.setComment(comment);
data.add(teacher);
//需求:追加写入
//覆盖写入
EasyExcel.write("F:/excel/teacher1"+ExcelTypeEnum.XLSX.getValue())
.head(Teacher2.class)
.sheet("1")
.doWrite(data);
}
@Test
void test1(){
//xls: 老版本的excel文件一次性最多可以写入65535行数据
//xlsx: 新版本的excel文件 写入数据一般没有限制 去掉了默认的样式 文件比老版本小
EasyExcel.write("F:/excel/t7"+ ExcelTypeEnum.XLSX.getValue()) //目标文件
.head(Teacher.class) // excel中的头:以后通过excel映射的bean的属性名解析
.sheet("teachers") // excel中的一个工作簿
.doWrite(data()); //写入到excel中的数据集合
}
private List<Teacher> data(){
List<Teacher> data = new ArrayList<>();
for (int i = 0; i <= 165535; i++) {
Teacher teacher = new Teacher(100000 + i, "pangju" + i,
RandomUtils.nextInt(35, 50), RandomUtils.nextDouble(20000D, 50000D),
new Date(), "http://asdasdasd/pangju.html", "hehe" + i);
data.add(teacher);
}
return data;
}
}
6. 测试读
public class TestRead {
@Test
void test1(){
EasyExcel.read("F:/excel/teacher1.xlsx")
.sheet("2")
.head(TeacherVo.class)
//需要配置监听器:接收easyexcel读取的每行数据
// easyexcel基于回调的方式每读取一行数据调用一次 监听器的回调方法传入
.registerReadListener(new TeacherVoReadListener())
.doRead();
}
}