EasyExcel的简单使用

什么是EasyExcel?

是阿里巴巴开源的excel处理框架,以使用简单,节省内存著称,

在读取数据的时候是从磁盘一行一行的读取数据,逐个解析,而不是全部加载到内存中。

支持Excel的导入与导出,支持xls和xlsm的文件格式

EasyExcel的依赖

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>2.0.5</version>
</dependency>

数据导出

导出测试

使用相关API进行数据的导出

EasyExcel.write(IO流/文件名,数据类型).sheet(文件名).doWrite(数据列表)

public class TsetWrite {
    public static void main(String[] args) {
        //构建一个虚拟数据list集合
        List list = new ArrayList();
        for(int i=0;i<10;i++)
        {
            UserData userData = new UserData();
            userData.setUid(i);
            userData.setUsername("alice"+i);
            list.add(userData);
        }
        //设置excel文件的路径和文件名
        String filename = "D:\\yygh_parent\\01.xlsx";
        //调用方法实现操作
        EasyExcel.write(filename, UserData.class).sheet("用户信息")
                .doWrite(list);
    }
}

项目实现

需要一个model模块添加导出实体

@Data
public class DictEeVo {
	@ExcelProperty(value = "id" ,index = 0)
	private Long id;
	@ExcelProperty(value = "上级id" ,index = 1)
	private Long parentId;
	@ExcelProperty(value = "名称" ,index = 2)
	private String name;
	@ExcelProperty(value = "值" ,index = 3)
	private String value;
	@ExcelProperty(value = "编码" ,index = 4)
	private String dictCode;
}

编写对应的service方法

    //导出数据字典接口
    @Override
    public void exportData(HttpServletResponse response) {
        //设置下载信息
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        String fileName = null;
        try {
            fileName = URLEncoder.encode("数据字典", "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        response.setHeader("Content-disposition", 
                "attachment;filename="+ fileName + ".xlsx");
        //查询数据库
        List<Dict> dictList = baseMapper.selectList(null);
        //将Dict类型数据转换成DictEeVo类型
        List<DictEeVo> dictVoList = new ArrayList<>();
        for(Dict dict:dictList) {
            DictEeVo dictEeVo = new DictEeVo();
            // dictEeVo.setId(dict.getId());
            BeanUtils.copyProperties(dict,dictEeVo);
            dictVoList.add(dictEeVo);
        }
        //调用方法进行写操作,使用流作为对象,将文件数据通过流的形式传递给用户
        try {
            EasyExcel.write(response.getOutputStream(), DictEeVo.class).sheet("dict")
                    .doWrite(dictVoList);
        } catch (IOException e) {
            e.printStackTrace();
        }

导入数据

创建回调监听器

导入数据要分配一个拦截器AnalysisEventListener

@Slf4j
public class DictListener extends AnalysisEventListener<DictEeVo> {
    
    @Autowired
    private DictMapper dictMapper;

    //一行一行的读取,读一行,写一行
    @Override
    public void invoke(DictEeVo dictEeVo, AnalysisContext analysisContext) {
        Dict dict = new Dict();
        //转换对象类
        BeanUtils.copyProperties(dictEeVo, dict);
        //写入数据库
        dictMapper.insert(dict);
    }

    //导入结束后执行
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        log.info("文件导入成功");
    }
}
@Slf4j
//@AllArgsConstructor //全参
@NoArgsConstructor //无参
public class ExcelDictDTOListener extends AnalysisEventListener<ExcelDictDTO> {

    /**
     * 每隔5条存储数据库,实际使用中可以3000条,然后清理list ,方便内存回收
     */
    private static final int BATCH_COUNT = 5;
    List<ExcelDictDTO> list = new ArrayList();

    private DictMapper dictMapper;

 //传入mapper对象
    public ExcelDictDTOListener(DictMapper dictMapper) {
        this.dictMapper = dictMapper;
    }

    /**
     *遍历每一行的记录
     * @param data
     * @param context
     */
    @Override
    public void invoke(ExcelDictDTO data, AnalysisContext context) {
        log.info("解析到一条记录: {}", data);
        list.add(data);
        // 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
        if (list.size() >= BATCH_COUNT) {
            saveData();
            // 存储完成清理 list
            list.clear();
        }
    }

    /**
     * 所有数据解析完成了 都会来调用
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        // 这里也要保存数据,确保最后遗留的数据也存储到数据库
        saveData();
        log.info("所有数据解析完成!");
    }

    /**
     * 加上存储数据库
     */
    private void saveData() {
        log.info("{}条数据,开始存储数据库!", list.size());
        dictMapper.insertBatch(list);  //批量插入
        log.info("存储数据库成功!");
    }
}

使用相关API进行数据的导如

EasyExcel.read(IO流/文件名,数据类型,数据类型对应的mapper映像 ​​​​​​​).sheet().doRead(数据列表)

    //导入数据
    @Override
    @CacheEvict(value = "dict",allEntries = true)
    public void importData(MultipartFile file) {
        try {
            EasyExcel.read(file.getInputStream(),DictEeVo.class,
                    new DictListener(dictMapper)).sheet().doRead();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sayhitoloverOvO

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值