EasyExcel专题 Excel 读取写入上传和下载
Posted Dream_it_possible!
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了EasyExcel专题 Excel 读取写入上传和下载相关的知识,希望对你有一定的参考价值。
一、将10万条数据从Excel读取出来
读取支持多标题,我们只需要指定最后一行的标题的行号即可,例如上述excel标题的行号为1,因此需要设置headRowNumber为1。
定义User 类,使用User类映射excel单条记录, 使用ExcelProperty注解标注excel里的字段名称。
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
import lombok.ToString;
@Data
@ToString
public class User
@ExcelProperty("id")
private String id;
@ExcelProperty("用户名")
private String userName;
@ExcelProperty("地址")
private String address;
FileUtil:
public class FileUtil
public static String getResourcePath()
return FileUtil.class.getResource("/").getPath();
执行读取,指定read方法的三个重要参数: file对象, 映射的pojo对象,读取监听器。
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.read.listener.PageReadListener;
import lombok.Data;
import lombok.ToString;
import org.junit.Test;
import java.io.File;
public class ExcelReadWriteTest
@Test
public void readData()
File file = new File(FileUtil.getResourcePath() + "demo.xlsx");
if (file.exists())
long start = System.currentTimeMillis();
EasyExcel.read(file, User.class, new PageReadListener<User>(dataList ->
for (User user : dataList)
System.out.println(user);
)).headRowNumber(1).sheet().doRead();
System.out.println("总耗时:" + (System.currentTimeMillis() - start) / 1000 + " s");
检查第一条数据是否正确:
总耗时1S:
二、将10万条数据写入到Excel
先看下写入的效果,单标题和多标题的区别。
1. 单标题
2. 多标题
完整代码
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.read.listener.PageReadListener;
import org.junit.Test;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class ExcelReadWriteTest
@Test
public void readData()
File file = new File(FileUtil.getResourcePath() + "demo.xlsx");
if (file.exists())
long start = System.currentTimeMillis();
EasyExcel.read(file, User.class, new PageReadListener<User>(dataList ->
for (User user : dataList)
System.out.println(user);
)).headRowNumber(1).sheet().doRead();
System.out.println("总耗时:" + (System.currentTimeMillis() - start) / 1000 + " s");
@Test
public void WriteData() throws IOException
File file = new File(FileUtil.getResourcePath() + "test01.xlsx");
if (!file.exists())
file.createNewFile();
EasyExcel.write(file, User.class).head(head()).sheet("用户表").doWrite(() -> data());
@Test
public void WriteData0() throws IOException
File file = new File(FileUtil.getResourcePath() + "test02.xlsx");
if (!file.exists())
file.createNewFile();
EasyExcel.write(file, User.class).head(manyHead()).sheet("用户表").doWrite(() -> data());
//单行标题
private List<List<String>> head()
List<List<String>> head = new ArrayList<>();
head.add(Arrays.asList("id"));
head.add(Arrays.asList("用户名"));
head.add(Arrays.asList("地址"));
return head;
// 多行标题
private List<List<String>> manyHead()
List<List<String>> head = new ArrayList<>();
head.add(Arrays.asList("用户", "id"));
head.add(Arrays.asList("用户", "用户名"));
head.add(Arrays.asList("用户", "地址"));
return head;
private List<User> data()
List<User> userList = new ArrayList<>();
for (int i = 0; i < 100000; i++)
User user = new User();
user.setId(i + "");
user.setUserName("zhangsan" + i);
user.setAddress("shanghai" + i);
userList.add(user);
return userList;
三、上传和下载excel
可以新建一个SpringBoot工程,使用接口测试上传和下载功能。
1. 上传10万条数据
写要给upLoad接口,同时指定下excel里的标题所在行号。
@PostMapping("/upLoad")
public String uploadExcel(MultipartFile file, Integer headRowNumber) throws IOException
//指定headRowNumber
EasyExcel.read(file.getInputStream(), User.class, new UploadListener(userService)).headRowNumber(headRowNumber).sheet().doRead();
return "success";
指定一个上传监听器,用于文件的回调处理。
package com.example;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.util.ListUtils;
import com.alibaba.fastjson.JSON;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class UploadListener implements ReadListener<User>
private static Logger logger = LoggerFactory.getLogger(UploadListener.class);
private UserService userService;
private List<User> cacheLists = new ArrayList<>(100);
public UploadListener(UserService userService)
this.userService = userService;
@Override
public void invoke(User data, AnalysisContext context)
logger.info("解析到一条数据: ", JSON.toJSONString(data));
cacheLists.add(data);
if (cacheLists.size() > 100)
saveData();
cacheLists = ListUtils.newArrayListWithExpectedSize(100);
private void saveData()
logger.info("存储数据" + cacheLists.size() + "条!");
@Override
public void doAfterAllAnalysed(AnalysisContext context)
if (CollectionUtils.isNotEmpty(cacheLists))
saveData();
logger.info("所有数据解析完成!");
用postman测试
查看第一条数据id为0, 说明上传正确。
2. 下载10万条数据
指定sheet名称,同时将URL用UTF-8编码,防止文件名导出出现乱码的情况。
@PostMapping("/downLoad")
public String downloadExcel(HttpServletResponse response) throws IOException
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("utf-8");
// 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
String fileName = URLEncoder.encode("测试", "UTF-8").replaceAll("\\\\+", "%20");
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
// 如果指定了ExcelProperty,那么可以不用不用指定head,到处的excel仍然含有标题,如果想要多标题,那么就需要指定
EasyExcel.write(response.getOutputStream(), User.class).sheet("用户表").doWrite(data());
return "success";
用postman测试
保存到本地,可以打开说明下载正确!
代码地址: https://gitee.com/bingbing-123456/easyexcel_practice
如果链接打不开,可私信找我。
以上是关于EasyExcel专题 Excel 读取写入上传和下载的主要内容,如果未能解决你的问题,请参考以下文章