Pārlūkot izejas kodu

取消卷曲故障告警和电源故障告警

wukai 7 mēneši atpakaļ
vecāks
revīzija
6d2525c0cb

+ 28 - 24
ruoyi-admin/src/main/java/com/ruoyi/biz/service/impl/AsyncServiceImpl.java

@@ -365,19 +365,20 @@ public class AsyncServiceImpl {
          //        }
          */
         boolean[] flags = new boolean[index + 1];
-        for (int kk = 0; kk < flags.length; kk++) {
-            flags[kk] = true;
-        }
+        Arrays.fill(flags, true);
         if (i == 1) {
             int j = 0;
             for (; j < index; j++) {
-                boolean currV = curr.getBool(j + 12);
-                if (currV) {
-                    flags[j] = false;
-                    recordAlarms = new TwinRecordAlarms();
-                    recordAlarms.setAlarmType(j + 1);
-                    recordAlarms.setStartTime(new Date(time));
-                    alarmRecord.add(recordAlarms);
+                if ((j + 1) != 9 && (j + 1) != 25) {
+                    //去掉电源故障和卷曲故障
+                    boolean currV = curr.getBool(j + 12);
+                    if (currV) {
+                        flags[j] = false;
+                        recordAlarms = new TwinRecordAlarms();
+                        recordAlarms.setAlarmType(j + 1);
+                        recordAlarms.setStartTime(new Date(time));
+                        alarmRecord.add(recordAlarms);
+                    }
                 }
             }
             //需要单独计算alarm27
@@ -394,20 +395,23 @@ public class AsyncServiceImpl {
         }
         int j = 0;
         for (; j < index; j++) {
-            if (flags[j]) {
-                boolean currV = curr.getBool(j + 12);
-                boolean lastV = last.getBool(j + 12);
-                if (currV && !lastV) {
-                    recordAlarms = new TwinRecordAlarms();
-                    recordAlarms.setAlarmType(j + 1);
-                    recordAlarms.setStartTime(new Date(time));
-                    alarmRecord.add(recordAlarms);
-                }
-                if (!currV && lastV) {
-                    recordAlarms = new TwinRecordAlarms();
-                    recordAlarms.setAlarmType(j + 1);
-                    recordAlarms.setEndTime(new Date(time));
-                    alarmRecord.add(recordAlarms);
+            if ((j + 1) != 9 && (j + 1) != 25) {
+                //去掉电源故障和卷曲故障
+                if (flags[j]) {
+                    boolean currV = curr.getBool(j + 12);
+                    boolean lastV = last.getBool(j + 12);
+                    if (currV && !lastV) {
+                        recordAlarms = new TwinRecordAlarms();
+                        recordAlarms.setAlarmType(j + 1);
+                        recordAlarms.setStartTime(new Date(time));
+                        alarmRecord.add(recordAlarms);
+                    }
+                    if (!currV && lastV) {
+                        recordAlarms = new TwinRecordAlarms();
+                        recordAlarms.setAlarmType(j + 1);
+                        recordAlarms.setEndTime(new Date(time));
+                        alarmRecord.add(recordAlarms);
+                    }
                 }
             }
         }

+ 417 - 0
ruoyi-admin/src/main/java/com/ruoyi/biz/service/impl/BrokenYarnExportServiceImpl.java

@@ -0,0 +1,417 @@
+package com.ruoyi.biz.service.impl;
+
+import com.ruoyi.biz.domain.TwinCalcDay;
+import com.ruoyi.biz.domain.TwinCalcStop;
+import com.ruoyi.biz.domain.TwinDevice;
+import com.ruoyi.biz.service.ITwinCalcDayService;
+import com.ruoyi.biz.service.ITwinCalcStopService;
+import com.ruoyi.biz.service.ITwinDeviceService;
+import com.ruoyi.biz.tools.Tools;
+import com.ruoyi.common.utils.DateUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.poi.ss.usermodel.*;
+import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.xddf.usermodel.chart.*;
+import org.apache.poi.xssf.usermodel.*;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.time.*;
+import java.util.*;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.stream.Collectors;
+
+/**
+ * 多线程执行任务
+ *
+ * @author wukai
+ * @date 2024/5/4 20:35
+ */
+@Service
+@Slf4j
+public class BrokenYarnExportServiceImpl {
+    @Resource
+    private ITwinCalcDayService twinCalcDayService;
+    @Resource
+    private ITwinCalcStopService stopService;
+    @Resource
+    private ITwinDeviceService deviceService;
+
+    /**
+     * 基本信息表
+     *
+     * @param wb
+     * @param localDate
+     */
+    public void base(XSSFWorkbook wb, LocalDate localDate) {
+        LocalDate st = localDate.minusDays(7);
+        Date sd = Date.from(st.atStartOfDay(ZoneOffset.of("+8")).toInstant());
+        Date ed = Date.from(localDate.atStartOfDay(ZoneOffset.of("+8")).toInstant());
+        //7天数据
+        List<TwinCalcDay> dayList = twinCalcDayService.selectTwinCalcDayListByTime(sd, ed);
+        //当天数据
+        List<TwinCalcDay> curr = dayList.stream().filter(day -> day.getTime().equals(ed)).collect(Collectors.toList());
+        //1.基本信息
+        XSSFSheet sheet = wb.getSheetAt(0);
+        Cell cell = sheet.getRow(1).getCell(1);
+        cell.setCellValue(localDate);
+
+        //计算开机设备数量,A班开机时间+B班开机时间大于0的。
+        //按设备分组
+        Map<Long, List<TwinCalcDay>> deviceGr = curr.stream().collect(Collectors.groupingBy(TwinCalcDay::getDeviceId, LinkedHashMap::new, Collectors.toList()));
+        int openDevices = 0;
+        BigDecimal totOpenTimes = BigDecimal.ZERO;
+        for (Map.Entry<Long, List<TwinCalcDay>> entry1 : deviceGr.entrySet()) {
+            TwinCalcDay tempDay = new TwinCalcDay(ed);
+            tempDay.calcDays(entry1.getValue());
+            BigDecimal tot = tempDay.getOpenTimeA().add(tempDay.getOpenTimeB());
+            if (tot.intValue() > 0) {
+                openDevices++;
+            }
+            totOpenTimes = totOpenTimes.add(tot);
+        }
+
+        cell = sheet.getRow(2).getCell(1);
+        cell.setCellValue(openDevices);
+        BigDecimal avgOpenTimes = totOpenTimes.divide(BigDecimal.valueOf(openDevices), 0, RoundingMode.HALF_UP);
+
+        cell = sheet.getRow(3).getCell(1);
+        cell.setCellValue(Tools.convertHMS(totOpenTimes.longValue()));
+        cell = sheet.getRow(4).getCell(1);
+        cell.setCellValue(Tools.convertHMS(avgOpenTimes.longValue()));
+
+        drawLine(sheet, dayList);
+    }
+
+    private final String[] stopStr = {"停经片停机", "CCD停机(相机号+断纱/故障)", "人工停机", "断电停机", "设备故障停机", "落布米数达到停机", "盘头剩余圈数达到停机"};
+
+    public void stop(XSSFWorkbook wb, LocalDate localDate) {
+        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"));
+        CellStyle dateStyle = wb.createCellStyle();
+        dateStyle.setDataFormat(creationHelper.createDataFormat().getFormat(DateUtils.YYYY_MM_DD));
+        CellStyle timeStyle = wb.createCellStyle();
+        timeStyle.setDataFormat(creationHelper.createDataFormat().getFormat(DateUtils.YYYY_MM_DD_HH_MM_SS));
+        CellStyle rightStyle = wb.createCellStyle();
+        rightStyle.setAlignment(HorizontalAlignment.RIGHT);
+        LocalDateTime sdt = LocalDateTime.of(localDate, LocalTime.of(7, 0));
+        LocalDateTime edt = LocalDateTime.of(localDate.plusDays(1), LocalTime.of(6, 59, 59));
+        Date sTime = Date.from(sdt.atZone(ZoneId.systemDefault()).toInstant());
+        Date eTime = Date.from(edt.atZone(ZoneId.systemDefault()).toInstant());
+        List<TwinCalcStop> stopList = stopService.selectTwinCalcStopListByDate(sTime, eTime);
+        Map<Integer, List<TwinCalcStop>> stopDeviceGroup = stopList.stream().collect(Collectors.groupingBy(TwinCalcStop::getStopType, LinkedHashMap::new, Collectors.toList()));
+
+        List<TwinCalcStop> yarnStopList = stopList.stream().filter(stop -> stop.getStopType().equals(2)).collect(Collectors.toList());
+        //1停经片停机,2-CCD停机(相机号+断纱/故障),3-人工停机,4-断电停机,5-设备故障停机,6-落布米数达到停机,7-盘头剩余圈数达到停机
+        //停机次数
+        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 -> {
+                Date stopEndTime = stop.getEndTime();
+                // 调整停机时间
+                if (stop.getEndTime().compareTo(eTime) > 0) {
+                    stopEndTime = eTime;
+                }
+                Date stopStartTime = stop.getStartTime();
+                //调整开机时间
+                if (stop.getStartTime().compareTo(sTime) < 0) {
+                    stopStartTime = sTime;
+                }
+                long t = (stopEndTime.getTime() - stopStartTime.getTime()) / 1000;
+                stopTime[pos] += t;
+                totalTime.updateAndGet(v -> v + t);
+            });
+        }
+        XSSFSheet sheet = wb.getSheetAt(1);
+        for (int i = 0; i < stopStr.length; i++) {
+            Row row = sheet.createRow(i + 2);
+            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(Tools.convertHMS(stopTime[i]));
+            cells[2].setCellStyle(rightStyle);
+            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);
+        }
+        int[] pos = {0, 10, 5, 30};
+        int[] data = {2, 8, 3, 3};
+        int[] xdata = {2, 8, 0, 0};
+        drawBar(sheet, "停机次数占比","停机原因", pos, xdata, data);
+        int[] pos1 = {6, 10, 16, 30};
+        int[] data1 = {2, 8, 4, 4};
+        drawBar(sheet, "停机时长占比","停机原因", pos1, xdata, data1);
+
+        brokenYarn(wb, yarnStopList, stopTime[1], stopList.size());
+        yarn(wb, yarnStopList, dateStyle, timeStyle, p2);
+
+    }
+
+    public void top(XSSFWorkbook wb, LocalDate localDate) {
+        LocalDateTime sdt = LocalDateTime.of(localDate.minusDays(7), LocalTime.of(7, 0));
+        LocalDateTime edt = LocalDateTime.of(localDate.plusDays(1), LocalTime.of(6, 59, 59));
+        Date sTime = Date.from(sdt.atZone(ZoneId.systemDefault()).toInstant());
+        Date eTime = Date.from(edt.atZone(ZoneId.systemDefault()).toInstant());
+        List<TwinCalcStop> stopList = stopService.selectTwinCalcStopListByDate(sTime, eTime);
+
+        List<TwinCalcStop> yarnStopList = stopList.stream().filter(stop -> stop.getStopType().equals(2)).collect(Collectors.toList());
+        Map<Long, Long> collect = yarnStopList.parallelStream().collect(Collectors.groupingBy(TwinCalcStop::getDeviceId, Collectors.counting()));
+        Map<Long, Long> sortedMap = collect.entrySet()
+                .stream()
+                .sorted(Collections.reverseOrder(Map.Entry.comparingByValue()))
+                .collect(Collectors.toMap(
+                        Map.Entry::getKey,
+                        Map.Entry::getValue,
+                        (e1, e2) -> e1,
+                        LinkedHashMap::new));
+        Map<Long, TwinDevice> deviceMap = deviceService.deviceMap();
+        XSSFSheet sheet = wb.getSheetAt(3);
+        Cell cell = sheet.getRow(0).getCell(0);
+        String title = "断纱停机周TOP排名\n(" + DateUtils.parseTimeToStr(sdt) + "至" + DateUtils.parseTimeToStr(edt) + ")";
+        cell.setCellValue(title);
+        int rn = 2;
+        for (Map.Entry<Long, Long> entry : sortedMap.entrySet()) {
+            Long deviceId = entry.getKey();
+            Row r1 = sheet.createRow(rn);
+            Cell cell1 = r1.createCell(0);
+            Cell cell2 = r1.createCell(1);
+            cell1.setCellValue(deviceMap.get(deviceId).getDeviceName());
+            cell2.setCellValue(entry.getValue());
+            rn++;
+        }
+
+        int[] pos = {4, 2, 10, rn};
+        int[] data = {2, rn, 1, 1};
+        int[] xdata = {2, rn, 0, 0};
+        drawBar(sheet, "断纱停机周TOP","设备名称", pos, xdata, data);
+    }
+
+    private void drawLine(XSSFSheet sheet, List<TwinCalcDay> dayList) {
+        Map<Date, List<TwinCalcDay>> dayGroup = dayList.stream().collect(Collectors.groupingBy(TwinCalcDay::getTime, LinkedHashMap::new, Collectors.toList()));
+        List<TwinCalcDay> jdl = new ArrayList<>();
+        for (Map.Entry<Date, List<TwinCalcDay>> entry : dayGroup.entrySet()) {
+            TwinCalcDay day = new TwinCalcDay(entry.getKey());
+            List<TwinCalcDay> days = entry.getValue();
+            day.calcDays(days);
+            jdl.add(day);
+        }
+        XSSFDrawing drawing = sheet.createDrawingPatriarch();
+        // 2 左侧距离单元格个数, 4 顶部距离单元格个数, 7 左侧距离单元格个数, 26 顶部距离单元格个数
+        XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 1, 7, 12, 25);
+        XSSFChart chart = drawing.createChart(anchor);
+        // 图表标题
+        chart.setTitleText("稼动率周曲线");
+        // 图例是否覆盖标题
+        chart.setTitleOverlay(false);
+        XDDFChartLegend legend = chart.getOrAddLegend();
+        // 图例位置:上下左右
+        legend.setPosition(LegendPosition.TOP);
+        // 创建x轴
+        XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
+        // X轴标题
+        bottomAxis.setTitle("日期");
+        // y轴标题
+        XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT);
+        leftAxis.setTitle("单位:%");
+
+//            // y轴数据
+        List<String> xtd = new ArrayList<>();
+        List<Double> tef = new ArrayList<>();
+        List<Double> aef = new ArrayList<>();
+        List<Double> bef = new ArrayList<>();
+        jdl.forEach(day -> {
+            aef.add(day.getEfficiencyA().multiply(BigDecimal.valueOf(100)).doubleValue());
+            bef.add(day.getEfficiencyB().multiply(BigDecimal.valueOf(100)).doubleValue());
+            tef.add(day.getEfficiency().multiply(BigDecimal.valueOf(100)).doubleValue());
+            xtd.add(DateUtils.parseDateToStr("MM-dd", day.getTime()));
+        });
+        XDDFDataSource<String> xdate = XDDFDataSourcesFactory.fromArray(xtd.toArray(new String[0]));
+        XDDFNumericalDataSource<Double> tt = XDDFDataSourcesFactory.fromArray(tef.toArray(new Double[0]));
+        XDDFNumericalDataSource<Double> aa = XDDFDataSourcesFactory.fromArray(aef.toArray(new Double[0]));
+        XDDFNumericalDataSource<Double> bb = XDDFDataSourcesFactory.fromArray(bef.toArray(new Double[0]));
+        // 创建y轴
+        XDDFLineChartData data = (XDDFLineChartData) chart.createData(ChartTypes.LINE, bottomAxis, leftAxis);
+        XDDFLineChartData.Series series = (XDDFLineChartData.Series) data.addSeries(xdate, tt);
+        // 图例标题
+        series.setTitle("总稼动率", null);
+        // 线条样式:true平滑曲线,false折线
+        series.setSmooth(true);
+        // 点的样式
+        series.setMarkerStyle(MarkerStyle.CIRCLE);
+
+        XDDFLineChartData.Series series1 = (XDDFLineChartData.Series) data.addSeries(xdate, aa);
+        series1.setTitle("A班稼动率", null);
+        series1.setSmooth(true);
+        series1.setMarkerStyle(MarkerStyle.CIRCLE);
+        XDDFLineChartData.Series series2 = (XDDFLineChartData.Series) data.addSeries(xdate, bb);
+        series2.setTitle("B班稼动率", null);
+        series2.setSmooth(true);
+        series2.setMarkerStyle(MarkerStyle.CIRCLE);
+        chart.plot(data);
+    }
+
+    private void drawBar(XSSFSheet sheet, String title,String xTitle, int[] pos, int[] xdata, int[] data) {
+        // 创建一个画布
+        XSSFDrawing drawing = sheet.createDrawingPatriarch();
+        // 前四个默认0,[0,5]:从0列5行开始;[7,26]:到7列26行结束
+        // 默认宽度(14-8)*12
+        XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, pos[0], pos[1], pos[2], pos[3]);
+        // 创建一个chart对象
+        XSSFChart chart = drawing.createChart(anchor);
+        // 标题
+        chart.setTitleText(title);
+        // 标题覆盖
+        chart.setTitleOverlay(false);
+
+        // 图例位置
+//        XDDFChartLegend legend = chart.getOrAddLegend();
+//        legend.setPosition(LegendPosition.TOP);
+
+        // 分类轴标(X轴),标题位置
+        XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
+        bottomAxis.setTitle(xTitle);
+        // 值(Y轴)轴,标题位置
+        XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT);
+//        leftAxis.setTitle("停机次数占比");
+
+        // CellRangeAddress(起始行号,终止行号, 起始列号,终止列号)
+        // 分类轴标(X轴)数据,单元格范围位置[0, 0]到[0, 6]
+        XDDFDataSource<String> countries = XDDFDataSourcesFactory.fromStringCellRange(sheet, new CellRangeAddress(xdata[0], xdata[1], xdata[2], xdata[3]));
+        // XDDFCategoryDataSource countries = XDDFDataSourcesFactory.fromArray(new String[] {"俄罗斯","加拿大","美国","中国","巴西","澳大利亚","印度"});
+        // 数据1,单元格范围位置[1, 0]到[1, 6]
+        XDDFNumericalDataSource<Double> area = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(data[0], data[1], data[2], data[3]));
+        // XDDFNumericalDataSource<Integer> area = XDDFDataSourcesFactory.fromArray(new Integer[] {17098242,9984670,9826675,9596961,8514877,7741220,3287263});
+
+        // bar:条形图,
+        XDDFBarChartData bar = (XDDFBarChartData) chart.createData(ChartTypes.BAR, bottomAxis, leftAxis);
+
+        leftAxis.setCrossBetween(AxisCrossBetween.BETWEEN);
+        // 设置为可变颜色
+        bar.setVaryColors(true);// 如果需要设置成自己想要的颜色,这里可变颜色要设置成false
+        // 条形图方向,纵向/横向:纵向
+        bar.setBarDirection(BarDirection.BAR);
+
+        // 图表加载数据,条形图1
+        XDDFBarChartData.Series series1 = (XDDFBarChartData.Series) bar.addSeries(countries, area);
+//        // 条形图例标题
+        series1.setTitle("百分比", null);
+//			XDDFSolidFillProperties fill = new XDDFSolidFillProperties(XDDFColor.from(PresetColor.RED));
+//			// 条形图,填充颜色
+//			series1.setFillProperties(fill);
+
+        // 绘制
+        chart.plot(bar);
+    }
+
+    public void brokenYarn(XSSFWorkbook wb, List<TwinCalcStop> yarnStopList, long time, int size) {
+        //3.断纱分析
+        Sheet sheet = wb.getSheetAt(2);
+        int yst = yarnStopList.size();
+        Cell cell = sheet.getRow(1).getCell(1);
+        cell.setCellValue(yst);
+        Map<Long, List<TwinCalcStop>> deviceGroup = yarnStopList.stream().collect(Collectors.groupingBy(TwinCalcStop::getDeviceId, LinkedHashMap::new, Collectors.toList()));
+        cell = sheet.getRow(2).getCell(1);
+        cell.setCellValue(deviceGroup.size());
+        float bl = 0f;
+        long aavg = 0;
+        if (yst > 0) {
+            bl = BigDecimal.valueOf(yst).divide(BigDecimal.valueOf(size), 4, RoundingMode.HALF_UP).floatValue();
+            aavg = time / yst;
+        }
+        cell = sheet.getRow(3).getCell(1);
+        cell.setCellValue(bl);
+
+        cell = sheet.getRow(4).getCell(1);
+        cell.setCellValue(Tools.convertHMS(time));
+        cell = sheet.getRow(5).getCell(1);
+        cell.setCellValue(Tools.convertHMS(aavg));
+    }
+
+    public void yarn(XSSFWorkbook wb, List<TwinCalcStop> yarnStopList, CellStyle dateStyle, CellStyle timeStyle, CellStyle p2) {
+        Map<Long, TwinDevice> deviceMap = deviceService.deviceMap();
+        //5.并发断纱分析
+        Sheet sheet = wb.getSheetAt(4);
+        int rowNum = 2;
+        int rn = 2;
+        yarnStopList.sort(Comparator.comparing(TwinCalcStop::getDataDate).thenComparing(TwinCalcStop::getHour));
+        Map<Date, Map<Integer, List<TwinCalcStop>>> stopHourGroup = yarnStopList.stream().collect(
+                Collectors.groupingBy(TwinCalcStop::getDataDate, LinkedHashMap::new,
+                        Collectors.groupingBy(TwinCalcStop::getHour, LinkedHashMap::new, Collectors.toList())));
+        for (Map.Entry<Date, Map<Integer, List<TwinCalcStop>>> entry : stopHourGroup.entrySet()) {
+            Map<Integer, List<TwinCalcStop>> map = entry.getValue();
+            for (Map.Entry<Integer, List<TwinCalcStop>> entry1 : map.entrySet()) {
+                List<TwinCalcStop> stops = entry1.getValue();
+                Row row = sheet.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(entry1.getKey());
+                Map<Long, List<TwinCalcStop>> yarnDeviceGroup = stops.stream().collect(Collectors.groupingBy(TwinCalcStop::getDeviceId, LinkedHashMap::new, Collectors.toList()));
+                cells[2].setCellValue(yarnDeviceGroup.size());
+                int num = stops.size();
+                cells[3].setCellValue(num);
+                //0.最小,1.最大,2.总时间
+                final long[] time = {999999L, 0, 0};
+                //6.设备断纱停机详情
+                Sheet sheet6 = wb.getSheetAt(5);
+                for (TwinCalcStop stop : stops) {
+                    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 = sheet6.createRow(rn);
+                    Cell[] cs = new Cell[6];
+                    for (int j = 0; j < cs.length; j++) {
+                        cs[j] = r1.createCell(j);
+                    }
+                    cs[0].setCellValue(stop.getDataDate());
+                    cs[0].setCellStyle(dateStyle);
+                    cs[1].setCellValue(stop.getHour());
+                    cs[2].setCellValue(deviceMap.get(stop.getDeviceId()).getDeviceName());
+                    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);
+                    rn++;
+                }
+
+                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++;
+            }
+        }
+    }
+}