zhang
2025-12-26 9569af2a6abcccc3f312abff0a7e660c0f2be2c8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
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("存储数据库成功!");
    }
}