|
@@ -0,0 +1,152 @@
|
|
|
|
+package com.iohao.mmo.excel.listener;
|
|
|
|
+
|
|
|
|
+import com.alibaba.excel.context.AnalysisContext;
|
|
|
|
+import com.alibaba.excel.event.AnalysisEventListener;
|
|
|
|
+import com.alibaba.excel.metadata.CellExtra;
|
|
|
|
+import com.alibaba.fastjson2.JSONObject;
|
|
|
|
+import com.fasterxml.jackson.core.JsonProcessingException;
|
|
|
|
+import com.iohao.mmo.common.kit.ConvertKit;
|
|
|
|
+import com.iohao.mmo.equip.entity.EquipProperty;
|
|
|
|
+import com.iohao.mmo.equip.entity.EquipTemplate;
|
|
|
|
+import com.iohao.mmo.equip.entity.EquipTemplate;
|
|
|
|
+import com.iohao.mmo.excel.dto.EquipTemplateExcelDTO;
|
|
|
|
+import com.iohao.mmo.excel.service.EquipTemplateExcelService;
|
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
|
+import org.slf4j.Logger;
|
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
|
+
|
|
|
|
+import java.util.ArrayList;
|
|
|
|
+import java.util.Arrays;
|
|
|
|
+import java.util.List;
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * 装备模板excel(公共列未合并)
|
|
|
|
+ *
|
|
|
|
+ * @author Toby javatangbin@163.com
|
|
|
|
+ */
|
|
|
|
+public class EquipTemplateExcelListener<E, T> extends AnalysisEventListener<T> {
|
|
|
|
+ private static final Logger LOGGER = LoggerFactory.getLogger(EquipTemplateExcelListener.class);
|
|
|
|
+ /**
|
|
|
|
+ * 每隔2000条存储数据库,然后清理list,方便内存回收
|
|
|
|
+ */
|
|
|
|
+ private static final int BATCH_COUNT = 2000;
|
|
|
|
+ private final List<EquipTemplate> equipTemplateList = new ArrayList<>();
|
|
|
|
+
|
|
|
|
+ private EquipTemplate nowEquipTemplate;
|
|
|
|
+ private final List<EquipProperty> equipPropertyList = new ArrayList<>();
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 通过构造器注入Service
|
|
|
|
+ */
|
|
|
|
+ private final EquipTemplateExcelService equipTemplateExcelService;
|
|
|
|
+ /**
|
|
|
|
+ * 表头行数
|
|
|
|
+ */
|
|
|
|
+ int headRowNumber = 1;
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 构造方法
|
|
|
|
+ *
|
|
|
|
+ * @param equipTemplateExcelService Service对象
|
|
|
|
+ */
|
|
|
|
+ public EquipTemplateExcelListener(EquipTemplateExcelService equipTemplateExcelService, int headRowNumber) {
|
|
|
|
+ this.equipTemplateExcelService = equipTemplateExcelService;
|
|
|
|
+ this.headRowNumber = headRowNumber;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 每条数据解析完,都会调用此方法
|
|
|
|
+ */
|
|
|
|
+ @Override
|
|
|
|
+ public void invoke(T data, AnalysisContext context) {
|
|
|
|
+ LOGGER.info("解析到一条数据:{}", JSONObject.toJSONString(data));
|
|
|
|
+ EquipTemplateExcelDTO excel = ConvertKit.sourceToTarget(data, EquipTemplateExcelDTO.class);
|
|
|
|
+ // (关键部分)这里对数据做自定义设置,如果一级类字段不为空,则一级类取本条数据新导入的,反之取缓存里面的
|
|
|
|
+ if(StringUtils.isNotBlank(excel.getCode())){
|
|
|
|
+ //拷贝一级类属性
|
|
|
|
+ nowEquipTemplate = ConvertKit.sourceToTarget(excel, EquipTemplate.class);
|
|
|
|
+ //一级类自定义属性
|
|
|
|
+ if(StringUtils.isNotBlank(excel.getPositionStrs())) {
|
|
|
|
+ nowEquipTemplate.setPositionList(Arrays.stream(excel.getPositionStrs().split("-")).toList());
|
|
|
|
+ }
|
|
|
|
+ //将一级类加入缓存list
|
|
|
|
+ equipTemplateList.add(nowEquipTemplate);
|
|
|
|
+ }
|
|
|
|
+ //拷贝二级类属性
|
|
|
|
+ EquipProperty equipProperty = ConvertKit.sourceToTarget(excel, EquipProperty.class);
|
|
|
|
+ //把二级类放入一级类的子列表中
|
|
|
|
+ List<EquipProperty> lastPropertyList = nowEquipTemplate.getPropertyList();
|
|
|
|
+ if(lastPropertyList==null){
|
|
|
|
+ lastPropertyList = new ArrayList<>();
|
|
|
|
+ }
|
|
|
|
+ lastPropertyList.add(equipProperty);
|
|
|
|
+ nowEquipTemplate.setPropertyList(lastPropertyList);
|
|
|
|
+
|
|
|
|
+ // 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
|
|
|
|
+ if (equipTemplateList.size() >= BATCH_COUNT) {
|
|
|
|
+ saveData();
|
|
|
|
+ // 存储完成清理 list
|
|
|
|
+ equipTemplateList.clear();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ @Override
|
|
|
|
+ public void extra(CellExtra extra, AnalysisContext context) {
|
|
|
|
+ switch (extra.getType()) {
|
|
|
|
+ case COMMENT: {
|
|
|
|
+ LOGGER.info("额外信息是批注,在rowIndex:{},columnIndex;{},内容是:{}", extra.getRowIndex(), extra.getColumnIndex(),
|
|
|
|
+ extra.getText());
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ case HYPERLINK: {
|
|
|
|
+ if ("Sheet1!A1".equals(extra.getText())) {
|
|
|
|
+ LOGGER.info("额外信息是超链接,在rowIndex:{},columnIndex;{},内容是:{}", extra.getRowIndex(),
|
|
|
|
+ extra.getColumnIndex(), extra.getText());
|
|
|
|
+ } else if ("Sheet2!A1".equals(extra.getText())) {
|
|
|
|
+ LOGGER.info(
|
|
|
|
+ "额外信息是超链接,而且覆盖了一个区间,在firstRowIndex:{},firstColumnIndex;{},lastRowIndex:{},lastColumnIndex:{},"
|
|
|
|
+ + "内容是:{}",
|
|
|
|
+ extra.getFirstRowIndex(), extra.getFirstColumnIndex(), extra.getLastRowIndex(),
|
|
|
|
+ extra.getLastColumnIndex(), extra.getText());
|
|
|
|
+ } else {
|
|
|
|
+ LOGGER.info("Unknown hyperlink!");
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ case MERGE: {
|
|
|
|
+ LOGGER.info(
|
|
|
|
+ "额外信息是合并单元格,而且覆盖了一个区间,在firstRowIndex:{},firstColumnIndex;{},lastRowIndex:{},lastColumnIndex:{}",
|
|
|
|
+ extra.getFirstRowIndex(), extra.getFirstColumnIndex(), extra.getLastRowIndex(),
|
|
|
|
+ extra.getLastColumnIndex());
|
|
|
|
+ if (extra.getRowIndex() >= headRowNumber) {
|
|
|
|
+// extraMergeInfoList.add(extra);
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ default: {
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 所有数据解析完成了 都会来调用
|
|
|
|
+ */
|
|
|
|
+ @Override
|
|
|
|
+ public void doAfterAllAnalysed(AnalysisContext context) {
|
|
|
|
+ // 这里也要保存数据,确保最后遗留的数据也存储到数据库
|
|
|
|
+ saveData();
|
|
|
|
+ LOGGER.info("所有数据解析完成!");
|
|
|
|
+ }
|
|
|
|
+ /**
|
|
|
|
+ * 加上存储数据库
|
|
|
|
+ */
|
|
|
|
+ private void saveData() {
|
|
|
|
+ LOGGER.info("{}条数据,开始存储数据库!", equipTemplateList.size());
|
|
|
|
+ try {
|
|
|
|
+ //根据code批量更新或者插入
|
|
|
|
+ equipTemplateExcelService.updateBatch(equipTemplateList);
|
|
|
|
+ } catch (JsonProcessingException e) {
|
|
|
|
+ throw new RuntimeException(e);
|
|
|
|
+ }
|
|
|
|
+ LOGGER.info("存储数据库成功!");
|
|
|
|
+ }
|
|
|
|
+}
|