Java中使用EasyExcel写excel文件

news/2024/6/18 21:46:19 标签: java, excel

 1、公式

package com.web.report.handler;

import com.alibaba.excel.context.WriteContext;
import com.alibaba.excel.metadata.csv.CsvCellStyle;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.handler.context.CellWriteHandlerContext;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.util.List;


@Slf4j
public class CustomCellWriteHandler implements CellWriteHandler {

    @Override
    public void afterCellDispose(CellWriteHandlerContext context) {
        Cell cell = context.getCell();
        // 这里可以对cell进行任何操作
        int rowIndex = cell.getRowIndex();
        String cellValue = cell.getStringCellValue();
        if (cellValue.startsWith("$$") && cellValue.endsWith("$$")) {
            String statisType = cellValue.substring(2, cellValue.length() - 2);
            String columnTitle = convertToTitle(cell.getColumnIndex() + 1);
            switch (statisType) {
                case "min":
                    cell.setCellFormula("min(" + columnTitle + (rowIndex + 5) + ":" + columnTitle + 1000000 + ")");
                    break;
                case "max":
                    cell.setCellFormula("max(" + columnTitle + (rowIndex + 4) + ":" + columnTitle + 1000000 + ")");
                    break;
//                case "testNum":
//                    cell.setCellFormula("COUNTA(A" + (rowIndex + 1 + 3) + ":A" + 1000000 + ")");
//                    break;
//                case "median":
//                    cell.setCellFormula("MEDIAN(" + columnTitle + (rowIndex + 3) + ":" + columnTitle + 1000000 + ")");
//                    break;
                case "avg":
                    cell.setCellFormula("IF(COUNT(" + columnTitle + (rowIndex + 3) + ":" + columnTitle + 1000000 + ")>0,AVERAGE(" + columnTitle + (rowIndex + 3) + ":" + columnTitle + 1000000 + "),0)");
                    break;
                case "stddev":
                    cell.setCellFormula("IF(COUNT(" + columnTitle + (rowIndex + 2) + ":" + columnTitle + 1000000 + ")>1,STDEV(" + columnTitle + (rowIndex + 2) + ":" + columnTitle + 1000000 + "),0)");
                    break;
            }
        } else {
            try {
                Double value = Double.valueOf(cellValue);
                cell.setCellValue(value);
            } catch (Exception e) {
            }
        }
    }
    public String convertToTitle(int n) {
        StringBuilder sb = new StringBuilder();
        while(n > 0){
            n--; // 重点
            sb.append((char)(n % 26 + 'A'));
            n /= 26;
        }
        sb.reverse();
        return sb.toString();
    }

}

2、合并

package com.web.report.handler;

import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.write.merge.AbstractMergeStrategy;
import org.apache.poi.ss.usermodel.Cell;

import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddress;


public class CustomMergeStrategy extends AbstractMergeStrategy {

    private Integer columnLength;

    private Sheet sheet;

    public CustomMergeStrategy(Integer columnLength) {
        this.columnLength = columnLength;
    }

    // 合并成一个单元格
    private void mergeCommonColumn(Integer rowIndexStart, Integer rowIndexEnd,Integer columnIndexStart,Integer columnIndexEnd ) {
        CellRangeAddress cellRangeAddress = new CellRangeAddress(rowIndexStart, rowIndexEnd, columnIndexStart, columnIndexEnd);
        sheet.addMergedRegionUnsafe(cellRangeAddress);
    }

    @Override
    protected void merge(Sheet sheet, Cell cell, Head head, Integer integer) {
        this.sheet = sheet;
        if (cell.getRowIndex() < 13) {
            this.mergeCommonColumn(cell.getRowIndex(),cell.getRowIndex(),1,this.columnLength-1);
        }
    }

}

3、样式

package com.web.report.style;

import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import org.apache.poi.ss.usermodel.*;

public class StyleUtils {

    /**
     * 标题样式
     * @return
     */
    public static WriteCellStyle getHeadStyle(){
        // 头的策略
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        // 背景颜色
//        headWriteCellStyle.setFillForegroundColor(IndexedColors.LIGHT_TURQUOISE1.getIndex());
//        headWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);

        // 字体
//        WriteFont headWriteFont = new WriteFont();
//        headWriteFont.setFontName("宋体");//设置字体名字
//        headWriteFont.setFontHeightInPoints((short)14);//设置字体大小
//        headWriteFont.setBold(true);//字体加粗
//        headWriteCellStyle.setWriteFont(headWriteFont); //在样式用应用设置的字体;
//
//        // 样式
//        headWriteCellStyle.setBorderBottom(BorderStyle.THIN);//设置底边框;
//        headWriteCellStyle.setBottomBorderColor((short) 0);//设置底边框颜色;
//        headWriteCellStyle.setBorderLeft(BorderStyle.THIN);  //设置左边框;
//        headWriteCellStyle.setLeftBorderColor((short) 0);//设置左边框颜色;
//        headWriteCellStyle.setBorderRight(BorderStyle.THIN);//设置右边框;
//        headWriteCellStyle.setRightBorderColor((short) 0);//设置右边框颜色;
//        headWriteCellStyle.setBorderTop(BorderStyle.THIN);//设置顶边框;
//        headWriteCellStyle.setTopBorderColor((short) 0); //设置顶边框颜色;
//
//        headWriteCellStyle.setWrapped(true);  //设置自动换行;

        headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);//设置水平对齐的样式为居中对齐;
        headWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);  //设置垂直对齐的样式为居中对齐;
        headWriteCellStyle.setShrinkToFit(true);//设置文本收缩至合适

        return headWriteCellStyle;
    }


    /**
     * 内容样式
     * @return
     */
    public static WriteCellStyle getContentStyle(){
        // 内容的策略
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();

        // 背景绿色
        // 这里需要指定 FillPatternType 为FillPatternType.SOLID_FOREGROUND 不然无法显示背景颜色.头默认了 FillPatternType所以可以不指定
//        contentWriteCellStyle.setFillForegroundColor(IndexedColors.PALE_BLUE.getIndex());
//        contentWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);

        // 设置字体
//        WriteFont contentWriteFont = new WriteFont();
//        contentWriteFont.setFontHeightInPoints((short) 12);//设置字体大小
//        contentWriteFont.setFontName("宋体"); //设置字体名字
//        contentWriteCellStyle.setWriteFont(contentWriteFont);//在样式用应用设置的字体;
//
//        //设置样式;
//        contentWriteCellStyle.setBorderBottom(BorderStyle.THIN);//设置底边框;
//        contentWriteCellStyle.setBottomBorderColor((short) 0);//设置底边框颜色;
//        contentWriteCellStyle.setBorderLeft(BorderStyle.THIN);  //设置左边框;
//        contentWriteCellStyle.setLeftBorderColor((short) 0);//设置左边框颜色;
//        contentWriteCellStyle.setBorderRight(BorderStyle.THIN);//设置右边框;
//        contentWriteCellStyle.setRightBorderColor((short) 0);//设置右边框颜色;
//        contentWriteCellStyle.setBorderTop(BorderStyle.THIN);//设置顶边框;
//        contentWriteCellStyle.setTopBorderColor((short) 0); ///设置顶边框颜色;

        contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);// 水平居中
        contentWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);// 垂直居中
        contentWriteCellStyle.setWrapped(true); //设置自动换行;

//        contentWriteCellStyle.setShrinkToFit(true);//设置文本收缩至合适

        return contentWriteCellStyle;
    }

}

4、 注解

package com.web.report.annotation;

import com.web.report.enums.HeaderLabelTypeEnum;
import com.web.report.enums.HeaderTypeEnum;

import java.lang.annotation.*;

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface TableHeader {
    /**
     * 表头显示名称
     * @return
     */
    String[] label() default {"."};

    /**
     * 正数加在对开头,负数加在结尾
     * @return
     */
    int index() default 1;

    /**
     * 表头类型
     * @return
     */
    HeaderTypeEnum headerType() default HeaderTypeEnum.NORMAL;

    HeaderLabelTypeEnum labelType() default HeaderLabelTypeEnum.NORMAL;


}

 5、枚举

package com.web.report.enums;

public enum HeaderLabelTypeEnum {
    NORMAL, CONFIG
}

package com.web.report.enums;

public enum HeaderTypeEnum {
    NORMAL, FLAT
}

6、各种DTO

(1)TableHeaderConfigDTO 

package com.web.report.dto;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class TableHeaderConfigDTO {
    private List<String> labels;

    private String value;
}

 (2)WorkReportConditionDTO 

package com.web.report.dto;

import com.web.enums.WorkProcedureResultEnum;
import com.web.report.annotation.TableHeader;
import com.web.report.enums.HeaderLabelTypeEnum;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class WorkReportConditionDTO {

    @TableHeader(labelType = HeaderLabelTypeEnum.CONFIG, index = 1)
    private TableHeaderConfigDTO ConditionDTO;





}

(3)WorkReportDTOT

package com.web.report.dto;

import com.web.report.annotation.TableHeader;
import com.web.report.enums.HeaderTypeEnum;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class WorkReportDTOT {
    @TableHeader(index = 1, headerType= HeaderTypeEnum.FLAT)
    private List<WorkReportConditionDTO> serialNo;

    @TableHeader(index = 2, headerType= HeaderTypeEnum.FLAT)
    private List<WorkReportConditionDTO> sequence;

    @TableHeader(index = 3, headerType= HeaderTypeEnum.FLAT)
    private  List<WorkReportConditionDTO> bin;

    @TableHeader(index = 4, headerType= HeaderTypeEnum.FLAT)
    private List<WorkReportProcedureDTO> workReportProcedureDTOS;

}

4、使用

@Component
@Slf4j
public class WorkReportUtilT {



    @Autowired
    private ProjectManageService projectManageService;

    @Autowired
    private WorkManageService workManageService;

    @Autowired
    private WorkResultService WorkResultService;


    private static final Map<String, Integer> code2Index = new HashMap<>();

    private static final Map<String, String> tmMap = new HashMap<>();

    private static final List<String> conditionsList = new ArrayList<>();

    private static final List<String> conditionValueList = new ArrayList<>();

    public void buildReport(WorkManageVO work, String filePath) {
        // 1.初始话报告内容
        XinGanXianWorkReportDTOT workReportDTO = null;
        // 2.判断文件是否存在,如果没有文件那就创建文件并添加表头,表头与数据分开写,防止表头合并
        File file = new File(filePath);
        if (!file.exists()) {
            // 测试结果和头部
            workReportDTO = buildWorkReportDTO(work,  false);
            List<List<String>> listHead = buildReportHead(workReportDTO);
            //
            ExcelWriter excelWriter = EasyExcel.write(file).build();
            // 合并单元格
            CustomMergeStrategy customMergeStrategy = new CustomMergeStrategy(listHead.size());
            // 只写测试结果头部
            excelWriter.write(new ArrayList<>(),
                    EasyExcel.writerSheet(0).head(listHead).
                            registerWriteHandler(new CustomCellWriteHandler()).
                            registerWriteHandler(customMergeStrategy)
                            .build());
            //这一步很关键,不然文件会损坏
            excelWriter.finish();
            excelWriter.close();
        }
        // 3. 报告内容为空的话,构建
        if(workReportDTO == null){
            workReportDTO = buildWorkReportDTO(work,  false);
        }
        // 4.往文件中追加数据
        List<Object> oldData = EasyExcel.read(file).sheet(0).headRowNumber(0).doReadSync();
        List<XinGanXianWorkReportConditionDTO> serialNo = workReportDTO.getSerialNo();
        serialNo.get(0).getConditionDTO().setValue(String.valueOf(oldData.size() - 21));
        List<String> procedureDataList = buildReportData(workReportDTO);
        oldData.add(procedureDataList);
        // 5.写入文件
        ExcelWriter excelWriter = EasyExcel.write(file).build();
        // 合并单元格
        CustomMergeStrategy customMergeStrategy = new CustomMergeStrategy(procedureDataList.size());
        // 设置单元格样式
        HorizontalCellStyleStrategy horizontalCellStyleStrategy =
                new HorizontalCellStyleStrategy(StyleUtils.getHeadStyle(), StyleUtils.getContentStyle());
        excelWriter.write(oldData,
                EasyExcel.writerSheet(0)
                        .registerWriteHandler(new CustomColumnWidthHandler())
                        .registerWriteHandler(new CustomCellWriteHandler())
                        .registerWriteHandler(customMergeStrategy)
                        .registerWriteHandler(horizontalCellStyleStrategy)
                        .build());
        excelWriter.finish();
        excelWriter.close();

    }

    private List<String> buildReportData(Object o) {
        List<Field> fields = ReflectionUtil.getAllField(o);
        List<String> collectDataList = fields.stream()
                .filter(field -> field.isAnnotationPresent(TableHeader.class))
                .sorted(Comparator.comparingInt(f -> f.getAnnotation(TableHeader.class).index()))
                .flatMap(field -> {
                    TableHeader tableHeader = field.getAnnotation(TableHeader.class);
                    Object value;
                    try {
                        field.setAccessible(true);
                        value = field.get(o);
                    } catch (IllegalAccessException e) {
                        throw new ServiceException("导出报告获取值错误");
                    }
                    if (tableHeader.headerType() == HeaderTypeEnum.FLAT) {
                        return ((List<Object>) value).stream().flatMap(v -> buildReportData(v).stream());
                    }
                    if (tableHeader.labelType() == HeaderLabelTypeEnum.CONFIG) {
                        if (!TableHeaderConfigDTO.class.equals(field.getType())) {
                            throw new ServiceException("导出报告配置错误");
                        }
                        if (value == null) {
                            return Stream.of();
                        }
                        return Stream.of(((TableHeaderConfigDTO) value).getValue());
                    }
                    return Stream.of(Optional.ofNullable(value).map(String::valueOf).orElse(""));
                }).collect(Collectors.toList());
        return collectDataList;
    }

    private List<List<String>> buildReportHead(Object o) {
        List<Field> fields = ReflectionUtil.getAllField(o);
        List<List<String>> collectHeadList = fields.stream()
                .filter(field -> field.isAnnotationPresent(TableHeader.class))
                .sorted(Comparator.comparingInt(f -> f.getAnnotation(TableHeader.class).index()))
                .flatMap(field -> {
                    TableHeader tableHeader = field.getAnnotation(TableHeader.class);
                    Object value;
                    try {
                        field.setAccessible(true);
                        value = field.get(o);
                    } catch (IllegalAccessException e) {
                        throw new ServiceException("导出报告获取值错误");
                    }
                    if (HeaderTypeEnum.FLAT.equals(tableHeader.headerType())) {
                        if (value == null) {
                            return Stream.of();
                        }
                        if (value instanceof List) {
                            return ((List<Object>) value).stream().flatMap(v -> buildReportHead(v).stream());
                        } else {
                            throw new ServiceException("导出报告配置错误");
                        }
                    }
                    if (HeaderLabelTypeEnum.CONFIG.equals(tableHeader.labelType())) {
                        if (!TableHeaderConfigDTO.class.equals(field.getType())) {
                            throw new ServiceException("导出报告配置错误");
                        }
                        if (value == null) {
                            return Stream.of();
                        }
                        return Stream.of(((TableHeaderConfigDTO) value).getLabels());
                    }
                    return Stream.of(Arrays.asList(tableHeader.label()));
                }).collect(Collectors.toList());
        return collectHeadList;
    }

    private JSONArray sortCompareRules(JSONArray chooseStandardJsonArray){
        if(code2Index.size() == 0){
            List<UniscCommonDictionary> dsaTypes = CommonDictionaryService.searchAll(CommonDictionaryVO.builder().typeLikeRight("device-standard-attribute").build());
            code2Index.putAll(dsaTypes.stream().collect(Collectors.toMap(CommonDictionary::getCode, CommonDictionary::getIndex, (v1, v2) -> v1)));
        }
        // 将JSONArray转换为List后排序
        List<JSONObject> jsonList = new ArrayList<>();
        for (int j = 0; j < chooseStandardJsonArray.size(); j++) {
            jsonList.add(chooseStandardJsonArray.getJSONObject(j));
        }
        // 对标规则排序
        if(jsonList.size() > 0){
            jsonList.sort((obj1, obj2) -> {
                Integer r1Index = code2Index.get(obj1.getString("label"));
                Integer r2Index = code2Index.get(obj2.getString("label"));
                if (r1Index == null && r2Index == null) {
                    return 0;
                } else if (r1Index == null) {
                    return 1;
                } else if (r2Index == null) {
                    return -1;
                } else {
                    return r1Index.compareTo(r2Index);
                }
            });
        }
        // 排序后再转回 JSONArray
        return new JSONArray(Collections.singletonList(jsonList));
    }

    private WorkReportDTOT buildWorkReportDTO(WorkManageVO work, boolean offline)  {
        log.info("开始构建buildWorkReportDTO");
        WorkManageVO detail = workManageService.getDetail(work.getId(), false);
        List<WorkProcedureVO> procedures = detail.getProcedures();
        // 不是离线的延时查询结果
        if(!offline){

            try {
                Thread.sleep(2000); // 延时2秒
            } catch (InterruptedException error) {
                error.printStackTrace();
            }
        }
        //一次全部查询
        List<WorkResultVO> ProcedureResultList = WorkResultService.searchAllVO(WorkResultVO.builder().workId(work.getId()).resultMode(WorkResultModeEnum.COMPARE).build());
        Map<Long, List<WorkResultVO>>  procedureIdAndResultMap = ProcedureResultList.stream().collect(Collectors.groupingBy(WorkResultVO::getProcedureId));
        //工序数据
        List<WorkReportProcedureDTO> procedureDTOList = new ArrayList<>();
        // 第一列
        List<WorkReportConditionDTO>  serialNoList = new ArrayList<>();
        // 第二列
        List<WorkReportConditionDTO>  sequenceList = new ArrayList<>();
        // 第三列
        List<WorkReportConditionDTO>  binList = new ArrayList<>();
        //
        if(procedures != null && procedures.size() > 0){
            log.info("procedures:" + procedures.size());
            procedures.forEach(e->{
                //管子名称
                String pipeName = e.getPipeName();
                // 工序参数
                JSONObject params = e.getParams();
                //构造条件
                if(conditionsList.isEmpty()){
                    conditionsList.addAll(Arrays.asList("CreateTime","DataFileName","TestFileName",".","TestIndex",
                            "TestPipe","TestMode","condition1","condition2","condition3","condition4","condition5",
                            "condition6",".",
                            "TestResult","MinLimit","MaxLimit","MinResult","MaxResult","Average","STD DEV","Serial#"));
                    conditionValueList.addAll(Arrays.asList(
                            DateUtil.format(work.getCreateTime(), DateUtils.DATE_FORMAT_19),
                            "",
                            work.getName(),
                            ".",
                            Optional.ofNullable(String.valueOf(e.getIdx())).orElse(""),
                            Optional.ofNullable(String.valueOf(e.getTsName())).orElse(""),
                            Optional.ofNullable(String.valueOf(e.getTmName())).orElse(""),
                            Optional.ofNullable(params.getString("T1")).orElse(""),
                            Optional.ofNullable(params.getString("T2")).orElse(""),
                            Optional.ofNullable(params.getString("T3")).orElse(""),
                            Optional.ofNullable(params.getString("correctT1")).orElse(""),
                            Optional.ofNullable(params.getString("targetIntensity")).orElse(""),
                            Optional.ofNullable(params.getString("targetVoltage")).orElse(""),
                            ".",
                            "","","","","","","","S#"
                            ));
                }
                if(serialNoList.isEmpty()){
                    XinGanXianWorkReportConditionDTO serialNo = new XinGanXianWorkReportConditionDTO();
                    serialNo.setConditionDTO(TableHeaderConfigDTO.builder().labels(conditionsList).value(".").build());
                    serialNoList.add(serialNo);
                }
                if(sequenceList.isEmpty()){
                    XinGanXianWorkReportConditionDTO sequence = new XinGanXianWorkReportConditionDTO();
                    sequence.setConditionDTO(TableHeaderConfigDTO.builder().labels(conditionValueList).value(detail.getSequence()).build());
                    sequenceList.add(sequence);
                }
                if(binList.isEmpty()){
                    XinGanXianWorkReportConditionDTO bin = new XinGanXianWorkReportConditionDTO();
                    List<String> binconditionList = new ArrayList<>(Collections.nCopies(conditionsList.size() - 1, ""));
                    binconditionList.add("Bin#");
                    bin.setConditionDTO(TableHeaderConfigDTO.builder().labels(binconditionList).value(String.valueOf(detail.getBinResult())).build());
                    binList.add(bin);
                }

                // 对标规则
                JSONArray chooseStandardJsonArray = new JSONArray();
                if(params.containsKey("chooseStandardList")){
                    chooseStandardJsonArray.addAll((JSONArray)params.get("chooseStandardList"));
                    log.info("工序 "+ e.getId() + " ,有对标规则");
                    // 排序对标规则
                    JSONArray sortedChooseStandardJsonArray = sortCompareRules(chooseStandardJsonArray);
                    // 结果集合初始化
                    Map<String, List<WorkResultVO>> collectMap = new HashMap<>();
                    // 有结果
                    if(e.getResult() != null){
                        //log.info("结果:" + e.getResult());
                        // 查找工序结果
                        //List<WorkResultVO> ProcedureResults = WorkResultService.searchAllVO(WorkResultVO.builder().procedureId(e.getId()).resultMode(WorkResultModeEnum.COMPARE).build());
                        List<WorkResultVO> ProcedureResults = procedureIdAndResultMap.get(e.getId());
                        if(ProcedureResults != null && ProcedureResults.size() > 0){
                            log.info("工序:"+ e.getId() + "查到结果:" + ProcedureResults.size());
                            collectMap.putAll(ProcedureResults.stream().collect(Collectors.groupingBy(WorkResultVO::getName)));
                        }else{
                            log.info("工序:"+ e.getId()+ "没有查到结果,重新查一次");
                            try {
                                Thread.sleep(2000); // 延时2秒
                            } catch (InterruptedException error) {
                                error.printStackTrace();
                            }
                            List<WorkResultVO> ProcedureResultListAgain = WorkResultService.searchAllVO(WorkResultVO.builder().workId(work.getId()).resultMode(WorkResultModeEnum.COMPARE).build());
                            Map<Long, List<WorkResultVO>>  procedureIdAndResultMapAgain = ProcedureResultListAgain.stream().collect(Collectors.groupingBy(WorkResultVO::getProcedureId));
                            List<WorkResultVO> ProcedureResultsAgain = procedureIdAndResultMapAgain.get(e.getId());
                            if(ProcedureResultsAgain != null && ProcedureResultsAgain.size() > 0){
                                log.info("工序:"+ e.getId() + "查到结果:" + ProcedureResultListAgain.size());
                                collectMap.putAll(ProcedureResultsAgain.stream().collect(Collectors.groupingBy(WorkResultVO::getName)));
                            }else{
                                log.info("工序:"+ e.getId()+ "没有查到结果");
                            }
                        }
                    }
                    // 遍历每个对标规则
                    ArrayList jsonArrayList = (ArrayList) sortedChooseStandardJsonArray.get(0);
                    log.info("工序id: "+ e.getId() +" ,对标规则数量: " + jsonArrayList.size());
                    jsonArrayList.forEach(ele->{
                        JSONObject jsonObject = (JSONObject)ele;
                        String unit = jsonObject.getString("unit").replace("(","").replace(")","");
                        String label = jsonObject.getString("label");
                        String maxValue = jsonObject.getString("maxValue");
                        String minValue = jsonObject.getString("minValue");
                        Double actual = 0.0;
                        if(collectMap.size() > 0){
                            List<WorkResultVO> WorkResultVOS = collectMap.get(label);
                            List<WorkResultVO> collectList = WorkResultVOS.stream()
                                    .sorted(Comparator.comparing(WorkResultVO::getId).reversed())
                                    .collect(Collectors.toList());
                            actual = collectList.get(0).getActual();
                        }
                        XinGanXianWorkReportProcedureDTO workReportProcedureDTO = new XinGanXianWorkReportProcedureDTO();
                        ArrayList<String> conditionList = new ArrayList<>(Collections.nCopies(conditionsList.size()-8, ""));
                        List<String> list = Arrays.asList(label, minValue, maxValue, "$$min$$", "$$max$$", "$$avg$$", "$$stddev$$", unit);
                        conditionList.addAll(list);
                        workReportProcedureDTO.setProcedureValue(TableHeaderConfigDTO.builder().labels(conditionList).value(String.valueOf(actual)).build());
                        procedureDTOList.add(workReportProcedureDTO);
                    });
                }else {
                    log.info("工序 "+  e.getId() + " ,没有对标规则");
                }
            });
        }

        WorkReportDTOT workReportDTO = new WorkReportDTOT();
        workReportDTO.setWorkReportProcedureDTOS(procedureDTOList);
        workReportDTO.setSerialNo(serialNoList);
        workReportDTO.setSequence(sequenceList);
        workReportDTO.setBin(binList);
        return workReportDTO;
    }


}


http://www.niftyadmin.cn/n/5263123.html

相关文章

微信小程序uniapp记住密码

记住密码功能 在请求登录接口成功后&#xff0c;我们需要判断用户是否勾选记住密码&#xff0c;如果是&#xff0c;则将记住密码状态、账号信息存入本地。 下次登录时&#xff0c;获取本地的记住密码状态&#xff0c;如果为true则获取本地存储的账号信息&#xff0c;将信息回填…

【Qt】点击QTreeWidget空白处,使当前选择的Item失效

原因 有时在开发中&#xff0c;可能会对QTreeWidget进行操作&#xff0c;当点击feiQTreeWidgetItem时&#xff0c;需要焦点取消&#xff0c;无Item选中。 解决方案 可以通过设置事件过滤器进行实现。 1.QtreeWidget安装事件过滤器 ui->treeWidget->viewport()->i…

2023年OceanBase开发者大会-核心PPT资料下载

一、峰会简介 2023年OceanBase开发者大会主要涵盖了OceanBase的最新技术进展、产品更新以及开发者工具的发布。大会发布了OceanBase 4.1版本&#xff0c;公布了两大友好工具&#xff0c;升级了文档的易用性&#xff0c;并统一了企业版和社区版的代码分支。这些举措全面呈现了O…

分布式解决方案与实战

分布式多线程性能调优 使用多线程优化接口 //下单业务public Object order( long userId){long start System.currentTimeMillis();//方法的开始时间戳&#xff08;ms&#xff09;JSONObject orderInfo remoteService.createOrder(userId);Callable<JSONObject> calla…

桂电|《操作系统》实验一:UNIX/LINUX及其使用环境(实验报告)

桂林电子科技大学2023-2024学年 第 一 学期 操作系统A 实验报告 实验名称 实验一 UNIX/LINUX及其使用环境 实验指导老师&#xff1a; 成绩 院 系 计算机与信息安全学院 专业 计算机科学与技术(卓越工程) 学 号 姓名 课内序…

每日一题SQL

以下题目来源微信公众号【SQL数据库开发】 1、编写一个 SQL 查询来实现分数排名。如果两个分数相同&#xff0c;则两个分数排名&#xff08;Rank&#xff09;相同。请注意&#xff0c;平分后的下一个名次应该是下一个连续的整数值。换句话说&#xff0c;名次之间不应该有“间隔…

实验:华为静态路由配置

1.实验目的&#xff1a; 掌握华为路由器和交换机的基本配置方法理解静态路由的原理和作用学习使用vlan和trunk技术划分和连接不同网段能够通过ping命令测试网络连通性和故障排除 2.实验内容&#xff1a; 使用ARI200路由器和S5735交换机搭建如下图所示的网络拓扑在路由器上配…

【SpringBoot篇】基于布隆过滤器,缓存空值,解决缓存穿透问题 (商铺查询时可用)

文章目录 &#x1f354;什么是缓存穿透&#x1f384;解决办法⭐缓存空值处理&#x1f388;优点&#x1f388;缺点&#x1f38d;代码实现 ⭐布隆过滤器&#x1f38d;代码实现 &#x1f354;什么是缓存穿透 缓存穿透是指在使用缓存机制时&#xff0c;大量的请求无法从缓存中获取…