|
@@ -0,0 +1,478 @@
|
|
|
+package com.jjt.biz.service.impl;
|
|
|
+
|
|
|
+import com.jjt.biz.domain.TwinDevice;
|
|
|
+import com.jjt.biz.service.ITwinDeviceService;
|
|
|
+import com.jjt.calc.domain.TwinCalcDay;
|
|
|
+import com.jjt.calc.domain.TwinCalcStop;
|
|
|
+import com.jjt.calc.service.ITwinCalcDayService;
|
|
|
+import com.jjt.calc.service.ITwinCalcStopService;
|
|
|
+import com.jjt.common.utils.DateUtils;
|
|
|
+import com.jjt.utils.Tools;
|
|
|
+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,BarDirection.BAR);
|
|
|
+ int[] pos1 = {6, 10, 16, 30};
|
|
|
+ int[] data1 = {2, 8, 4, 4};
|
|
|
+ drawBar(sheet, "停机时长占比", "停机原因", pos1, xdata, data1,BarDirection.BAR);
|
|
|
+
|
|
|
+ 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(6), 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> yarnStopList = stopService.selectTwinCalcStopListByDate(sTime, eTime, 2);
|
|
|
+
|
|
|
+ yarnStopList.forEach(stop -> {
|
|
|
+ if (stop.getHour() < 7) {
|
|
|
+ Date d = stop.getDataDate();
|
|
|
+ stop.setDataDate(DateUtils.addDays(d, -1));
|
|
|
+ }
|
|
|
+ });
|
|
|
+ Map<Long, Map<Date, Long>> weekData = yarnStopList.stream().collect(Collectors.groupingBy(TwinCalcStop::getDeviceId, Collectors.groupingBy(TwinCalcStop::getDataDate, Collectors.counting())));
|
|
|
+ List<Date> dateList = yarnStopList.stream().map(TwinCalcStop::getDataDate).distinct().sorted().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);
|
|
|
+ for (int i = 0; i < dateList.size(); i++) {
|
|
|
+ Cell dateCell = sheet.getRow(1).getCell(i + 2);
|
|
|
+ dateCell.setCellValue(dateList.get(i));
|
|
|
+ }
|
|
|
+
|
|
|
+ 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[] cells = new Cell[9];
|
|
|
+ for (int j = 0; j < cells.length; j++) {
|
|
|
+ cells[j] = r1.createCell(j);
|
|
|
+ }
|
|
|
+ cells[0].setCellValue(deviceMap.get(deviceId).getDeviceName());
|
|
|
+ cells[1].setCellValue(entry.getValue());
|
|
|
+ Map<Date, Long> xx = weekData.get(deviceId);
|
|
|
+ for (int i = 0; i < dateList.size(); i++) {
|
|
|
+ Long v = xx.get(dateList.get(i));
|
|
|
+ if (v == null) {
|
|
|
+ v = 0L;
|
|
|
+ }
|
|
|
+ cells[i + 2].setCellValue(v);
|
|
|
+ }
|
|
|
+ rn++;
|
|
|
+ }
|
|
|
+
|
|
|
+ int[] pos = {10, 2, 16, rn};
|
|
|
+ int[] data = {2, rn, 1, 1};
|
|
|
+ int[] xdata = {2, rn, 0, 0};
|
|
|
+ drawBar(sheet, "断纱停机周TOP", "设备名称", pos, xdata, data,BarDirection.BAR);
|
|
|
+ drawTopLine(sheet, rn);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void drawTopLine(XSSFSheet sheet, int endRn) {
|
|
|
+ XSSFDrawing drawing = sheet.createDrawingPatriarch();
|
|
|
+ // 2 左侧距离单元格个数, 4 顶部距离单元格个数, 7 左侧距离单元格个数, 26 顶部距离单元格个数
|
|
|
+ XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 1, endRn + 1, 15, endRn + 26);
|
|
|
+ XSSFChart chart = drawing.createChart(anchor);
|
|
|
+ // 图表标题
|
|
|
+ chart.setTitleText("断纱停机趋势");
|
|
|
+ // 图例是否覆盖标题
|
|
|
+ chart.setTitleOverlay(false);
|
|
|
+ XDDFChartLegend legend = chart.getOrAddLegend();
|
|
|
+ // 图例位置:上下左右
|
|
|
+ legend.setPosition(LegendPosition.BOTTOM);
|
|
|
+ // 创建x轴
|
|
|
+ XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.LEFT);
|
|
|
+ // X轴标题
|
|
|
+ bottomAxis.setTitle("日期");
|
|
|
+ // y轴标题
|
|
|
+ XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT);
|
|
|
+ leftAxis.setTitle("单位:次");
|
|
|
+ // y轴数据
|
|
|
+ // 分类轴标(X轴)数据,单元格范围位置[0, 0]到[0, 6]
|
|
|
+ XDDFDataSource<String> xData = XDDFDataSourcesFactory.fromStringCellRange(sheet, new CellRangeAddress(1, 1, 2, 8));
|
|
|
+ // 创建y轴
|
|
|
+ XDDFLineChartData data = (XDDFLineChartData) chart.createData(ChartTypes.LINE, bottomAxis, leftAxis);
|
|
|
+ for (int i = 2; i < endRn; i++) {
|
|
|
+ // 创建y轴
|
|
|
+ XDDFNumericalDataSource<Double> yData = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(i, i, 2, 8));
|
|
|
+ XDDFLineChartData.Series series = (XDDFLineChartData.Series) data.addSeries(xData, yData);
|
|
|
+ // 图例标题
|
|
|
+ series.setTitle(sheet.getRow(i).getCell(0).getStringCellValue(), null);
|
|
|
+ // 线条样式:true平滑曲线,false折线
|
|
|
+ series.setSmooth(true);
|
|
|
+ // 点的样式
|
|
|
+// series.setMarkerStyle(MarkerStyle.CIRCLE);
|
|
|
+ }
|
|
|
+ chart.plot(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);
|
|
|
+ }
|
|
|
+
|
|
|
+ public void drawBar(XSSFSheet sheet, String title, String xTitle, int[] pos, int[] xdata, int[] data,BarDirection barDirection) {
|
|
|
+ // 创建一个画布
|
|
|
+ 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);
|
|
|
+
|
|
|
+ // 图表加载数据,条形图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++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|