Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都存在一个严重的问题就是非常的耗内存,poi有一套SAX模式的API可以一定程度的解决一些内存溢出的问题,但POI还是有一些缺陷,比如07版Excel解压缩以及解压后存储都是在内存中完成的,内存消耗依然很大。
easyexcel重写了poi对07版Excel的解析,一个3M的excel用POI sax解析依然需要100M左右内存,改用easyexcel可以降低到几M,并且再大的excel也不会出现内存溢出;03版依赖POI的sax模式,在上层做了模型转换的封装,让使用者更加简单方便。
查看最新版本
<dependency>
<groupId>com.alibabagroupId>
<artifactId>easyexcelartifactId>
<version>3.3.2version>
dependency>
easyexcel是基于poi来完成对excel文件的解析
package com.student.model;
import java.io.Serializable;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.format.DateTimeFormat;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.lang.Character;
import java.util.ArrayList;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.lang.Integer;
/**
* 学生基本信息 StudentInfo
* @date 2022-01-27 22:12:56
*/
@ApiModel(value="StudentInfo", description="学生基本信息")
@JsonIgnoreProperties(value = {"handler"})
public class StudentInfo implements Serializable {
private static final long serialVersionUID = 1L;
/** 学号 **/
@ExcelProperty("学号")
@ApiModelProperty(value = "学号")
private String id;
/** 姓名 **/
@ExcelProperty("姓名")
@ApiModelProperty(value = "姓名")
private String name;
/** 年龄 **/
@ExcelProperty("年龄")
@ApiModelProperty(value = "年龄")
private Integer age;
/** 出生日期 **/
@DateTimeFormat("yyyy年MM月dd日HH时mm分ss秒")
@ExcelProperty("日期标题")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
@ApiModelProperty(value = "出生日期")
private Date birthday;
/** 民族 **/
@ApiModelProperty(value = "民族")
private String nation;
/** 证件类型 **/
@ApiModelProperty(value = "证件类型")
private String idType;
/** 证件号码 **/
@ApiModelProperty(value = "证件号码")
private String idNumber;
/** 手机号 **/
@ApiModelProperty(value = "手机号")
private Integer tel;
/** 入学时间 **/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
@ApiModelProperty(value = "入学时间")
private Date admissionTime;
/** 家庭住址 **/
@ApiModelProperty(value = "家庭住址")
private String address;
/** 院系 **/
@ApiModelProperty(value = "院系")
private String faculty;
/** 专业 **/
@ApiModelProperty(value = "专业")
private String major;
/** 班级 **/
@ApiModelProperty(value = "班级")
private Integer classID;
/** 辅导员 **/
@ApiModelProperty(value = "辅导员")
private String instructor;
/** 是否在籍(0:否;1:是) **/
@ApiModelProperty(value = "是否在籍(0:否;1:是)")
private Character registered;
/** 分数信息**/
@ApiModelProperty(value = "分数信息StudentScore")
private ArrayList<StudentScore> studentScore;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getNation() {
return nation;
}
public void setNation(String nation) {
this.nation = nation;
}
public String getIdType() {
return idType;
}
public void setIdType(String idType) {
this.idType = idType;
}
public String getIdNumber() {
return idNumber;
}
public void setIdNumber(String idNumber) {
this.idNumber = idNumber;
}
public Integer getTel() {
return tel;
}
public void setTel(Integer tel) {
this.tel = tel;
}
public Date getAdmissionTime() {
return admissionTime;
}
public void setAdmissionTime(Date admissionTime) {
this.admissionTime = admissionTime;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getFaculty() {
return faculty;
}
public void setFaculty(String faculty) {
this.faculty = faculty;
}
public String getMajor() {
return major;
}
public void setMajor(String major) {
this.major = major;
}
public Integer getClassID() {
return classID;
}
public void setClassID(Integer classID) {
this.classID = classID;
}
public String getInstructor() {
return instructor;
}
public void setInstructor(String instructor) {
this.instructor = instructor;
}
public Character getRegistered() {
return registered;
}
public void setRegistered(Character registered) {
this.registered = registered;
}
public ArrayList<StudentScore> getStudentScore() {
return studentScore;
}
public void setStudentScore(ArrayList<StudentScore> studentScore) {
this.studentScore = studentScore;
}
public StudentInfo() {
super();
}
public StudentInfo(String id, String name, Integer age, Date birthday, String nation, String idType, String idNumber, Integer tel, Date admissionTime, String address, String faculty, String major, Integer classID, String instructor, Character registered) {
this.id = id;
this.name = name;
this.age = age;
this.birthday = birthday;
this.nation = nation;
this.idType = idType;
this.idNumber = idNumber;
this.tel = tel;
this.admissionTime = admissionTime;
this.address = address;
this.faculty = faculty;
this.major = major;
this.classID = classID;
this.instructor = instructor;
this.registered = registered;
}
@Override
public String toString() {
return "StudentInfo{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", birthday=" + birthday +
", nation='" + nation + '\'' +
", idType='" + idType + '\'' +
", idNumber='" + idNumber + '\'' +
", tel=" + tel +
", admissionTime=" + admissionTime +
", address='" + address + '\'' +
", faculty='" + faculty + '\'' +
", major='" + major + '\'' +
", classID=" + classID +
", instructor='" + instructor + '\'' +
", registered=" + registered +
", studentScore=" + studentScore +
'}';
}
}
package easyexcel;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.util.ListUtils;
import com.student.model.StudentInfo;
import java.util.Date;
import java.util.List;
/**
* 写的常见写法
*
* @author zjg
*/
public class WriteTest {
private static final String FILE_PATH="E:\\test\\easyexcel\\";
public static void main(String[] args) {
new WriteTest().simpleWrite();
}
/**
* 最简单的写
*
* 1. 创建excel对应的实体对象 参照{@link StudentInfo}
*
* 2. 直接写即可
*/
public void simpleWrite() {
// 注意 simpleWrite在数据量不大的情况下可以使用(5000以内,具体也要看实际情况),数据量大参照 重复多次写入
String fileName = FILE_PATH + "simpleWrite.xlsx";
// 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
// 如果这里想使用03 则 传入excelType参数即可
EasyExcel.write(fileName, StudentInfo.class).sheet("StudentInfo").doWrite(data());
}
private List<StudentInfo> data() {
List<StudentInfo> list = ListUtils.newArrayList();
for (int i = 0; i < 10; i++) {
StudentInfo data = new StudentInfo();
data.setId(i+"");
data.setName("特斯拉"+i+"号");
data.setAge(i);
data.setBirthday(new Date());
list.add(data);
}
return list;
}
}
package easyexcel;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.read.listener.PageReadListener;
import com.alibaba.fastjson.JSON;
import com.student.model.StudentInfo;
/**
* Create by zjg on 2023/7/29
*/
public class ReadTest {
private static final String FILE_PATH="E:\\test\\easyexcel\\simpleWrite.xlsx";
public static void main(String[] args) {
new ReadTest().simpleRead();
}
/**
* 最简单的读
*
* 1. 创建excel对应的实体对象 参照{@link StudentInfo}
*/
public void simpleRead() {
// 写法1:JDK8+ ,不用额外写一个StudentInfoListener
// since: 3.0.0-beta1
// 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭
// 具体需要返回多少行可以在`PageReadListener`的构造函数设置
EasyExcel.read(FILE_PATH, StudentInfo.class, new PageReadListener<StudentInfo>(dataList -> {
for (StudentInfo studentInfo : dataList) {
System.out.println(String.format("读取到一条数据%s", JSON.toJSONString(studentInfo, SerializerFeature.WriteDateUseDateFormat)));
}
})).sheet().doRead();
}
}
以上介绍了easyexcel的基本使用,更多使用请参考官方文档和demo代码地址
回到顶部
官方网站
demo代码地址:gitee github