一、什么是EasyExcel
EasyExcel 是一款基于Java的开源Excel操作工具,它提供了简单且强大的 API,使开发人员可以轻松地读写、操作和生成Excel文件。
二、常用注解
@ExcelProperty
:用于标识实体类中的字段与 Excel 表格中的列的对应关系。
@ExcelIgnore
:用于标识在读写 Excel 时忽略某个字段。
@ExcelIgnoreUnannotated
:用于标识在读取 Excel 时忽略未标注@ExcelProperty
注解的字段。
@ExcelTable
:用于标识表格的属性,如表头所在行数等。
三、SpringBoot整合
1.添加依赖
主要依赖:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.1.3</version>
</dependency>
项目完整依赖:
<dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.1.3</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>28.2-jre</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.31</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.9</version>
</dependency>
<!-- mybatis-plus配置不同数据源 需要引入的包 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.0</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>3.4.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.16</version>
</dependency>
</dependencies>
2.实体类
@Data
public class Stu implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@ExcelProperty("姓名")
private String name;
@ExcelProperty("年龄")
private Integer age;
@ExcelProperty("班级")
private String calss;
@ExcelProperty("学校")
private String school;
@ExcelProperty(value = "性别")
private Integer sex;
}
3.自定义监听器
/**
* 自定义监听器,对下载的excel中的数据进行校验
* */
public class StuListener extends AnalysisEventListener {
List<String> names = new ArrayList<>();
/**
* 每解析一行,回调该方法
*
* @param data
* @param context
*/
@Override
public void invoke(Object data, AnalysisContext context) {
//校验名称
String name = ((Stu) data).getName();
if (StrUtil.isBlank(name)) {
throw new RuntimeException(String.format("第%s行名称为空,请核实", context.readRowHolder().getRowIndex() + 1));
}
if (names.contains(name)) {
throw new RuntimeException(String.format("第%s行名称已重复,请核实", context.readRowHolder().getRowIndex() + 1));
} else {
names.add(name);
}
}
/**
* 出现异常回调
*
* @param exception
* @param context
* @throws Exception
*/
@Override
public void onException(Exception exception, AnalysisContext context) throws Exception {
if (exception instanceof ExcelDataConvertException) {
/**从0开始计算*/
Integer columnIndex = ((ExcelDataConvertException) exception).getColumnIndex() + 1;
Integer rowIndex = ((ExcelDataConvertException) exception).getRowIndex() + 1;
String message = "第" + rowIndex + "行,第" + columnIndex + "列" + "数据格式有误,请核实";
throw new RuntimeException(message);
} else if (exception instanceof RuntimeException) {
throw exception;
} else {
super.onException(exception, context);
}
}
/**
* 解析完,全部回调
*
* @param context
*/
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
//解析完,全部回调逻辑实现
names.clear();
}
}
4.导入
准备一个导入数据的文件,下方是我的文件:
Controller层代码
@PostMapping(value = "/importData")
public void importData(MultipartFile file) {
try {
//获取文件的输入流
InputStream inputStream = file.getInputStream();
List<Stu> lst = EasyExcel.read(inputStream) //调用read方法
//注册自定义监听器,字段校验可以在监听器内实现
.registerReadListener(new StuListener())
.head(Stu.class) //对应导入的实体类
.sheet(0) //导入数据的sheet页编号,0代表第一个sheet页,如果不填,则会导入所有sheet页的数据
.headRowNumber(1) //列表头行数,1代表列表头有1行,第二行开始为数据行
.doReadSync(); //开始读Excel,返回一个List<T>集合,继续后续入库操作
System.out.println(lst);
// TODO 导入后的处理逻辑
} catch (IOException exception) {
throw new RuntimeException(exception);
}
}
导入成功
扫描二维码关注公众号,回复:
17613887 查看本文章

5.导出
Controller代码
/**
* 导出数据
* */
@GetMapping("/export/user")
public void exportUserExcel(HttpServletResponse response) throws IOException {
OutputStream outputStream=response.getOutputStream();
try {
String filePath = "userlist.xlsx"; // 保存到当前项目下的文件名
File file = new File(filePath);
this.setExcelResponseProp(response, "用户列表");
// 模拟根据条件在数据库查询数据
// List<Stu> stus = stuMapper.selectList(null);
List<Stu> stus = new ArrayList<>();
for (int i = 0; i < 5; i++) {
Stu stu = new Stu();
stu.setId(i);
stu.setName("老" + i);
if (i % 2 == 0) {
stu.setSex(1);
} else {
stu.setSex(0);
}
stu.setCalss(i + "班");
stu.setSchool("第一中学");
stus.add(stu);
}
// 创建本地文件输出流
outputStream = new FileOutputStream(file);
//这个实现方式非常简单直接,使用EasyExcel的write方法将查询到的数据进行处理,以流的形式写出即可
EasyExcel.write(outputStream,Stu.class)//对应的导出实体类
.excelType(ExcelTypeEnum.XLSX)//excel文件类型,包括CSV、XLS、XLSX
.sheet("Stu列表")//导出sheet页名称
.doWrite(stus); //查询获取的数据集合List<T>,转成excel
} catch (IOException e) {
throw new RuntimeException(e);
}finally {
outputStream.flush();
outputStream.close();
}
}
/**
* 设置响应结果
*
* @param response 响应结果对象
* @param rawFileName 文件名
* @throws UnsupportedEncodingException 不支持编码异常
*/
private void setExcelResponseProp(HttpServletResponse response, String rawFileName) throws UnsupportedEncodingException {
//设置内容类型
response.setContentType("application/vnd.vnd.ms-excel");
//设置编码格式
response.setCharacterEncoding("utf-8");
//设置导出文件名称(避免乱码)
String fileName = URLEncoder.encode(rawFileName.concat(".xlsx"), "UTF-8");
// 设置响应头
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName);
}
导出成功
以上一个简单的demo就编写完成了。