拿捏EasyExcel

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);
        }
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值