Quellcode durchsuchen

一大堆导出搞定了

wukai vor 11 Monaten
Ursprung
Commit
e80fe3feca

+ 312 - 79
ruoyi-admin/src/main/java/com/ruoyi/biz/controller/ApiController.java

@@ -8,7 +8,6 @@ import com.ruoyi.common.core.controller.BaseController;
 import com.ruoyi.common.core.domain.R;
 import com.ruoyi.common.utils.CacheUtils;
 import com.ruoyi.common.utils.DateUtils;
-import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.system.service.ISysConfigService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
@@ -24,15 +23,16 @@ import java.io.BufferedOutputStream;
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.OutputStream;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
 import java.net.URLEncoder;
 import java.text.ParseException;
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.time.ZoneOffset;
+import java.time.*;
 import java.util.*;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
 import java.util.stream.Collectors;
 
 /**
@@ -52,6 +52,10 @@ public class ApiController extends BaseController {
     @Resource
     private ITwinRecordAlarmsService recordAlarmsService;
     @Resource
+    private ITwinCalcStopService stopService;
+    @Resource
+    private ITwinCalcAlarmsService alarmsService;
+    @Resource
     private ITwinDeviceService deviceService;
     @Resource
     private IIotService iotService;
@@ -67,6 +71,12 @@ public class ApiController extends BaseController {
     private String formulaExcelTemplate;
     @Value("${excel.gram}")
     private String gramExcelTemplate;
+    @Value("${excel.stops}")
+    private String stopsExcelTemplate;
+    @Value("${excel.stopsType}")
+    private String stopsTypeExcelTemplate;
+    @Value("${excel.alarms}")
+    private String alarmsExcelTemplate;
 
     @ApiOperation("在线设备")
     @GetMapping("/device/online")
@@ -153,9 +163,9 @@ public class ApiController extends BaseController {
     }
 
     @ApiOperation("送经量")
-    @GetMapping("/warp/run-in")
+    @GetMapping("/export/warp-run-in")
     @CrossOrigin(origins = "*")
-    public void warpRunIn(HttpServletResponse response) {
+    public void warpRunInExport(HttpServletResponse response) {
         Object d = CacheUtils.get(Constants.IOT_TOKEN, Constants.INDEX_WARP_RUN_IN);
         if (d != null) {
             List<WarpRunIn> list = (List<WarpRunIn>) d;
@@ -238,7 +248,7 @@ public class ApiController extends BaseController {
     }
 
     @ApiOperation("平方米克重导出")
-    @GetMapping("/gram-mass/export")
+    @GetMapping("/export/gram-mass")
     @CrossOrigin(origins = "*")
     public void gramMassExport(HttpServletResponse response) {
         Object total = CacheUtils.get(Constants.IOT_TOKEN, Constants.INDEX_GRAM_MASS);
@@ -365,86 +375,309 @@ public class ApiController extends BaseController {
         }
     }
 
-
-    @ApiOperation("导出Excel")
-    @GetMapping("/export")
+    @ApiOperation("导出产量数据")
+    @GetMapping("/export/production")
     @CrossOrigin(origins = "*")
-    public void export(String start, String end, HttpServletResponse response) {
-        Date startD = null;
-        Date endD = null;
-        if (StringUtils.isNotEmpty(start) && StringUtils.isNotEmpty(end)) {
-            try {
-                startD = DateUtils.parseDate(start + " 00:00:00", DateUtils.YYYY_MM_DD_HH_MM_SS);
-                endD = DateUtils.parseDate(end + " 23:59:59", DateUtils.YYYY_MM_DD_HH_MM_SS);
-            } catch (ParseException ignored) {
+    public void productionExport(HttpServletResponse response) {
+        LocalDateTime ldt = LocalDateTime.now();
+        if (ldt.getHour() < 7) {
+            ldt = ldt.minusDays(1);
+        }
+        LocalDate localDate = ldt.toLocalDate().minusDays(7);
+        Date date = Date.from(localDate.atStartOfDay(ZoneOffset.of("+8")).toInstant());
+        List<TwinCalcDay> list = twinCalcDayService.selectTwinCalcDayListByTime(date);
+        try (FileInputStream inputStream = new FileInputStream(totalExcelTemplate); Workbook wb = new XSSFWorkbook(inputStream); OutputStream outputStream = new BufferedOutputStream(response.getOutputStream())) {
+            CreationHelper creationHelper = wb.getCreationHelper();
+            CellStyle percentStyle = wb.createCellStyle();
+            percentStyle.setDataFormat(creationHelper.createDataFormat().getFormat("0.00%"));
+            CellStyle p2 = wb.createCellStyle();
+            p2.setDataFormat(wb.createDataFormat().getFormat("0.00"));
+
+            Map<Date, List<TwinCalcDay>> dayGroup = list.stream().collect(Collectors.groupingBy(TwinCalcDay::getTime, LinkedHashMap::new, Collectors.toList()));
+            for (Map.Entry<Date, List<TwinCalcDay>> entry : dayGroup.entrySet()) {
+                Sheet sheet = wb.cloneSheet(0);
+                wb.setSheetName(wb.getSheetIndex(sheet), DateUtils.parseDateToStr("yyyy-MM-dd", entry.getKey()));
+                List<TwinCalcDay> days = entry.getValue();
+                AtomicInteger rowNum = new AtomicInteger(2);
+                days.forEach(day -> {
+                    Row row = sheet.createRow(rowNum.get());
+                    Cell[] cells = new Cell[25];
+                    for (int i = 0; i < cells.length; i++) {
+                        cells[i] = row.createCell(i);
+                    }
+                    day.setCells(cells);
+                    rowNum.getAndIncrement();
+                });
             }
+
+            wb.removeSheetAt(0);
+            // 清空response
+            response.reset();
+            // 设置response的Header
+            response.setCharacterEncoding("UTF-8");
+            //Content-Disposition的作用:告知浏览器以何种方式显示响应返回的文件,用浏览器打开还是以附件的形式下载到本地保存
+            //attachment表示以附件方式下载 inline表示在线打开 "Content-Disposition: inline; filename=文件名.mp3"
+            // filename表示文件的默认名称,因为网络传输只支持URL编码的相关支付,因此需要将文件名URL编码后进行传输,前端收到后需要反编码才能获取到真正的名称
+            response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("最近7天产量统计" + System.currentTimeMillis() + ".xlsx", "UTF-8"));
+            response.setContentType("application/octet-stream");
+            wb.write(outputStream);
+            outputStream.flush();
+        } catch (IOException ex) {
+            ex.printStackTrace();
         }
-        if (startD == null) {
-            LocalDate localDate = LocalDate.now().minusDays(7);
-            startD = Date.from(localDate.atStartOfDay(ZoneOffset.of("+8")).toInstant());
+    }
+
+    @ApiOperation("导出停机数据")
+    @GetMapping("/export/stops")
+    @CrossOrigin(origins = "*")
+    public void stopsExport(String start, String end, HttpServletResponse response) throws ParseException {
+        Date sTime = DateUtils.parseDate(start, DateUtils.YYYY_MM_DD_HH_MM_SS);
+        Date eTime = DateUtils.parseDate(end, DateUtils.YYYY_MM_DD_HH_MM_SS);
+        List<TwinCalcStop> list = stopService.selectTwinCalcStopListByDate(sTime, eTime);
+        Map<Integer, List<TwinCalcStop>> stopDeviceGroup = list.stream().collect(Collectors.groupingBy(TwinCalcStop::getStopType, LinkedHashMap::new, Collectors.toList()));
+        //1停经片停机,2-CCD停机(相机号+断纱/故障),3-人工停机,4-断电停机,5-设备故障停机,6-落布米数达到停机,7-盘头剩余圈数达到停机
+        String[] stopStr = {"停经片停机", "CCD停机(相机号+断纱/故障)", "人工停机", "断电停机", "设备故障停机", "落布米数达到停机", "盘头剩余圈数达到停机"};
+        //停机次数
+        Integer[] stopNum = new Integer[7];
+        Integer totalNum = 0;
+        //停机时间
+        Long[] stopTime = new Long[7];
+        Arrays.fill(stopTime, 0L);
+        AtomicReference<Long> totalTime = new AtomicReference<>(0L);
+        for (Map.Entry<Integer, List<TwinCalcStop>> entry : stopDeviceGroup.entrySet()) {
+            Integer stopType = entry.getKey();
+            int pos = stopType - 1;
+            List<TwinCalcStop> stops = entry.getValue();
+            stopNum[pos] = stops.size();
+            totalNum += stops.size();
+            stops.forEach(stop -> {
+                // 调整停机时间
+                if (stop.getEndTime().compareTo(eTime) > 0) {
+                    stop.setEndTime(eTime);
+                }
+                //调整开机时间
+                if (stop.getStartTime().compareTo(sTime) < 0) {
+                    stop.setStartTime(sTime);
+                }
+                long t = (stop.getEndTime().getTime() - stop.getStartTime().getTime()) / 1000;
+                stopTime[pos] += t;
+                totalTime.updateAndGet(v -> v + t);
+            });
         }
-        List<TwinCalc2hr> list = calc2hrService.calc2hrList(startD, endD);
-        Map<String, Object> queryMap = new HashMap<>(16);
-        queryMap.put("start", startD);
-        queryMap.put("end", endD);
-        TwinRecordAlarms recordAlarms = new TwinRecordAlarms();
-        //TODO 需要改的
-//        recordAlarms.setAlarmType("stop");
-        recordAlarms.setParams(queryMap);
-        List<TwinRecordAlarms> alarms = recordAlarmsService.selectTwinRecordAlarmsList(recordAlarms);
-        // path是指想要下载的文件的路径
-        // 读取现有的xlsx文件
-        try (FileInputStream inputStream = new FileInputStream(totalExcelTemplate); Workbook wb = new XSSFWorkbook(inputStream); OutputStream outputStream = new BufferedOutputStream(response.getOutputStream())) {
-            Sheet sheet = wb.getSheetAt(0);
-            AtomicInteger rowNum = new AtomicInteger(2);
-            //填充数据
-            list.forEach(calc2hr -> {
+        try (FileInputStream inputStream = new FileInputStream(stopsExcelTemplate); Workbook wb = new XSSFWorkbook(inputStream); OutputStream outputStream = new BufferedOutputStream(response.getOutputStream())) {
+            CreationHelper creationHelper = wb.getCreationHelper();
+            CellStyle percentStyle = wb.createCellStyle();
+            percentStyle.setDataFormat(creationHelper.createDataFormat().getFormat("0.00%"));
+            CellStyle timeStyle = wb.createCellStyle();
+            timeStyle.setDataFormat(creationHelper.createDataFormat().getFormat(DateUtils.YYYY_MM_DD_HH_MM_SS));
+            Sheet sheetAt = wb.getSheetAt(0);
+            for (int i = 0; i < stopStr.length; i++) {
+                Row row = sheetAt.createRow(i + 1);
+                Cell[] cells = new Cell[5];
+                for (int j = 0; j < cells.length; j++) {
+                    cells[j] = row.createCell(j);
+                }
+                cells[0].setCellValue(stopStr[i]);
+                cells[1].setCellValue(stopNum[i]);
+                cells[2].setCellValue(stopTime[i]);
+                float percentNum = BigDecimal.valueOf(stopNum[i]).divide(BigDecimal.valueOf(totalNum), 4, RoundingMode.HALF_UP).floatValue();
+                float percentTimes = BigDecimal.valueOf(stopTime[i]).divide(BigDecimal.valueOf(totalTime.get()), 4, RoundingMode.HALF_UP).floatValue();
+                cells[3].setCellValue(percentNum);
+                cells[3].setCellStyle(percentStyle);
+                cells[4].setCellValue(percentTimes);
+                cells[4].setCellStyle(percentStyle);
+            }
+
+            Sheet sheet = wb.getSheetAt(1);
+            AtomicInteger rowNum = new AtomicInteger(1);
+            list.forEach(stop -> {
                 Row row = sheet.createRow(rowNum.get());
-                Cell[] cells = new Cell[25];
-                for (int i = 0; i < cells.length; i++) {
-                    cells[i] = row.createCell(i);
+                Cell[] cells = new Cell[4];
+                for (int j = 0; j < cells.length; j++) {
+                    cells[j] = row.createCell(j);
                 }
-                calc2hr.setCells(cells);
+
+                cells[0].setCellValue(stop.getDeviceId());
+                cells[1].setCellValue(stopStr[stop.getStopType() - 1]);
+                cells[2].setCellValue(stop.getStartTime());
+                cells[2].setCellStyle(timeStyle);
+                cells[3].setCellValue(stop.getEndTime());
+                cells[3].setCellStyle(timeStyle);
                 rowNum.getAndIncrement();
             });
 
-            AtomicInteger row1num = new AtomicInteger(1);
-            Sheet sheet1 = wb.getSheetAt(1);
-            //填充数据
-            alarms.forEach(alarm -> {
-                Row row = sheet1.createRow(row1num.get());
-                Cell cell = row.createCell(0);
-                cell.setCellValue(alarm.getRemark());
-                cell = row.createCell(1);
-                //TODO 需要改的
-                /*
-                cell.setCellValue(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, alarm.getStartTime()));
-                cell = row.createCell(2);
-                switch (alarm.getAlarmCode().intValue()) {
-                    case 1:
-                        cell.setCellValue("停经片停机");
-                        break;
-                    case 2:
-                        cell.setCellValue("CCD停机");
-                        break;
-                    case 3:
-                        cell.setCellValue("人工停机");
-                        break;
-                    case 4:
-                        cell.setCellValue("断电停机");
-                        break;
-                    case 5:
-                        cell.setCellValue("设备故障停机");
-                        break;
-                    case 6:
-                        cell.setCellValue("落布米数达到停机");
-                        break;
-                    case 7:
-                        cell.setCellValue("盘头剩余圈数达到停机");
-                        break;
-                    default:
-                }*/
-                row1num.getAndIncrement();
+            // 清空response
+            response.reset();
+            // 设置response的Header
+            response.setCharacterEncoding("UTF-8");
+            //Content-Disposition的作用:告知浏览器以何种方式显示响应返回的文件,用浏览器打开还是以附件的形式下载到本地保存
+            //attachment表示以附件方式下载 inline表示在线打开 "Content-Disposition: inline; filename=文件名.mp3"
+            // filename表示文件的默认名称,因为网络传输只支持URL编码的相关支付,因此需要将文件名URL编码后进行传输,前端收到后需要反编码才能获取到真正的名称
+            response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("停机分析" + System.currentTimeMillis() + ".xlsx", "UTF-8"));
+            response.setContentType("application/octet-stream");
+            wb.write(outputStream);
+            outputStream.flush();
+        } catch (IOException ex) {
+            ex.printStackTrace();
+        }
+    }
+
+    @ApiOperation("停机分类导出")
+    @GetMapping("/export/stops/type/{type}")
+    @CrossOrigin(origins = "*")
+    public void stopsTypeExport(@PathVariable Integer type, String start, String end, Integer st, Integer et, HttpServletResponse response) {
+        LocalDate s = LocalDate.parse(start);
+        LocalDate e = LocalDate.parse(end);
+        List<TwinCalcStop> list = new ArrayList<>();
+        do {
+            LocalDateTime ldtS = LocalDateTime.of(s, LocalTime.MIN).plusHours(st);
+            LocalDateTime ldtE = LocalDateTime.of(s, LocalTime.MIN).plusHours(et);
+            Date date = Date.from(ldtS.toLocalDate().atStartOfDay(ZoneOffset.of("+8")).toInstant());
+            Date sTime = Date.from(ldtS.atZone(ZoneId.systemDefault()).toInstant());
+            Date eTime = Date.from(ldtE.atZone(ZoneId.systemDefault()).toInstant());
+            List<TwinCalcStop> stopList = stopService.selectTwinCalcStopListByDate(sTime, eTime);
+            stopList.forEach(stop -> {
+                stop.setDataDate(date);
+            });
+            list.addAll(stopList);
+            s = s.plusDays(1);
+        } while (!s.isAfter(e));
+
+        List<TwinCalcStop> stopList = list.stream().filter(stop -> stop.getStopType().equals(type)).collect(Collectors.toList());
+
+        Map<Date, List<TwinCalcStop>> stopDateGroup = stopList.stream().collect(Collectors.groupingBy(TwinCalcStop::getDataDate, LinkedHashMap::new, Collectors.toList()));
+        //1停经片停机,2-CCD停机(相机号+断纱/故障),3-人工停机,4-断电停机,5-设备故障停机,6-落布米数达到停机,7-盘头剩余圈数达到停机
+        String[] stopStr = {"断纱", "断纱", "人工停机", "断电停机", "设备故障停机", "下卷", "叫料"};
+
+        try (FileInputStream inputStream = new FileInputStream(stopsTypeExcelTemplate); Workbook wb = new XSSFWorkbook(inputStream); OutputStream outputStream = new BufferedOutputStream(response.getOutputStream())) {
+            CreationHelper creationHelper = wb.getCreationHelper();
+            CellStyle percentStyle = wb.createCellStyle();
+            percentStyle.setDataFormat(creationHelper.createDataFormat().getFormat("0.00%"));
+            CellStyle timeStyle = wb.createCellStyle();
+            timeStyle.setDataFormat(creationHelper.createDataFormat().getFormat(DateUtils.YYYY_MM_DD_HH_MM_SS));
+            CellStyle dateStyle = wb.createCellStyle();
+            dateStyle.setDataFormat(creationHelper.createDataFormat().getFormat(DateUtils.YYYY_MM_DD));
+            CellStyle p2 = wb.createCellStyle();
+            p2.setDataFormat(wb.createDataFormat().getFormat("0.00"));
+            Sheet sheetAt = wb.getSheetAt(0);
+            int rowNum = 1;
+            AtomicInteger rs = new AtomicInteger(1);
+            for (Map.Entry<Date, List<TwinCalcStop>> entry : stopDateGroup.entrySet()) {
+                List<TwinCalcStop> stops = entry.getValue();
+                Row row = sheetAt.createRow(rowNum);
+                Cell[] cells = new Cell[7];
+                for (int j = 0; j < cells.length; j++) {
+                    cells[j] = row.createCell(j);
+                }
+                cells[0].setCellValue(entry.getKey());
+                cells[0].setCellStyle(dateStyle);
+                cells[1].setCellValue(st + "-" + et);
+                Map<Long, List<TwinCalcStop>> stopDeviceGroup = stops.stream().collect(Collectors.groupingBy(TwinCalcStop::getDeviceId, LinkedHashMap::new, Collectors.toList()));
+                cells[2].setCellValue(stopDeviceGroup.size());
+                int num = stops.size();
+                cells[3].setCellValue(num);
+                //0.最小,1.最大,2.总时间
+                final long[] time = {999999L, 0, 0};
+                Sheet sheet = wb.getSheetAt(1);
+                stops.forEach(stop -> {
+                    long t = (stop.getEndTime().getTime() - stop.getStartTime().getTime()) / 1000;
+                    if (t < time[0]) {
+                        time[0] = t;
+                    }
+                    if (t > time[1]) {
+                        time[1] = t;
+                    }
+                    time[2] += t;
+
+                    Row r1 = sheet.createRow(rs.get());
+                    Cell[] cs = new Cell[6];
+                    for (int j = 0; j < cs.length; j++) {
+                        cs[j] = r1.createCell(j);
+                    }
+                    cs[0].setCellValue(entry.getKey());
+                    cs[0].setCellStyle(dateStyle);
+                    cs[1].setCellValue(st + "-" + et);
+                    cs[2].setCellValue(stop.getDeviceId());
+                    cs[3].setCellValue(stopStr[stop.getStopType() - 1]);
+                    cs[4].setCellValue(stop.getStartTime());
+                    cs[4].setCellStyle(timeStyle);
+                    cs[5].setCellValue(stop.getEndTime());
+                    cs[5].setCellStyle(timeStyle);
+                    rs.getAndIncrement();
+                });
+
+                cells[4].setCellValue(time[1]);
+                cells[5].setCellValue(time[0]);
+                float avg = BigDecimal.valueOf(time[2]).divide(BigDecimal.valueOf(num), 2, RoundingMode.HALF_UP).floatValue();
+                cells[6].setCellValue(avg);
+                cells[6].setCellStyle(p2);
+                rowNum++;
+            }
+
+            // 清空response
+            response.reset();
+            // 设置response的Header
+            response.setCharacterEncoding("UTF-8");
+            //Content-Disposition的作用:告知浏览器以何种方式显示响应返回的文件,用浏览器打开还是以附件的形式下载到本地保存
+            //attachment表示以附件方式下载 inline表示在线打开 "Content-Disposition: inline; filename=文件名.mp3"
+            // filename表示文件的默认名称,因为网络传输只支持URL编码的相关支付,因此需要将文件名URL编码后进行传输,前端收到后需要反编码才能获取到真正的名称
+            response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(stopStr[type-1] + "分析" + System.currentTimeMillis() + ".xlsx", "UTF-8"));
+            response.setContentType("application/octet-stream");
+            wb.write(outputStream);
+            outputStream.flush();
+        } catch (IOException ex) {
+            ex.printStackTrace();
+        }
+    }
+
+    @ApiOperation("告警统计导出")
+    @GetMapping("/export/alarms")
+    @CrossOrigin(origins = "*")
+    public void alarmsExport(String start, String end, HttpServletResponse response) throws ParseException {
+        Date sTime = DateUtils.parseDate(start, DateUtils.YYYY_MM_DD_HH_MM_SS);
+        Date eTime = DateUtils.parseDate(end, DateUtils.YYYY_MM_DD_HH_MM_SS);
+        List<TwinCalcAlarms> list = alarmsService.selectTwinCalcAlarmsListByDate(sTime, eTime);
+        list.sort((Comparator.comparing(TwinCalcAlarms::getDeviceId)));
+        Map<Long, List<TwinCalcAlarms>> alarmsGroup = list.stream().collect(Collectors.groupingBy(TwinCalcAlarms::getDeviceId, LinkedHashMap::new, Collectors.toList()));
+        String[] alarmStr = {"GB1伺服通讯故障", "GB2伺服通讯故障", "GB3伺服通讯故障", "GB4伺服通讯故障", "GB5伺服通讯故障", "牵引伺服通讯故障", "卷曲伺服通讯故障", "断纱故障", "电源故障", "联动未完全啮合", "米长到达", "GB1剩余圈数报警", "GB2剩余圈数报警", "GB3剩余圈数报警", "GB4剩余圈数报警", "GB5剩余圈数报警", "主轴变频掉线", "主轴变频故障", "GB1伺服故障", "GB2伺服故障", "GB3伺服故障", "GB4伺服故障", "GB5伺服故障", "牵引伺服故障", "卷曲伺服故障", "拍照自停", "CCD位置报警信息显示"};
+        try (FileInputStream inputStream = new FileInputStream(alarmsExcelTemplate); Workbook wb = new XSSFWorkbook(inputStream); OutputStream outputStream = new BufferedOutputStream(response.getOutputStream())) {
+            CreationHelper creationHelper = wb.getCreationHelper();
+            CellStyle percentStyle = wb.createCellStyle();
+            percentStyle.setDataFormat(creationHelper.createDataFormat().getFormat("0.00%"));
+            CellStyle timeStyle = wb.createCellStyle();
+            timeStyle.setDataFormat(creationHelper.createDataFormat().getFormat(DateUtils.YYYY_MM_DD_HH_MM_SS));
+            Sheet sheetAt = wb.getSheetAt(0);
+            int rowNum = 2;
+            for (Map.Entry<Long, List<TwinCalcAlarms>> entry : alarmsGroup.entrySet()) {
+                List<TwinCalcAlarms> alarms = entry.getValue();
+                Row row = sheetAt.createRow(rowNum);
+                Cell[] cells = new Cell[29];
+                for (int j = 0; j < cells.length; j++) {
+                    cells[j] = row.createCell(j);
+                }
+                cells[0].setCellValue(entry.getKey());
+                cells[1].setCellValue(alarms.size());
+                Map<Integer, Long> temp = alarms.stream().collect(Collectors.groupingBy(TwinCalcAlarms::getAlarmType, Collectors.counting()));
+                for (Integer v : temp.keySet()) {
+                    cells[v + 1].setCellValue(temp.get(v));
+                }
+                rowNum++;
+            }
+
+            Sheet sheet = wb.getSheetAt(1);
+            AtomicInteger rn = new AtomicInteger(1);
+            list.forEach(alarms -> {
+                Row row = sheet.createRow(rn.get());
+                Cell[] cells = new Cell[3];
+                for (int j = 0; j < cells.length; j++) {
+                    cells[j] = row.createCell(j);
+                }
+
+                cells[0].setCellValue(alarms.getDeviceId());
+                cells[1].setCellValue(alarmStr[alarms.getAlarmType() - 1]);
+                cells[2].setCellValue(alarms.getStartTime());
+                cells[2].setCellStyle(timeStyle);
+                rn.getAndIncrement();
             });
 
             // 清空response
@@ -454,7 +687,7 @@ public class ApiController extends BaseController {
             //Content-Disposition的作用:告知浏览器以何种方式显示响应返回的文件,用浏览器打开还是以附件的形式下载到本地保存
             //attachment表示以附件方式下载 inline表示在线打开 "Content-Disposition: inline; filename=文件名.mp3"
             // filename表示文件的默认名称,因为网络传输只支持URL编码的相关支付,因此需要将文件名URL编码后进行传输,前端收到后需要反编码才能获取到真正的名称
-            response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("告警数据导出" + System.currentTimeMillis() + ".xlsx", "UTF-8"));
+            response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("告警统计" + System.currentTimeMillis() + ".xlsx", "UTF-8"));
             response.setContentType("application/octet-stream");
             wb.write(outputStream);
             outputStream.flush();

+ 5 - 0
ruoyi-admin/src/main/java/com/ruoyi/biz/domain/TwinCalcAlarms.java

@@ -6,6 +6,7 @@ import com.ruoyi.common.core.domain.BaseEntity;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
+import org.apache.poi.ss.usermodel.Cell;
 
 import java.util.Date;
 
@@ -104,4 +105,8 @@ public class TwinCalcAlarms extends BaseEntity {
     @Excel(name = "更新时间", width = 30, dateFormat = "yyyy-MM-dd")
     @ApiModelProperty("更新时间")
     private Date updatedTime;
+
+    public void setCell(Cell[] cells) {
+
+    }
 }

+ 57 - 0
ruoyi-admin/src/main/java/com/ruoyi/biz/domain/TwinCalcDay.java

@@ -4,11 +4,13 @@ import com.fasterxml.jackson.annotation.JsonFormat;
 import com.ruoyi.biz.tools.Tools;
 import com.ruoyi.common.annotation.Excel;
 import com.ruoyi.common.core.domain.BaseEntity;
+import com.ruoyi.common.utils.DateUtils;
 import com.ruoyi.common.utils.bean.BeanUtils;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 import lombok.NoArgsConstructor;
+import org.apache.poi.ss.usermodel.Cell;
 
 import java.math.BigDecimal;
 import java.math.RoundingMode;
@@ -348,4 +350,59 @@ public class TwinCalcDay extends BaseEntity {
         this.efficiencyB = openTimeB.divide(teamTimeB, 2, RoundingMode.HALF_UP);
         this.efficiency = totalOpenTime.divide(totalTeamTime, 2, RoundingMode.HALF_UP);
     }
+
+    public void setCells(Cell[] cells) {
+        //设备名称
+        cells[0].setCellValue(this.getRemark());
+        //时间
+        cells[1].setCellValue(DateUtils.parseDateToStr(this.getTime()));
+        //总长
+        cells[2].setCellValue(this.getLengthA().add(this.getLengthB()).floatValue());
+        //总重
+        cells[3].setCellValue(this.getWeightA().add(this.getWeightB()).floatValue());
+        //总稼动率
+        BigDecimal totalOpenTime = this.getOpenTimeA().add(this.getOpenTimeB());
+        BigDecimal totalCloseTime = this.getCloseTimeA().add(this.getCloseTimeB());
+        cells[4].setCellValue(Tools.calcPercent(totalOpenTime, totalCloseTime).floatValue());
+        // 总电量
+        cells[5].setCellValue(this.getKwh().floatValue());
+        //告警次数
+        cells[6].setCellValue(this.getAlarm());
+        //A班米长
+        cells[7].setCellValue(this.getLengthA().floatValue());
+        //A班重量
+        cells[8].setCellValue(this.getWeightA().floatValue());
+        //A班开机时间
+        cells[9].setCellValue(this.getOpenTimeA().floatValue());
+        //A班停机时间
+        cells[10].setCellValue(this.getCloseTimeA().floatValue());
+        //A班稼动率
+        cells[11].setCellValue(Tools.calcPercent(this.getOpenTimeA(), this.getCloseTimeA()).floatValue());
+        //A班电量
+        cells[12].setCellValue(this.getKwhA().floatValue());
+        //A班停经片停机次数
+        cells[13].setCellValue(this.getStop1A());
+        //A班CCD停机次数
+        cells[14].setCellValue(this.getStop2A());
+        //A班人工停机次数
+        cells[15].setCellValue(this.getStop3A());
+        //B班米长
+        cells[16].setCellValue(this.getLengthB().floatValue());
+        //B班重量
+        cells[17].setCellValue(this.getWeightB().floatValue());
+        //B班开机时间
+        cells[18].setCellValue(this.getOpenTimeB().floatValue());
+        //B班停机时间
+        cells[19].setCellValue(this.getCloseTimeB().floatValue());
+        //B班稼动率
+        cells[20].setCellValue(Tools.calcPercent(this.getOpenTimeB(), this.getCloseTimeB()).floatValue());
+        //B班电量
+        cells[21].setCellValue(this.getKwhB().floatValue());
+        //B班停经片停机次数
+        cells[22].setCellValue(this.getStop1B());
+        //B班CCD停机次数
+        cells[23].setCellValue(this.getStop2B());
+        //B班人工停机次数
+        cells[24].setCellValue(this.getStop3B());
+    }
 }

+ 2 - 2
ruoyi-admin/src/main/java/com/ruoyi/biz/service/impl/ApiServiceImpl.java

@@ -85,8 +85,8 @@ public class ApiServiceImpl implements IApiService {
         LocalDate localDate = ldt.toLocalDate().minusDays(7);
         Date date = Date.from(localDate.atStartOfDay(ZoneOffset.of("+8")).toInstant());
         List<TwinCalcDay> list = twinCalcDayService.selectTwinCalcDayListByTime(date);
-        Map<Date, List<TwinCalcDay>> stopDeviceGroup = list.stream().collect(Collectors.groupingBy(TwinCalcDay::getTime, LinkedHashMap::new, Collectors.toList()));
-        for (Map.Entry<Date, List<TwinCalcDay>> entry : stopDeviceGroup.entrySet()) {
+        Map<Date, List<TwinCalcDay>> dayGroup = list.stream().collect(Collectors.groupingBy(TwinCalcDay::getTime, LinkedHashMap::new, Collectors.toList()));
+        for (Map.Entry<Date, List<TwinCalcDay>> entry : dayGroup.entrySet()) {
             TwinCalcDay day = new TwinCalcDay(entry.getKey());
             List<TwinCalcDay> days = entry.getValue();
             day.calcDays(days);

+ 2 - 2
ruoyi-admin/src/main/java/com/ruoyi/biz/service/impl/TwinCalcDayServiceImpl.java

@@ -157,8 +157,8 @@ public class TwinCalcDayServiceImpl implements ITwinCalcDayService {
         Date endTimeA = teamPairA.getValue();
         Date startTimeB = teamPairB.getKey();
         Date endTimeB = teamPairB.getValue();
-        Map<Long, List<TwinCalcHour>> stopDeviceGroup = hourList.stream().collect(Collectors.groupingBy(TwinCalcHour::getDeviceId, LinkedHashMap::new, Collectors.toList()));
-        for (Map.Entry<Long, List<TwinCalcHour>> entry : stopDeviceGroup.entrySet()) {
+        Map<Long, List<TwinCalcHour>> hourDeviceGroup = hourList.stream().collect(Collectors.groupingBy(TwinCalcHour::getDeviceId, LinkedHashMap::new, Collectors.toList()));
+        for (Map.Entry<Long, List<TwinCalcHour>> entry : hourDeviceGroup.entrySet()) {
             List<TwinCalcHour> hours = entry.getValue();
             TwinCalcDay day = new TwinCalcDay(date);
             day.setDeviceId(entry.getKey());

+ 5 - 2
ruoyi-admin/src/main/resources/application.yml

@@ -11,9 +11,12 @@ excel:
   total: D:\SYSTEM\Desktop\temp\excel\total.xlsx
   formula: D:\SYSTEM\Desktop\temp\excel\formula.xlsx
   gram: D:\SYSTEM\Desktop\temp\excel\gram.xlsx
+  stops: D:\SYSTEM\Desktop\temp\excel\stops.xlsx
+  stopsType: D:\SYSTEM\Desktop\temp\excel\stopsType.xlsx
+  alarms: D:\SYSTEM\Desktop\temp\excel\alarms.xlsx
 #数据补录
-#data:
-#  bl: false
+data:
+  bl: false
 # 项目相关配置
 ruoyi:
   # 名称

+ 34 - 2
ruoyi-admin/src/main/resources/mapper/biz/TwinCalcDayMapper.xml

@@ -39,8 +39,40 @@
     </resultMap>
 
     <sql id="selectTwinCalcDayVo">
-        select ID, TIME, DEVICE_ID, LENGTH, WEIGHT, EFFICIENCY, KWH, ALARM, LENGTH_A, WEIGHT_A, EFFICIENCY_A, OPEN_TIME_A, CLOSE_TIME_A, KWH_A, STOP1_A, STOP2_A, STOP3_A, LENGTH_B, WEIGHT_B, EFFICIENCY_B, OPEN_TIME_B, CLOSE_TIME_B, KWH_B, STOP1_B, STOP2_B, STOP3_B, CREATED_BY, CREATED_TIME, UPDATED_BY, UPDATED_TIME, REMARK
-        from twin_calc_day
+        select * from (select A.ID,
+                       A.TIME,
+                       A.DEVICE_ID,
+                       A.LENGTH,
+                       A.WEIGHT,
+                       A.EFFICIENCY,
+                       A.KWH,
+                       A.ALARM,
+                       A.LENGTH_A,
+                       A.WEIGHT_A,
+                       A.EFFICIENCY_A,
+                       A.OPEN_TIME_A,
+                       A.CLOSE_TIME_A,
+                       A.KWH_A,
+                       A.STOP1_A,
+                       A.STOP2_A,
+                       A.STOP3_A,
+                       A.LENGTH_B,
+                       A.WEIGHT_B,
+                       A.EFFICIENCY_B,
+                       A.OPEN_TIME_B,
+                       A.CLOSE_TIME_B,
+                       A.KWH_B,
+                       A.STOP1_B,
+                       A.STOP2_B,
+                       A.STOP3_B,
+                       A.CREATED_BY,
+                       A.CREATED_TIME,
+                       A.UPDATED_BY,
+                       A.UPDATED_TIME,
+                       B.device_name REMARK
+                from twin_calc_day a,
+                     twin_device b
+                where a.device_id = b.device_id) a
     </sql>
 
     <select id="selectTwinCalcDayList" parameterType="TwinCalcDay" resultMap="TwinCalcDayResult">