EasyExcel知识【Java程序进行读写生成Excel操作】
- 💂 个人主页: 爱吃豆的土豆
🌈欢迎加入社区,福利多多哦!土豆社区
- 🤟数据库专栏更新完毕:数据库知识
- 🤟JDBC专栏更新完毕:JDBC知识
- 🤟Mybatis专栏更新完毕:Mybatis知识
- 💬 如果文章对你有帮助、欢迎关注、点赞、收藏(一键三连)和订阅专栏哦
目录
1,Easy Excel入门
1.1:Easy Excel概述
1.2:Easy Excel特点
1.3:环境搭建
1.3.1:测试父项目
1.3.2:测试excel项目
1.4:基本操作
1.4.1:测试JavaBean
1.4.2:测试文件路径
1.4.3:写入操作
1.4.4:读出操作
1.5:复杂操作
1.5.1:复合表头
1.5.2:写操作:多表
1.5.3:读操作:多表
1.5.4:写操作:多对象
1,Easy Excel入门
1.1:Easy Excel概述
EasyExcel是一个基于Java的简单、省内存的读写Excel的开源项目。在尽可能节约内存的情况下支持读写百M的Excel工具。
官网:EasyExcel官方文档 - 基于Java的Excel处理工具 | Easy Excel
github地址:GitHub - alibaba/easyexcel: 快速、简洁、解决大文件内存溢出的java处理Excel工具
1.2:Easy Excel特点
Java解析、生成Excel比较有名的框架有Apache poi、jxl,但他们都存在一个严重的问题就是非常的耗内存。
EasyExcel 重写了poi,使一个3M的excel只需要几M内存,并且再大的excel不会出现内存溢出。
64M内存1分钟内读取75M(46W行25列)的Excel。
1.3:环境搭建
1.3.1:测试父项目
项目名:zx-test-parent
-
修改pom文件
org.springframework.boot spring-boot-starter-test org.springframework.boot spring-boot-starter-amqp
1.3.2:测试excel项目
项目名:zx-test-excel
修改pom,添加依赖
com.alibaba easyexcel 3.1.1 org.projectlombok lombok
1.4:基本操作
1.4.1:测试JavaBean
常用的注解:
@Data@AllArgsConstructor@NoArgsConstructor@ColumnWidth(30)@HeadRowHeight(30)public class Student1 { @ExcelProperty("编号") private String id; @ExcelProperty("姓名") @ContentFontStyle(fontName = "楷体",italic = BooleanEnum.TRUE,color = Font.ITALIC) private String name; @ExcelProperty({"基本信息","年龄"}) private Integer age; @ExcelProperty({"基本信息","电话"}) private String phone; @ExcelProperty({"可选信息","邮件"}) private String Email; @ExcelProperty({"可选信息","生日"}) @DateTimeFormat("yyyy-MM-dd HH:mm") private Date birthday;}
1.4.2:测试文件路径
public String path(){ return this.getClass().getResource("/").getPath(); }
1.4.3:写入操作
-
excel 属于 office组件一个软件
-
存在若干版本,大体上划分2种情况,2007前的,2007年后的
-
2003版:扩展名 xls,内容比较少,最大单元格
IV65536
,256列(IV) -
2007版:扩展名 xlsx,内容较多,最大单元格
XFD1048576
,16384列(XFD)
-
// 模拟数据 public List getDate(){ //模拟十条数据 ArrayList student1s = new ArrayList(); for (int i = 0; i < 10; i++) { Student1 student1 = new Student1(i+"","土豆"+i,i,"115"+i,"626"+i,new Date()); student1s.add(student1); } return student1s; } //创建测试写程序 @Test public void testWrite(){ //写入位置:%classpath%/ //文件名称:student-demo.xls //表名:土豆 //1,文件位置 String file = path()+"student_demo1.xls"; //2 写操作 EasyExcel.write(file, Student1.class).sheet("土豆").doWrite(getDate()); }
1.4.4:读出操作
处理类:
-
处理类需要实现
AnalysisEventListener
接口
package com.czxy.read;import com.alibaba.excel.context.AnalysisContext;import com.alibaba.excel.event.AnalysisEventListener;import com.czxy.excel.Student1;public class StudentDataListener1 extends AnalysisEventListener { @Override public void invoke(Student1 student1, AnalysisContext analysisContext) { System.out.println(student1); } @Override public void doAfterAllAnalysed(AnalysisContext analysisContext) { }}
//测试读出excel程序 @Test public void testRead(){ String file = path()+"student_demo1.xls"; //读操作 EasyExcel.read(file, Student1.class, new StudentDataListener1()).sheet("土豆").doRead(); }
1.5:复杂操作
1.5.1:复合表头
package com.czxy.excel;import com.alibaba.excel.annotation.ExcelProperty;import com.alibaba.excel.annotation.format.DateTimeFormat;import com.alibaba.excel.annotation.write.style.ColumnWidth;import com.alibaba.excel.annotation.write.style.ContentFontStyle;import com.alibaba.excel.annotation.write.style.HeadRowHeight;import com.alibaba.excel.enums.BooleanEnum;import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor;import java.awt.*;import java.util.Date;@Data@AllArgsConstructor@NoArgsConstructor@ColumnWidth(30)@HeadRowHeight(30)public class Student2 { @ExcelProperty("编号") private String id; @ExcelProperty("姓名") @ContentFontStyle(fontName = "楷体",italic = BooleanEnum.TRUE,color = Font.ITALIC) private String name; @ExcelProperty({"基本信息","年龄"}) private Integer age; @ExcelProperty({"基本信息","电话"}) private String phone; @ExcelProperty({"可选信息","邮件"}) private String Email; @ExcelProperty({"可选信息","生日"}) @DateTimeFormat("yyyy-MM-dd HH:mm") private Date birthday;}
1.5.2:写操作:多表
//得到根目录路径 public String path(){ return this.getClass().getResource("/").getPath(); } // 模拟数据 public List getDate(){ //模拟十条数据 ArrayList student1s = new ArrayList(); for (int i = 0; i < 10; i++) { Student1 student1 = new Student1(i+"","土豆"+i,i,"115"+i,"626"+i,new Date()); student1s.add(student1); } return student1s; } //创建测试书写多表 @Test public void testWrite(){ //写入位置:%classpath%/ //文件名称:student-demo.xls //表名:土豆 //1,文件位置 String file = path()+"student_demo2.xls"; //2 写操作 ExcelWriter excelWriter = EasyExcel.write(file, Student2.class).build(); //写入多个sheet WriteSheet writeSheet1 = EasyExcel.writerSheet("爱吃豆的").build(); excelWriter.write(getDate(),writeSheet1); //写入第二个sheet WriteSheet writeSheet2 = EasyExcel.writerSheet("土豆").build(); excelWriter.write(getDate(),writeSheet2); excelWriter.finish(); }
1.5.3:读操作:多表
具有缓存处理类
package com.czxy.read;import com.alibaba.excel.context.AnalysisContext;import com.alibaba.excel.event.AnalysisEventListener;import com.czxy.excel.Student2;import java.util.ArrayList;import java.util.List;public class StudentDataListener2 extends AnalysisEventListener { //创建一个集合用于保存学生 private List student2List = new ArrayList(); //创建一个变量用于判断 private Integer size = 4; @Override public void invoke(Student2 student2, AnalysisContext analysisContext) { student2List.add(student2); if (student2List.size()>size){ print(); } } //重新创建一个方法 public void print(){ student2List.forEach(System.out::println); System.out.println("============"); //打印完成之后进行清空集合 student2List.clear(); } //该方法 @Override public void doAfterAllAnalysed(AnalysisContext analysisContext) { System.out.println("打印完成"); //如果集合中还有数据进行打印if (!student2List.isEmpty()){ print();}student2List.clear(); }}
读操作
@Test public void testRead(){ String file = path()+"student_demo2.xls"; //读操作 ExcelReader excelReader = EasyExcel.read(file, Student2.class, new StudentDataListener2()).build(); ReadSheet readSheet1 = EasyExcel.readSheet("爱吃豆的").build(); excelReader.read(readSheet1); ReadSheet readSheet2 = EasyExcel.readSheet("土豆").build(); excelReader.read(readSheet2); excelReader.finish(); }
1.5.4:写操作:多对象
Student
@Data@NoArgsConstructor@AllArgsConstructorpublic class Student { @ExcelProperty("姓名") private String name; @ExcelProperty("年龄") private Integer age;}
Book
@Data@NoArgsConstructor@AllArgsConstructor@HeadRowHeight(50)@HeadFontStyle(fontName = "黑体",italic = BooleanEnum.TRUE, color = Font.COLOR_RED, underline = 2)public class Book { @ExcelProperty("编号") private String id; @ExcelProperty({"作者信息","姓名"}) private String authorName; @ExcelProperty({"作者信息","年龄"}) private Integer authorAge; @ExcelProperty({"书籍基本信息","标题"}) private String title; @ContentFontStyle(fontName = "楷书",italic = BooleanEnum.TRUE, color = Font.COLOR_RED, underline = -1) @ExcelProperty({"书籍基本信息","价格"}) private Double price; @ExcelProperty({"书籍基本信息","出版日期"}) @DateTimeFormat("yyyy年MM月dd日") private Date publishDate;}
实现
public class TestManyObject { // 获得当前项目的运行时的根目录 public String getPath() { return this.getClass().getResource("/").getPath(); } // 模拟数据 public List getStudentData() { List list = new ArrayList(); for (int i = 0; i < 20; i++) { list.add(new Student("张三" + i, 18 + i)); } return list; } public List getBookData() { List list = new ArrayList(); for (int i = 0; i < 20; i++) { list.add(new Book(i+"" , "张三" + i , 18 +i, "坏蛋是怎么"+i, 998d+i, new Date())); } return list; } // 遍历map即可 private Map<Class, List> getData() { Map<Class, List> map = new HashMap(); map.put(Student.class, getStudentData()); map.put(Book.class, getBookData()); return map; } @Test public void testManyObject() { String file = getPath() + "many_object.xlsx"; //1 开始写 ExcelWriter excelWriter = EasyExcel.write(file).build(); //2 依次写每一个对象 for(Map.Entry<Class, List> entry : getData().entrySet()) { Class clazz = entry.getKey(); //类型 List data = entry.getValue(); //数据 WriteSheet writeSheet = EasyExcel.writerSheet(clazz.getSimpleName()).head(clazz).build(); excelWriter.write(data, writeSheet); } //3 写完成 excelWriter.finish(); }}