easyexcel listener无法通过Autowired注入xxMapper
文章目录
- easyexcel listener无法通过Autowired注入xxMapper
- bug记录:
- 解决方案:
- easyexcel 使用例子
- controller
- ServiceImpl
- listener
bug记录:
productMapper注入一直为null,而procureDetailMapper却正常注入?
@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;@Autowiredprivate IProductMapper productMapper;public ProductInfoExcelListener(IProcureDetailMapper procureDetailMapper) {this.procureDetailMapper = procureDetailMapper;}// 每解析一行数据就会调用一次该方法 todo@Overridepublic 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);}@Overridepublic 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;}
}
@Slf4j
@Service
@RequiredArgsConstructor(onConstructor_ = {@Autowired})
public class ProcureDetailServiceImpl implements IProcureDetailService {private final IProcureDetailMapper procureDetailMapper;@Overridepublic 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?
解决方案:
- https://codeleading.com/article/13375080759/
- 构造器注入
easyexcel 使用例子
<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.1.0</version></dependency>
controller
@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
@Slf4j
@Service
@RequiredArgsConstructor(onConstructor_ = {@Autowired})
public class ProcureDetailServiceImpl implements IProcureDetailService {private final IProcureDetailMapper procureDetailMapper;@Overridepublic 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
/*** @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@Overridepublic 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);}@Overridepublic 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;}
}