EasyExcel listener无法通过Autowired注入xxMapper

easyexcel listener无法通过Autowired注入xxMapper

文章目录

bug记录:

productMapper注入一直为null,而procureDetailMapper却正常注入?

java 复制代码
@Slf4j
@Component
public class ProductInfoExcelListener<T> extends AnalysisEventListener<T> {


    /**
     * 缓存的数据
     */
    private List<ProductEntity> cachedDataList = ListUtils.newArrayList();

    /**
     * 存临时表的数据
     */
//    private List<ProcureDetailEntity> tempDataList = ListUtils.newArrayList();
    private final StringBuilder errMsg = new StringBuilder();

    private boolean hasException = false;

    private boolean hasNext = true;
    private IProcureDetailMapper procureDetailMapper;

    @Autowired
    private IProductMapper productMapper;

    public ProductInfoExcelListener(IProcureDetailMapper procureDetailMapper) {
        this.procureDetailMapper = procureDetailMapper;
    }

    // 每解析一行数据就会调用一次该方法 todo

    @Override
    public void invoke(T t, AnalysisContext analysisContext) {

        // 获取行号
        int index = analysisContext.readRowHolder().getRowIndex() + 1;

        ProductExcelVo data = (ProductExcelVo) t;
        String productId = data.getProductId();

        String productNum = data.getProductNum();
        String categoryName = data.getCategoryName();
        String specName = data.getSpecName();
        if (!StringUtils.hasText(productId)) {
            hasException = true;
            setErrMsg(index, ":商品条码不能为空");
            return;
        }


        if (!StringUtils.hasText(productNum)) {
            hasException = true;
            setErrMsg(index, ":商品数量不能为空");
            return;
        }
        if (StringUtils.hasText(productNum)) {
            int productNumInteger = Integer.parseInt(productNum);
            if (productNumInteger <= 0) {
                hasException = true;
                setErrMsg(index, ":商品数量不能小于0");
                return;
            }

        }

        if (!StringUtils.hasText(categoryName)) {
            hasException = true;

            setErrMsg(index, ":分类名称不能为空");
            return;
        }

        //根据商品条码查询对应的分类信息
        ProductEntity productBaseDByProductId = productMapper.findProductBaseDByProductId(productId);
        if (productBaseDByProductId == null) {
            hasException = true;

            setErrMsg(index, ":该商品不存在");
            return;
        }
        if (!productBaseDByProductId.getCategoryName().equals(categoryName)) {
            hasException = true;

            setErrMsg(index, ":该商品的分类名称有误");
            return;
        }

        cachedDataList.add(productBaseDByProductId);
        log.info("invoke" + index);

    }


    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        // excel解析完毕以后需要执行的代码
//        saveData()
        log.info("doAfterAllAnalysed ");
    }

    public List getCachedDataList() {
        return cachedDataList;
    }

    private void setErrMsg(int index, String msg) {
        this.hasNext = false;
        this.hasException = true;
        errMsg.append("第").append(index).append(msg);
        log.error("row {} org data verify failure:{};", index, msg);
    }

    public StringBuilder getErrMsg() {
        return errMsg;
    }

    public boolean isHasException() {
        return hasException;
    }
}
java 复制代码
@Slf4j
@Service
@RequiredArgsConstructor(onConstructor_ = {@Autowired})
public class ProcureDetailServiceImpl implements IProcureDetailService {

    private final IProcureDetailMapper procureDetailMapper;

    @Override
    public ProductInfo uploadAndParseExcel(MultipartFile file) throws IOException, CustomException {


        ProductInfoExcelListener<ProductExcelVo> listener = new ProductInfoExcelListener<>(procureDetailMapper);
        EasyExcel.read(file.getInputStream(),
                ProductExcelVo.class,
                listener).sheet().doRead();
        System.out.println("*******************");
        System.out.println(listener.getCachedDataList().size() == 0);
        System.out.println("1111111111111111111");
        List<ProductEntity> cachedDataList = listener.getCachedDataList();
        log.info("isHasException:{}", listener.getErrMsg());
        if(listener.isHasException()){
            throw new CustomException(CommonConstant.ErrorConstants.EXCEL_UNKNOWN_ERROR.getCode(), listener.getErrMsg().toString());
        }
        for (ProductEntity p: cachedDataList){
            System.out.println(p.toString());
        }


        return null;
    }
}

springboot在listener和filter中注入mapper会为null?

解决方案:

  1. https://codeleading.com/article/13375080759/
  2. 构造器注入

easyexcel 使用例子

xml 复制代码
<dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
            <version>3.1.0</version>
        </dependency>

controller

java 复制代码
 @Slf4j
@RestController
@RequestMapping("/api-procure/procureController")
@RequiredArgsConstructor(onConstructor_ = {@Autowired})
public class ProcureController extends BaseController {

    private final IProcureDetailService procureDetailService;
  /**
     * 上传excel并且校验解析 procure
     *
     * @param file      excel
     * @param loginUser 登录用户
     * @return
     * @throws Exception
     */
    @PostMapping("/uploadExcel/procure")
    public Result<ProductInfo> uploadExcelP(@RequestBody MultipartFile file, @LoginUser LoginUserBean loginUser) throws Exception {
        log.info("upload excel file:{}", file.getName());
        ProductInfo data = procureDetailService.uploadAndParseExcel(file, loginUser, CommonConstant.Type.PROCURE.getCode());
        return Result.succeed(data, "上传成功");
    }
}

ServiceImpl

java 复制代码
@Slf4j
@Service
@RequiredArgsConstructor(onConstructor_ = {@Autowired})
public class ProcureDetailServiceImpl implements IProcureDetailService {

    private final IProcureDetailMapper procureDetailMapper;
    
@Override
    public ProductInfo uploadAndParseExcel(MultipartFile file, LoginUserBean loginUser, String type) throws IOException, CustomException {


        ProductInfoExcelListener<ProductExcelVo> listener = new ProductInfoExcelListener<>(procureDetailMapper, productMapper);
        EasyExcel.read(file.getInputStream(),
                ProductExcelVo.class,
                listener).sheet().doRead();

        if (listener.getCachedDataList().size() == 0) {
            throw new CustomException(CommonConstant.ErrorConstants.EXCEL_UNKNOWN_ERROR.getCode(), "没有有效数据");
        }
        List<ProcureDetailEntity> cachedDataList = listener.getCachedDataList();
        log.info("isHasException:{}", listener.getErrMsg());
        if (listener.isHasException()) {
            throw new CustomException(CommonConstant.ErrorConstants.EXCEL_UNKNOWN_ERROR.getCode(), listener.getErrMsg().toString());
        }
//        for (ProductEntity p : cachedDataList) {
//            System.out.println(p.toString());
//        }
        if (cachedDataList == null || cachedDataList.size() == 0) {
            throw new CustomException(CommonConstant.ErrorConstants.EXCEL_UNKNOWN_ERROR.getCode(), "未检测到有效数据");

        }

        String userId = loginUser.getUserId();
        Date date = new Date();


        //申请标号采购申请单ID 订单
        //"P"+YYYYMMDDHHMMSS+6位随机数  "PO"+YYYYMMDDHHMMSS+6位随机数
        String pattern = "YYYYMMDDHHMMSS";
        SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
        String format = dateFormat.format(date);
        int i = (int) ((Math.random() * 9 + 1) * 100000);
        String procureId;
        if (type.equals(CommonConstant.Type.PROCURE.getCode())) {
            procureId = "P" + format + i;
        } else if (type.equals(CommonConstant.Type.ORDER.getCode())) {
            procureId = "PO" + format + i;
        } else {
            procureId = null;
            log.info("这一步执行到就完蛋了");
        }


        //存入t_procure_detail_tmp表
        procureDetailMapper.batchInsertProcureDetailTempList(procureId, userId, date, cachedDataList);


        //返回响应实体列表
        ProductInfo productInfo = new ProductInfo();
        List<ProcureDetailEntity> list = cachedDataList.stream().map(e -> {
            e.setProcureId(procureId);
            return e;
        }).collect(Collectors.toList());

        productInfo.setProductList(list);
        return productInfo;
    }
}

listener

java 复制代码
/**
 * @description <采购申请解析返回的excel信息监听器>
 * <p>
 * <p>
 * 解析模板导入的数据,对商品条码、分类名称、规格名称校验其有效性是否存在,对数量校验大于0.其数据保存在采购单商品临时表.
 * @author: zhouchaoyu
 * @Date: 2023-11-14
 */
@Slf4j
@Component
public class ProductInfoExcelListener<T> extends AnalysisEventListener<T> {


    /**
     * 缓存的数据
     */
    private List<ProcureDetailEntity> cachedDataList = ListUtils.newArrayList();

    /**
     * 存临时表的数据
     */
//    private List<ProcureDetailEntity> tempDataList = ListUtils.newArrayList();
    private final StringBuilder errMsg = new StringBuilder();

    private boolean hasException = false;

    private boolean hasNext = true;
    private IProcureDetailMapper procureDetailMapper;

    private IProductMapper productMapper;

    public ProductInfoExcelListener(IProcureDetailMapper procureDetailMapper, IProductMapper productMapper) {
        this.procureDetailMapper = procureDetailMapper;
        this.productMapper = productMapper;
    }

    // 每解析一行数据就会调用一次该方法 todo

    @Override
    public void invoke(T t, AnalysisContext analysisContext) {

        // 获取行号
        int index = analysisContext.readRowHolder().getRowIndex() + 1;

        ProductExcelVo data = (ProductExcelVo) t;
        String productId = data.getProductId();

        String productNum = data.getProductNum();
        String categoryName = data.getCategoryName();
        String specName = data.getSpecName();
        if (!StringUtils.hasText(productId)) {
            hasException = true;
            setErrMsg(index, ":商品条码不能为空");
            return;
        }


        if (!StringUtils.hasText(productNum)) {
            hasException = true;
            setErrMsg(index, ":商品数量不能为空");
            return;
        }
        if (StringUtils.hasText(productNum)) {
            int productNumInteger = Integer.parseInt(productNum);
            if (productNumInteger <= 0) {
                hasException = true;
                setErrMsg(index, ":商品数量不能小于0");
                return;
            }

        }

        if (!StringUtils.hasText(categoryName)) {
            hasException = true;

            setErrMsg(index, ":分类名称不能为空");
            return;
        }

        //根据商品条码查询对应的分类信息
        ProductEntity productBaseDByProductId = productMapper.findProductBaseDByProductId(productId);
        if (productBaseDByProductId == null) {
            hasException = true;

            setErrMsg(index, ":该商品不存在");
            return;
        }
        if (!productBaseDByProductId.getCategoryName().equals(categoryName)) {
            hasException = true;

            setErrMsg(index, ":该商品的分类名称有误");
            return;
        }
        String uid = IdGenerator.getIdStr() ;

        ProcureDetailEntity procureDetailEntity = new ProcureDetailEntity();
        procureDetailEntity.setId(uid);
        procureDetailEntity.setProductId(productBaseDByProductId.getProductId());
        procureDetailEntity.setProductNum(Integer.parseInt(productNum));
        procureDetailEntity.setCategoryId(productBaseDByProductId.getCategoryId());
        procureDetailEntity.setSpecId(specName);
        procureDetailEntity.setRowStatus("1");
        procureDetailEntity.setProductName(productBaseDByProductId.getProductName());
        procureDetailEntity.setCategoryName(productBaseDByProductId.getCategoryName());
        procureDetailEntity.setInventoryCount(productBaseDByProductId.getInventoryCount());

        BigDecimal costPrice = productBaseDByProductId.getCostPrice();
        BigDecimal totalPrice = costPrice.multiply(new BigDecimal(productNum)).setScale(2, RoundingMode.HALF_UP);
        procureDetailEntity.setTotalPrice(totalPrice);

        cachedDataList.add(procureDetailEntity);
        log.info("invoke" + index);

    }


    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        // excel解析完毕以后需要执行的代码
//        saveData()
        log.info("doAfterAllAnalysed ");
    }

    public List<ProcureDetailEntity> getCachedDataList() {
        return cachedDataList;
    }

    private void setErrMsg(int index, String msg) {
        this.hasNext = false;
        this.hasException = true;
        errMsg.append("第").append(index).append(msg);
        log.error("row {} org data verify failure:{};", index, msg);
    }

    public StringBuilder getErrMsg() {
        return errMsg;
    }

    public boolean isHasException() {
        return hasException;
    }
}
相关推荐
程序媛小果6 分钟前
基于java+SpringBoot+Vue的宠物咖啡馆平台设计与实现
java·vue.js·spring boot
追风林12 分钟前
mac m1 docker本地部署canal 监听mysql的binglog日志
java·docker·mac
芒果披萨26 分钟前
El表达式和JSTL
java·el
许野平1 小时前
Rust: 利用 chrono 库实现日期和字符串互相转换
开发语言·后端·rust·字符串·转换·日期·chrono
duration~1 小时前
Maven随笔
java·maven
zmgst1 小时前
canal1.1.7使用canal-adapter进行mysql同步数据
java·数据库·mysql
跃ZHD1 小时前
前后端分离,Jackson,Long精度丢失
java
blammmp2 小时前
Java:数据结构-枚举
java·开发语言·数据结构
暗黑起源喵2 小时前
设计模式-工厂设计模式
java·开发语言·设计模式
WaaTong2 小时前
Java反射
java·开发语言·反射