springboot整合easyexcel实现不固定列导入

1、pom.xml文件引入easyExcel

		<!--阿里开源easyExcel依赖-->
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>easyexcel</artifactId>
			<version>2.2.10</version>
		</dependency>
		
		<dependency>
			<groupId>org.apache.poi</groupId>
			<artifactId>poi</artifactId>
			<version>3.17</version>
		</dependency>

2、导入监听类

package com.tool.pc.utils;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.tool.pc.service.UsersService;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Data
@Slf4j
public class ExcelImoprtListener extends AnalysisEventListener<Map<Integer, String>> {
    //定义每多少条数据进行数据库保存
    private static final int BATCH_COUNT = 128;
    //自己实现service层,我这里用的用户表来演示
    private UsersService usersService;
    //用list集合保存解析到的结果
    private List<Map<Integer, String>> list;
    //部门id,需要传入的参数可以自己定义
    private Integer deptId;

    //重构,把传来的值赋给对应的属性
    public ExcelImoprtListener(UsersService usersService, Integer deptId) {
        this.usersService = usersService;
        this.deptId = deptId;
        list = new ArrayList<>();
    }

    /**
     * 重写invokeHeadMap方法,获去表头,如果有需要获取第一行表头就重写这个方法,不需要则不需要重写
     *
     * @param headMap Excel每行解析的数据为Map<Integer, String>类型,Integer是Excel的列索引,String为Excel的单元格值
     * @param context context能获取一些东西,比如context.readRowHolder().getRowIndex()为Excel的行索引,表头的行索引为0,0之后的都解析成数据
     */
    @Override
    public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
        log.info("解析到一条头数据:{}, currentRowHolder: {}", headMap.toString(), 			context.readRowHolder().getRowIndex());
        list.add(headMap);
    }

    /**
     * 重写invoke方法获得除Excel第一行表头之后的数据,
     * 如果Excel第二行也是表头,那么也会解析到这里,如果不需要就通过判断context.readRowHolder().getRowIndex()跳过
     *
     * @param data    除了第一行表头外,数据都会解析到这个方法
     * @param context 和上面解释一样
     */
    @Override
    public void invoke(Map<Integer, String> data, AnalysisContext context) {
        log.info("解析到一条数据:{}, currentRowIndex: {}----", data.toString(), context.readRowHolder().getRowIndex());
        list.add(data);
        // 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
        if (list.size() >= BATCH_COUNT) {
            saveData();
            // 存储完成清理 list
            list.clear();
        }
    }

    /**
     * 解析到最后会进入这个方法,需要重写这个doAfterAllAnalysed方法,然后里面调用自己定义好保存方法
     * @param context
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        // 这里也要保存数据,确保最后遗留的数据也存储到数据库
        saveData();
        log.info("所有数据解析完成!");
    }

    /**
     * 加上存储数据库
     */
    private void saveData() {
        log.info("{}条数据,开始存储数据库!", list.size());
        //这里自行实现service层方法存储数据库
        usersService.saveList(list,deptId);

    }

}

3、Controller方法

 /**
     * 导入
     * @param file
     * @param deptId 部门id
     * @author
     * @date 
     * @return 
     */
    @PostMapping("/limitImport")
    public void limitImport(@RequestParam("file") MultipartFile file,
                                  @RequestParam("deptId") Integer deptId) throws IOException {
        //初始化监听器
        ExcelImoprtListener excelImoprtListener = new ExcelImoprtListener(usersService,deptId);
        //解析数据
        EasyExcel.read(file.getInputStream(), excelImoprtListener).sheet(0).doReadSync();

    }

4、导入模板

在这里插入图片描述
在这里插入图片描述

5、效果查看

在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值