package com.zy.acs.manager.manager.controller.utils;
|
|
import com.alibaba.excel.context.AnalysisContext;
|
import com.alibaba.excel.read.listener.ReadListener;
|
import com.alibaba.fastjson.JSON;
|
import com.google.common.collect.Lists;
|
import com.zy.acs.common.utils.GsonUtils;
|
import com.zy.acs.framework.common.Cools;
|
import com.zy.acs.manager.manager.entity.Code;
|
import com.zy.acs.manager.manager.entity.CodeGap;
|
import com.zy.acs.manager.manager.entity.Route;
|
import com.zy.acs.manager.manager.service.CodeGapService;
|
import com.zy.acs.manager.manager.service.CodeService;
|
import com.zy.acs.manager.manager.service.RouteService;
|
import lombok.extern.slf4j.Slf4j;
|
|
import java.util.*;
|
|
@Slf4j
|
public class MapDataListener implements ReadListener<Map<Integer, String>> {
|
/**
|
* 每隔5条存储数据库,实际使用中可以100条,然后清理list ,方便内存回收
|
*/
|
private static final int BATCH_COUNT = 10000;
|
private List<Map<Integer, String>> cachedDataList = Lists.newArrayListWithExpectedSize(BATCH_COUNT);
|
/**
|
* 假设这个是一个DAO,当然有业务逻辑这个也可以是一个service。当然如果不用存储这个对象没用。
|
*/
|
private RouteService routeService;
|
|
private CodeService codeService;
|
|
private CodeGapService codeGapService;
|
|
private List<Code> codes = new ArrayList<>();
|
|
private List<Route> routes = new ArrayList<>();
|
|
private List<CodeGap> codeGaps = new ArrayList<>();
|
|
/**
|
* 如果使用了spring,请使用这个构造方法。每次创建Listener的时候需要把spring管理的类传进来
|
*
|
* @param routeService
|
*/
|
public MapDataListener(RouteService routeService, CodeService codeService, CodeGapService codeGapService) {
|
this.routeService = routeService;
|
this.codeService = codeService;
|
this.codeGapService = codeGapService;
|
}
|
|
|
/**
|
* 这个每一条数据解析都会来调用
|
*
|
* @param data one row value. It is same as {@link AnalysisContext#readRowHolder()}
|
* @param context
|
*/
|
@Override
|
public void invoke(Map<Integer, String> data, AnalysisContext context) {
|
log.info("解析到一条数据:{}", JSON.toJSONString(data));
|
cachedDataList.add(data);
|
// 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
|
if (cachedDataList.size() >= BATCH_COUNT) {
|
saveData();
|
// 存储完成清理 list
|
cachedDataList = Lists.newArrayListWithExpectedSize(BATCH_COUNT);
|
}
|
}
|
|
|
/**
|
* 所有数据解析完成了 都会来调用
|
*
|
* @param context
|
*/
|
@Override
|
public void doAfterAllAnalysed(AnalysisContext context) {
|
// 这里也要保存数据,确保最后遗留的数据也存储到数据库
|
Map<Integer, String> xData = cachedDataList.get(78);
|
Map<Integer, String> x = new HashMap<>();
|
xData.entrySet().forEach(entry -> {
|
x.put(entry.getKey() , entry.getValue());
|
});
|
Map<Integer, String> y = new HashMap<>();
|
for (int i = 0; i < cachedDataList.size(); i++) {
|
Map<Integer, String> integerStringMap = cachedDataList.get(i);
|
y.put(i, integerStringMap.get(1));
|
}
|
log.info("x轴:{}", JSON.toJSONString(x));
|
log.info("y轴:{}", JSON.toJSONString(y));
|
for (int i = 0; i < cachedDataList.size(); i++) {
|
if (i >= 78) {
|
continue;
|
}
|
Map<Integer, String> integerStringMap = cachedDataList.get(i);
|
int finalI = i;
|
integerStringMap.entrySet().forEach(entry -> {
|
if (entry.getValue() != null && entry.getValue().startsWith("00")) {
|
log.info("数据:{}", entry.getValue());
|
Code code = new Code();
|
code.setData(entry.getValue());
|
code.setUuid("code".concat(code.getData()));
|
if (x.get(entry.getKey()) == null) {
|
log.info("x轴数据为空:{}", entry.getKey());
|
}
|
code.setX(Double.parseDouble(x.get(entry.getKey()))+10000);
|
if (y.get(finalI) == null) {
|
log.info("y轴数据为空:{},{}", finalI, y.get(finalI));
|
}
|
code.setY(Double.parseDouble(y.get(finalI))+10000);
|
code.setScale(GsonUtils.toJson(Cools.add("x", 1).add("y", 1)));
|
code.setCreateTime(new Date());
|
code.setUpdateTime(new Date());
|
codes.add(code);
|
|
|
|
}
|
});
|
}
|
//log.info("所有数据解析完成!{}", JSON.toJSONString(codes));
|
log.info("所有数据解析完成!{}", codes.size());
|
saveData();
|
}
|
|
|
/**
|
* 加上存储数据库
|
*/
|
private void saveData() {
|
log.info("{}条数据,开始存储数据库!", cachedDataList.size());
|
for (Code code : codes){
|
codeService.save(code);
|
}
|
log.info("存储数据库成功!");
|
}
|
}
|