EasyExcel读写、模板填充、Web上传下载入门到实战全指南
作者:五阿哥永琪
EasyExcel类是一套基于Java的开源Excel解析工具类,相较于传统的框架如Apache poi、jxl等更加快速、简洁,还可以解决大文件内存溢出问题,这篇文章主要介绍了EasyExcel读写、模板填充、Web上传下载入门到实战的相关资料,需要的朋友可以参考下
EasyExcel 是阿里巴巴开源的一款 基于 Java 的高性能、简单易用的 Excel 读写工具库,专注于解决使用 Apache POI(Java 操作 Excel 的底层库)时常见的 内存溢出(OOM) 和 API 复杂 问题。
一、 主要功能
1. 读 Excel(支持 .xls / .xlsx)
- 按行读取,自动映射到 Java 对象
- 支持读取表头、数据、异常处理
- 可监听每行数据(适合大数据量)
EasyExcel.read(fileName, DemoData.class, new MyReadListener())
.sheet()
.doRead();
2. 写 Excel
- 自动根据对象字段生成表头和数据
- 支持大数据量分批写入(百万行无压力)
- 可指定列宽、行高、样式等
EasyExcel.write(fileName, DemoData.class)
.sheet("Sheet1")
.doWrite(dataList);
3. Excel 填充(模板填充)
- 提供 Excel 模板(带占位符如
{name}) - 自动填充数据,适合生成报表、证书等
EasyExcel.write(out, DemoData.class)
.withTemplate(templateFile)
.sheet()
.doFill(data);
4. 丰富的注解支持
@ExcelProperty("姓名"):指定列名@ColumnWidth(20):设置列宽@DateTimeFormat("yyyy-MM-dd"):日期格式化@NumberFormat("#,##0.00"):数字格式化@ExcelIgnore:忽略字段
public class User {
@ExcelProperty("用户姓名")
private String name;
@ExcelProperty("注册时间")
@DateTimeFormat("yyyy年MM月dd日")
private Date registerTime;
}
二、 快速开始
1. 引入依赖
<!--Lombok依赖-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!--easyexcel依赖-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>4.0.3</version>
</dependency>
<!--fastjson依赖-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>2.0.57</version>
</dependency>
2. 写实体类
package com.nuc.demoexcel.entity;
import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.alibaba.excel.annotation.write.style.HeadRowHeight;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;
import java.util.Date;
@Data
@HeadRowHeight(20)
@ColumnWidth(20)
public class DemoDate {
@ExcelProperty("字符串标题")
private String name;
@ExcelProperty("日期标题")
@JSONField(format = "yyyy-MM-dd,HH:mm:ss") // 格式化日期 没有注解会默认转成时间戳
private Date date;
@ExcelProperty("数字标题")
private Double doubleData;
@ExcelIgnore
private String ignore;
}
3. Excel读取
读取常用有三种方法
- 这是我提前准备好的excel文件

方法一:
有封装的实体类
用.head(DemoData.class)封装
结果用List<DemoData>存
/**
* 测试读1
* 有封装的实体类
*/
@Test
void readExcel1() {
System.out.println("测试");
List<DemoDate> list = EasyExcel.read("D:\\测试\\demo.xlsx").head(DemoDate.class).sheet().doReadSync();
list.forEach(data ->{
String jsonString = JSON.toJSONString(data);
log.info("读取到数据{}",jsonString);
});
}
- 测试结果

方法二:没有封装的实体类
没有封装的实体类
结果用List<Map<Integer,String>>存
/**
* 测试读2
* 没有分装的实体类用Map来存
*/
@Test
void readExcel2() {
System.out.println("测试");
List<Map<Integer,String>> list = EasyExcel.read("D:\\测试\\demo.xlsx").sheet().doReadSync();
list.forEach(data ->{
String string = data.toString();
log.info("读取到数据{}",string);
});
}
- 测试结果同上
方法三:使用监听器来读取文件
使用监听器来读取文件
/**
* 测试读3
* 使用监听器读取文件。
* 需要我们额外创建一个监听器
*/
@Test
void readExcel3() {
System.out.println("测试");
EasyExcel.read("D:\\测试\\demo.xlsx", DemoDate.class, new ExcelListener(demoService)).sheet().doRead();
}
- 这里需要额外写一个监听器
package com.nuc.demoexcel.listener;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.fastjson.JSON;
import com.nuc.demoexcel.entity.DemoDate;
import com.nuc.demoexcel.service.DemoService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
import java.util.List;
/**
* 这里不能用SprongIoC容器来管理Listener,Listener可添加多个,会自动执行
*/
@Slf4j
@RequiredArgsConstructor
public class ExcelListener extends AnalysisEventListener<DemoDate> {
/**
* 每隔5条存储数据库,清理list,方便内存回收
*/
private static final int BATCH_COUNT = 5;
private List<DemoDate> list = new ArrayList<DemoDate>();
private final DemoService demoService;
@Override
public void invoke(DemoDate demoDate, AnalysisContext analysisContext) {
log.info("读取到数据{}", JSON.toJSONString(demoDate));
list.add(demoDate);
// 到达批次数,保存数据,防止数据几万条数据在内存中,容易OOM
if (list.size() >= BATCH_COUNT) {
saveData();
// 保存完成,清理list
list.clear();
}
}
/**
* 所有的数据都读完,最后收尾数据
* @param analysisContext
*/
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
//这里也要保存数据,确保最后遗留的数据也存储到数据库
saveData();
log.info("所有数据解析完成!");
}
/**
* 存储数据到数据库
*/
private void saveData() {
log.info("{}条数据,开始存储数据库!", list.size());
demoService.saveData(list);
log.info("存储数据库成功!");
}
}
这里只是演示EasyExcel
所以就不写Service层代码
4. Excel写入
/**
* 测试写
*/
@Test
void testWrite() {
// 文件输出位置
String fileName = "D:\\text" + System.currentTimeMillis() + ".xlsx";
EasyExcel.write(fileName, DemoDate.class).sheet("模板").doWrite(data());
}
private List<DemoDate> data(){
//模拟数据
List<DemoDate> list = new ArrayList<>();
for (int i = 0; i < 13; i++) {
DemoDate data = new DemoDate();
data.setName("张三"+i);
data.setDate(new Date());
data.setDoubleData(Math.random()*100);
list.add(data);
}
return list;
}
- 成功写入

5. Excel下载&上传
package com.nuc.demoexcel.controller;
import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson.JSON;
import com.nuc.demoexcel.entity.DemoDate;
import com.nuc.demoexcel.listener.ExcelListener;
import com.nuc.demoexcel.service.DemoService;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.*;
@Controller
public class UploadDownController {
@Autowired
private DemoService demoService;
/**
* 下载失败了(会返回一个有部分数据的Excel)
* @param response
* @throws IOException
*/ @RequestMapping("/download")
public void download(HttpServletResponse response) throws IOException {
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
//这里的encode是解决中文乱码, 这里必须使用UTF-8, 不然乱码
String fileName = URLEncoder.encode("测试", "UTF-8").replaceAll("\\+", "%20");
//这里使用附件的形式下载
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
EasyExcel.write(response.getOutputStream(), DemoDate.class).sheet("模板").doWrite(data());
}
@RequestMapping("/api/download")
public void downloadApi(HttpServletResponse response) throws IOException {
try {
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
//这里的encode是解决中文乱码, 这里必须使用UTF-8, 不然乱码
String fileName = URLEncoder.encode("测试", "UTF-8").replaceAll("\\+", "%20");
//这里使用附件的形式下载
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
EasyExcel.write(response.getOutputStream(), DemoDate.class).sheet("模板").doWrite(data());
} catch (IOException e) {
//重置响应
response.reset();
response.setContentType("application/json");
response.setCharacterEncoding("utf-8");
Map<String, Object> map = new HashMap<>();
map.put("status", 500);
map.put("message", "数据写入失败" + e.getMessage());
response.getWriter().println(JSON.toJSONString(map));
}
}
@PostMapping("/upload")
@ResponseBody
public String upload(MultipartFile file) throws IOException {
EasyExcel.read(file.getInputStream(), DemoDate.class, new ExcelListener(demoService)).sheet().doRead();
return "success";
}
private List<DemoDate> data(){
//模拟数据
List<DemoDate> list = new ArrayList<>();
for (int i = 0; i < 13; i++) {
DemoDate data = new DemoDate();
data.setName("张三"+i);
data.setDate(new Date());
data.setDoubleData(Math.random()*100);
list.add(data);
}
return list;
}
}
- 调用
localhost:8080/download接口
5. Excel下载&上传
package com.nuc.demoexcel.controller;
import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson.JSON;
import com.nuc.demoexcel.entity.DemoDate;
import com.nuc.demoexcel.listener.ExcelListener;
import com.nuc.demoexcel.service.DemoService;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.*;
@Controller
public class UploadDownController {
@Autowired
private DemoService demoService;
/**
* 下载失败了(会返回一个有部分数据的Excel)
* @param response
* @throws IOException
*/ @RequestMapping("/download")
public void download(HttpServletResponse response) throws IOException {
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
//这里的encode是解决中文乱码, 这里必须使用UTF-8, 不然乱码
String fileName = URLEncoder.encode("测试", "UTF-8").replaceAll("\\+", "%20");
//这里使用附件的形式下载
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
EasyExcel.write(response.getOutputStream(), DemoDate.class).sheet("模板").doWrite(data());
}
@RequestMapping("/api/download")
public void downloadApi(HttpServletResponse response) throws IOException {
try {
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
//这里的encode是解决中文乱码, 这里必须使用UTF-8, 不然乱码
String fileName = URLEncoder.encode("测试", "UTF-8").replaceAll("\\+", "%20");
//这里使用附件的形式下载
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
EasyExcel.write(response.getOutputStream(), DemoDate.class).sheet("模板").doWrite(data());
} catch (IOException e) {
//重置响应
response.reset();
response.setContentType("application/json");
response.setCharacterEncoding("utf-8");
Map<String, Object> map = new HashMap<>();
map.put("status", 500);
map.put("message", "数据写入失败" + e.getMessage());
response.getWriter().println(JSON.toJSONString(map));
}
}
@PostMapping("/upload")
@ResponseBody
public String upload(MultipartFile file) throws IOException {
EasyExcel.read(file.getInputStream(), DemoDate.class, new ExcelListener(demoService)).sheet().doRead();
return "success";
}
private List<DemoDate> data(){
//模拟数据
List<DemoDate> list = new ArrayList<>();
for (int i = 0; i < 13; i++) {
DemoDate data = new DemoDate();
data.setName("张三"+i);
data.setDate(new Date());
data.setDoubleData(Math.random()*100);
list.add(data);
}
return list;
}
}
调用
localhost:8080/download接口
调用
localhost:8080/api/upload接口
使用postman 调用
localhost:8080/upload接口
- 后端

- 后端
总结
到此这篇关于EasyExcel读写、模板填充、Web上传下载入门到实战的文章就介绍到这了,更多相关EasyExcel读写、模板填充、Web上传下载内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!







