| | |
| | | return a; |
| | | } |
| | | |
| | | /** 审核结果导出 Excel(含企业名/规则名/状态/审核意见) */ |
| | | /** 审核结果导出 Excel(两 Sheet,按业务模板):Sheet1 审核结果(逐条明细);Sheet2 企业合并(按企业汇总 + 问题列) */ |
| | | public byte[] exportResults(String reportPeriod, String reportType) throws Exception { |
| | | return exportResults(reportPeriod, reportType, true, "all"); |
| | | } |
| | | |
| | | /** onlyVerify=true 时剔除“提醒型”规则(如 RULE_004 环比提醒),只保留核实型问题;status=all/pending/handled 与界面“状态”筛选一致 */ |
| | | public byte[] exportResults(String reportPeriod, String reportType, boolean onlyVerify, String status) throws Exception { |
| | | List<AuditResult> results = queryResults(reportPeriod, reportType); |
| | | java.util.List<AuditResult> filtered = new java.util.ArrayList<>(); |
| | | String st = status == null ? "all" : status.trim(); |
| | | for (AuditResult res : results) { |
| | | if (onlyVerify && isReminderRule(res.getRuleCode())) continue; |
| | | if ("pending".equals(st) && !"PENDING".equals(res.getStatus())) continue; |
| | | if ("handled".equals(st) && (res.getStatus() == null || "PENDING".equals(res.getStatus()))) continue; |
| | | filtered.add(res); |
| | | } |
| | | try (XSSFWorkbook wb = new XSSFWorkbook()) { |
| | | // ---------- Sheet1 审核结果(逐条,列与业务模板一致) ---------- |
| | | Sheet sheet = wb.createSheet("审核结果"); |
| | | String[] headers = {"报表期", "企业/市州", "规则编码", "审核规则", "等级", "实际值", "阈值/基准", "偏差说明", "状态", "审核意见"}; |
| | | Row head = sheet.createRow(0); |
| | | for (int i = 0; i < headers.length; i++) { |
| | | Cell cell = head.createCell(i); |
| | | cell.setCellValue(headers[i]); |
| | | org.apache.poi.ss.usermodel.CellStyle style = wb.createCellStyle(); |
| | | org.apache.poi.ss.usermodel.Font font = wb.createFont(); |
| | | font.setBold(true); |
| | | style.setFont(font); |
| | | cell.setCellStyle(style); |
| | | } |
| | | writeAuditHeader(sheet, headers); |
| | | int r = 1; |
| | | for (AuditResult res : results) { |
| | | for (AuditResult res : filtered) { |
| | | Row row = sheet.createRow(r++); |
| | | row.createCell(0).setCellValue(valueOf(res.getReportPeriod())); |
| | | row.createCell(1).setCellValue(valueOf(res.getEnterpriseName())); |
| | |
| | | for (int i = 0; i < widths.length; i++) { |
| | | sheet.setColumnWidth(i, widths[i] * 256); |
| | | } |
| | | |
| | | // ---------- Sheet2 企业合并(同一企业多条规则并排列出 + 问题汇总列) ---------- |
| | | Sheet ms = wb.createSheet("企业合并"); |
| | | String[] h2 = {"报表期", "企业/市州", "审核规则", "实际值", "阈值/基准", "偏差说明", "问题"}; |
| | | writeAuditHeader(ms, h2); |
| | | java.util.LinkedHashMap<String, java.util.List<AuditResult>> groups = new java.util.LinkedHashMap<>(); |
| | | for (AuditResult res : filtered) { |
| | | String key = valueOf(res.getEnterpriseName()); |
| | | if (key.isEmpty()) key = valueOf(res.getReportPeriod()) + "#" + valueOf(res.getActualValue()); |
| | | groups.computeIfAbsent(key, k -> new java.util.ArrayList<>()).add(res); |
| | | } |
| | | int rowCursor = 1; |
| | | for (java.util.Map.Entry<String, java.util.List<AuditResult>> e : groups.entrySet()) { |
| | | java.util.List<AuditResult> items = e.getValue(); |
| | | int groupStart = rowCursor; |
| | | StringBuilder problems = new StringBuilder(); |
| | | int seq = 0; |
| | | for (AuditResult it : items) { |
| | | Row row = ms.createRow(rowCursor++); |
| | | if (seq == 0) { |
| | | row.createCell(0).setCellValue(valueOf(it.getReportPeriod())); |
| | | row.createCell(1).setCellValue(valueOf(it.getEnterpriseName()).isEmpty() ? e.getKey() : valueOf(it.getEnterpriseName())); |
| | | } |
| | | row.createCell(2).setCellValue(valueOf(it.getRuleName())); |
| | | row.createCell(3).setCellValue(valueOf(it.getActualValue())); |
| | | row.createCell(4).setCellValue(valueOf(it.getThresholdValue())); |
| | | row.createCell(5).setCellValue(valueOf(it.getDeviation())); |
| | | seq++; |
| | | if (problems.length() > 0) problems.append("\n"); |
| | | problems.append(seq).append("、").append(issueSentence(it)); |
| | | } |
| | | if (rowCursor - groupStart > 1) { |
| | | ms.addMergedRegion(new org.apache.poi.ss.util.CellRangeAddress(groupStart, rowCursor - 1, 1, 1)); |
| | | ms.addMergedRegion(new org.apache.poi.ss.util.CellRangeAddress(groupStart, rowCursor - 1, 6, 6)); |
| | | } |
| | | Row first = ms.getRow(groupStart); |
| | | if (first.getCell(6) == null) first.createCell(6); |
| | | first.getCell(6).setCellValue(problems.toString()); |
| | | } |
| | | int[] widths2 = {12, 30, 22, 34, 22, 34, 60}; |
| | | for (int i = 0; i < widths2.length; i++) { |
| | | ms.setColumnWidth(i, widths2[i] * 256); |
| | | } |
| | | ByteArrayOutputStream out = new ByteArrayOutputStream(); |
| | | wb.write(out); |
| | | return out.toByteArray(); |
| | | } |
| | | } |
| | | |
| | | private void writeAuditHeader(Sheet sheet, String[] headers) { |
| | | Row head = sheet.createRow(0); |
| | | for (int i = 0; i < headers.length; i++) { |
| | | Cell cell = head.createCell(i); |
| | | cell.setCellValue(headers[i]); |
| | | org.apache.poi.ss.usermodel.CellStyle style = sheet.getWorkbook().createCellStyle(); |
| | | org.apache.poi.ss.usermodel.Font font = sheet.getWorkbook().createFont(); |
| | | font.setBold(true); |
| | | style.setFont(font); |
| | | cell.setCellStyle(style); |
| | | } |
| | | } |
| | | |
| | | /** 提醒型规则:仅提示变化、不需人工核实(如 RULE_004 货运类型环比提醒) */ |
| | | private boolean isReminderRule(String ruleCode) { |
| | | return "RULE_004".equals(ruleCode); |
| | | } |
| | | |
| | | /** 企业合并“问题”列话术:按规则类型生成可读的核实意见 */ |
| | | private String issueSentence(AuditResult res) { |
| | | String code = res.getRuleCode(); |
| | | String dev = valueOf(res.getDeviation()); |
| | | String act = valueOf(res.getActualValue()); |
| | | String thr = valueOf(res.getThresholdValue()); |
| | | if ("RULE_001".equals(code) || "RULE_002".equals(code)) { |
| | | return "企业上报车辆/吨位与运政数据对比存在差异(" + dev + "),请核实"; |
| | | } |
| | | if ("RULE_003".equals(code)) { |
| | | return "上报周转量与轨迹测算周转量差异明显(" + dev + "),请参考轨迹核实企业周转量"; |
| | | } |
| | | if ("RULE_004".equals(code)) { |
| | | return "货运类型环比发生变化,请核实"; |
| | | } |
| | | if ("RULE_005".equals(code)) { |
| | | return "无集装箱车但存在集装箱货运量,请核实车辆类型与货运量填报"; |
| | | } |
| | | if ("RULE_006".equals(code)) { |
| | | return "整车吨位超出 4~40 吨合理范围,请核实平均吨位填报"; |
| | | } |
| | | return valueOf(res.getRuleName()) + "异常(实际:" + act + ";基准:" + thr + ";" + dev + "),请核实"; |
| | | } |
| | | |
| | | private String auditStatusCn(String status) { |
| | | if ("CONFIRMED".equals(status)) return "已确认"; |
| | | if ("IGNORED".equals(status)) return "已忽略"; |