1.引入easyexcel
(springboot环境下引入)
<!-- https://mvnrepository.com/artifact/com.alibaba/easyexcel -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.2.1</version>
</dependency>
2.接口
@GetMapping(value = "/exportData")
public void exportData(HttpServletResponse response) {
categoryService.exportData(response);
}
@PostMapping("importData")
public Result importData(MultipartFile file) {
categoryService.importData(file);
return Result.build(null , ResultCodeEnum.SUCCESS) ;
}
3.实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CategoryExcelVo {
@ExcelProperty(value = "id" ,index = 0)
private Long id;
@ExcelProperty(value = "名称" ,index = 1)
private String name;
@ExcelProperty(value = "图片url" ,index = 2)
private String imageUrl ;
@ExcelProperty(value = "上级id" ,index = 3)
private Long parentId;
@ExcelProperty(value = "状态" ,index = 4)
private Integer status;
@ExcelProperty(value = "排序" ,index = 5)
private Integer orderNum;
}
4.实现写 write
这里BeanUtils可用可不用,用就用了,不用就getset慢慢写
@Override
public void exportData(HttpServletResponse response) {
try {
//1.设置响应头信息
response.setContentType("application/vmd.ms-excel");
response.setCharacterEncoding("utf-8");
String fileName = URLEncoder.encode("分类数据", "UTF-8");
response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
//2.查所有
List<Category> categories = categoryMapper.findAll();
ArrayList<CategoryExcelVo> categoryExcelVos = new ArrayList<>();
for (Category category : categories) {
CategoryExcelVo excelVo = new CategoryExcelVo();
BeanUtils.copyProperties(category, excelVo);
categoryExcelVos.add(excelVo);
}
//3.调用read方法
EasyExcel.write(response.getOutputStream(), CategoryExcelVo.class)
.sheet("分类数据").doWrite(categoryExcelVos);
} catch (Exception e) {
e.printStackTrace();
throw new CustomException(ResultCodeEnum.DATA_ERROR);
}
}
5.实现读 read
这一块挺麻烦,需要写个监听器阿里官方给的文档说,不可以依赖注入,否则会引发线程问题,只能用构造器。还需要切片查出来的集合,否则在数据量大的情况下会有oom
package com.atguigu.manager.listener;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.util.ListUtils;
import com.atguigu.manager.mapper.CategoryMapper;
import com.atguigu.vo.product.CategoryExcelVo;
import java.util.List;
/**
* @Author:无敌暴龙战士
* @Package:com.atguigu.manager.listener
* @Project:spzx-parent
* @name:ExcelListener
* @Date:2025/2/17 4:47
* @Filename:ExcelListener
* @Description:
*/
public class ExcelListener<T> extends AnalysisEventListener<T> {
/**
* 每隔5条存储数据库,实际使用中可以100条,然后清理list ,方便内存回收
*/
private static final int BATCH_COUNT = 100;
/**
* 缓存的数据
*/
private List<T> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
//获取mapper对象
private CategoryMapper categoryMapper;
public ExcelListener(CategoryMapper categoryMapper) {
this.categoryMapper = categoryMapper;
}
// 每解析一行数据就会调用一次该方法
@Override
public void invoke(T t, AnalysisContext analysisContext) {
cachedDataList.add(t);
if (cachedDataList.size() >= BATCH_COUNT) {
saveData();
cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
}
}
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
// excel解析完毕以后需要执行的代码
// 这里也要保存数据,确保最后遗留的数据也存储到数据库
saveData();
}
private void saveData() {
categoryMapper.batchInsert((List<CategoryExcelVo>) cachedDataList);
}
}
继承自AnalysisEventListener,用于处理Excel文件的解析。这个类主要用于在解析Excel文件时,将数据批量插入数据库中。
5.1类定义和成员变量
public class ExcelListener<T> extends AnalysisEventListener<T> {
private static final int BATCH_COUNT = 100;
private List<T> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
private CategoryMapper categoryMapper;
}
ExcelListener<T>:这是一个泛型类,`T`表示解析的Excel行数据类型。
BATCH_COUNT:定义了每次批量插入数据库的数据条数,这里设置为100。
cachedDataList:用于缓存解析的数据,当缓存的数据条数达到100时,将数据批量插入数据库。
categoryMapper:用于数据库操作的Mapper对象。
5.2构造方法
public ExcelListener(CategoryMapper categoryMapper) {
this.categoryMapper = categoryMapper;
}
构造方法接收一个CategoryMapper对象,用于后续的数据插入操作。
5.3方法实现
5.3.1invoke方法
@Override
public void invoke(T t, AnalysisContext analysisContext) {
cachedDataList.add(t);
if (cachedDataList.size() >= BATCH_COUNT) {
saveData();
cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
}
}
invoke方法在解析每一行数据时被调用。
将解析的行数据`t`添加到`cachedDataList`中。
如果cachedDataList中的数据条数达到100,则调用saveData方法将数据批量插入数据库,并清空cachedDataList以便回收内存。
5.3.2doAfterAllAnalysed方法
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
saveData();
}
doAfterAllAnalysed方法在所有数据解析完毕后被调用。
确保最后遗留的数据也被插入数据库。
5.3.3saveData方法
private void saveData() {
categoryMapper.batchInsert((List<CategoryExcelVo>) cachedDataList);
}
saveData方法将cachedDataList中的数据批量插入数据库。
使用categoryMapper的batchInsert方法进行批量插入。
主要用途是在解析Excel文件时,将数据批量插入数据库,以提高处理效率和性能。
5.4实现读
@Override
public void importData(MultipartFile file) {
ExcelListener<CategoryExcelVo> excelListener = new ExcelListener(categoryMapper);
try {
EasyExcel.read(file.getInputStream(), CategoryExcelVo.class, excelListener).sheet().doRead();
} catch (Exception e) {
e.printStackTrace();
throw new CustomException(ResultCodeEnum.DATA_ERROR);
}
}

1274

被折叠的 条评论
为什么被折叠?



