From 3e69f49ab60292a75b6bf04024e8049ceafdd3b7 Mon Sep 17 00:00:00 2001 From: bai <1643359946@qq.com> Date: Tue, 14 Nov 2023 02:16:39 +0800 Subject: [PATCH] =?UTF-8?q?2023=E5=B9=B411=E6=9C=8814=E6=97=A5=20=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E5=AF=BC=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modules/kc/jiaoshi/export/Export.java | 301 +++++++++++++++--- .../modules/tools/word/WordOperator.java | 36 +++ .../officetemplates/exp1/zhjs-tjfxbg.docx | Bin 22315 -> 22505 bytes 3 files changed, 286 insertions(+), 51 deletions(-) diff --git a/jeecg-module-main/src/main/java/org/jeecg/modules/kc/jiaoshi/export/Export.java b/jeecg-module-main/src/main/java/org/jeecg/modules/kc/jiaoshi/export/Export.java index 75339384..664f0ae3 100644 --- a/jeecg-module-main/src/main/java/org/jeecg/modules/kc/jiaoshi/export/Export.java +++ b/jeecg-module-main/src/main/java/org/jeecg/modules/kc/jiaoshi/export/Export.java @@ -1,6 +1,5 @@ package org.jeecg.modules.kc.jiaoshi.export; -import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.ArrayUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.beust.jcommander.internal.Sets; @@ -8,30 +7,22 @@ import com.google.common.collect.Lists; import com.google.common.collect.Maps; import lombok.Data; import org.apache.commons.lang3.StringUtils; -import org.jeecg.common.system.query.QueryGenerator; -import org.jeecg.common.system.vo.DictModel; import org.jeecg.common.util.SpringContextHolder; -import org.jeecg.modules.kc.config.entity.KcExportConfigTpkwcqkjzglx; -import org.jeecg.modules.kc.config.service.IKcExportConfigTpkwcqkjzglxService; -import org.jeecg.modules.kc.grab.SynchronizationService.tools.ChangeTingKeTongJi; -import org.jeecg.modules.kc.grab.imports.entity.Xxhbuser; -import org.jeecg.modules.kc.grab.imports.service.IXxhbuserService; import org.jeecg.modules.kc.jiaoshi.entity.KcZhihuijiaoshiMonitorLog; import org.jeecg.modules.kc.jiaoshi.service.IKcZhihuijiaoshiMonitorLogService; -import org.jeecg.modules.kc.kcXqxnHistory.entity.KcXqxnHistory; -import org.jeecg.modules.kc.tksf.kctkcstj.entity.KcTkcstj; -import org.jeecg.modules.kc.tksf.kctkcstj.service.IKcTkcstjService; -import org.jeecg.modules.system.service.ISysDictService; import org.jeecg.modules.tools.word.BaseExport; import org.jeecg.modules.tools.word.ExportWord; import org.jeecg.modules.tools.word.WordOperator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import java.math.BigDecimal; import java.math.RoundingMode; -import java.util.*; +import java.text.DecimalFormat; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.stream.Collectors; @@ -78,9 +69,56 @@ public class Export extends BaseExport { // public List getDictList(String dictCode){ // return sysDictService.queryDictItemsByCode(dictCode); // } + //不保留小数 + DecimalFormat dfz = new DecimalFormat("0"); + + /** + * 转换为 *** + * @param num 数字 + * @return 字符型的***数字 + */ + public String dfzf(String num){ + return dfzf(new BigDecimal(num)); + } + + /** + * 转换为 *** + * @param num 数字 + * @return 字符型的***数字 + */ + public String dfzf(BigDecimal num){ + return dfz.format(num); + } + + //保留两位小数 + public static DecimalFormat dfzdzz = new DecimalFormat("0.00"); + + /** + * 转换为 ***.** + * @param num 数字 + * @return 字符型的***.**数字 + */ + public String dfzdzzf(String num){ + return dfzdzz.format(new BigDecimal(num)); + } + + /** + * 转换为 ***.** + * @param num 数字 + * @return 字符型的***.**数字 + */ + public String dfzdzzf(BigDecimal num){ + return dfzdzz.format(num); + } //数量÷总数×100 public BigDecimal getPercentage(BigDecimal zc, BigDecimal yc){ + if(zc.compareTo(new BigDecimal(0)) == 0){ + return new BigDecimal("0"); + } + if(yc.compareTo(new BigDecimal(0)) == 0){ + return new BigDecimal("0"); + } BigDecimal all = zc.add(yc); return zc.divide(all, 2, RoundingMode.HALF_UP).multiply(new BigDecimal("100")); } @@ -100,6 +138,27 @@ public class Export extends BaseExport { if(num == null) return 0; return num; } + @Data + public class TwoYcListClass { + private String ycHh;//异常节次 + private String ycKcmc;//异常课程名称 + private String ycDate;//异常时间 + + private Integer jccs;//监测次数 + private Integer yccs;//异常次数 + + public void addJccs(Integer num){ + if(this.jccs == null) this.jccs = 0; + if(num == null) return; + this.jccs += num; + } + public void addYccs(Integer num){ + if(this.yccs == null) this.yccs = 0; + if(num == null) return; + this.yccs += num; + } + + } @Data @@ -112,13 +171,14 @@ public class Export extends BaseExport { private Integer yckts = 0;//异常课堂数 private String ycqksm;//异常情况说明 - private List ycHhList = Lists.newArrayList();//异常节次 - private List ycKcmcList = Lists.newArrayList();//异常课程名称 - - private List jccsList = Lists.newArrayList();//监测次数 - private List yccsList = Lists.newArrayList();//异常次数 - private List yclList = Lists.newArrayList();//异常率 + private Map ycMap = Maps.newLinkedHashMap(); +// private List ycHhList = Lists.newArrayList();//异常节次 +// private List ycKcmcList = Lists.newArrayList();//异常课程名称 +// +// private List jccsList = Lists.newArrayList();//监测次数 +// private List yccsList = Lists.newArrayList();//异常次数 +// private List yclList = Lists.newArrayList();//异常率 public void addKfkts(Integer num){ if(this.kfkts == null) this.kfkts = 0; if(num == null) return; @@ -204,7 +264,7 @@ public class Export extends BaseExport { //查询日志 QueryWrapper mainQw = new QueryWrapper<>(); mainQw.isNotNull("kt_id"); - mainQw.ge(StringUtils.isNotBlank(kcZhihuijiaoshiMonitorLog.getStartTime()),"create_time",kcZhihuijiaoshiMonitorLog.getStartTime()); + mainQw.ge(StringUtils.isNotBlank(kcZhihuijiaoshiMonitorLog.getStartTime()),"create_time",kcZhihuijiaoshiMonitorLog.getStartTime() + " 07:02:00"); mainQw.le(StringUtils.isNotBlank(kcZhihuijiaoshiMonitorLog.getEndTime()),"create_time",kcZhihuijiaoshiMonitorLog.getEndTime() + " 23:59:59"); if(StringUtils.isNotBlank(kcZhihuijiaoshiMonitorLog.getJxlName())){ mainQw.in("jxl_name", Arrays.asList(StringUtils.split(kcZhihuijiaoshiMonitorLog.getJxlName(),","))); @@ -212,7 +272,7 @@ public class Export extends BaseExport { List mainLogList = kcZhihuijiaoshiMonitorLogService.list(mainQw); if(mainLogList.isEmpty()){ // String today= DateUtil.today(); - result.put("监测时间", kcZhihuijiaoshiMonitorLog.getStartTime() + "-" + kcZhihuijiaoshiMonitorLog.getEndTime()); + result.put("监测时间", kcZhihuijiaoshiMonitorLog.getStartTime() + " - " + kcZhihuijiaoshiMonitorLog.getEndTime()); result.put("监测教学楼", kcZhihuijiaoshiMonitorLog.getJxlName()); result.put("教学楼数", "0"); result.put("教室数", "0"); @@ -224,6 +284,22 @@ public class Export extends BaseExport { wo.insert2Table(0, 2, true, Lists.newArrayList()); wo.insert2Table(1, 1, true, Lists.newArrayList()); } + //01 聚合数据, + Map mainLogMap = Maps.newHashMap(); + for(KcZhihuijiaoshiMonitorLog mainLog: mainLogList){ + String day = formatDate(mainLog.getCreateTime(), "yyyy-MM-dd"); + String key = day + "-" + mainLog.getHh() + "-" + mainLog.getKtId(); + if(mainLogMap.containsKey(key)){ + //KcZhihuijiaoshiMonitorLog mmainLog = mainLogMap.get(key); + if(mainLog.getLogType() == null || mainLog.getLogType() != 1){ + //失败的,瞬间污染全局 + mainLogMap.put(key,mainLog); + } + }else{ + mainLogMap.put(key,mainLog); + } + } + //折腾数据 int jxls = 0; int jss = 0; @@ -242,7 +318,7 @@ public class Export extends BaseExport { Map oneListMap = Maps.newHashMap(); Map twoListMap = Maps.newHashMap(); - for(KcZhihuijiaoshiMonitorLog monitorLog: mainLogList){ + for(KcZhihuijiaoshiMonitorLog monitorLog: mainLogMap.values()){ //基础数据 jxlsSet.add(monitorLog.getJxlName()); jssSet.add(monitorLog.getJsmc()); @@ -275,27 +351,46 @@ public class Export extends BaseExport { } oneListMap.put(monitorLog.getJxlName() + "-" + monitorLog.getHh(),o); } + } + + for(KcZhihuijiaoshiMonitorLog monitorLog: mainLogList){ //教学楼 教室名称 开放课堂数 正常课堂率 正常课堂数 异常课堂数 异常情况说明 //第二集 if(twoListMap.containsKey(monitorLog.getJxlName() + monitorLog.getJsmc())){ //存在,累计数 TwoListClass o = twoListMap.get(monitorLog.getJxlName() + monitorLog.getJsmc()); - o.addKfkts(1); - if(monitorLog.getLogType() != null && monitorLog.getLogType() == 1){ - o.addZckts(1); - }else{ - o.addYckts(1); - -// String sm = "1.异常节次:"+getHhName(monitorLog.getHh())+" 异常课程:"+monitorLog.getKtName()+" 监测次数:"+" 异常次数:"+" 异常率:"+"";//1.异常节次: 异常课程: 监测次数: 异常次数: 异常率: -// o.setYcqksm(sm); - o.getYcHhList().add(getHhName(monitorLog.getHh())); - o.getYcKcmcList().add(monitorLog.getKtName());//异常课程名称 - o.getJccsList().add(1);//监测次数 - o.getYccsList().add(1);//异常次数 + String key = monitorLog.getJxlName() + monitorLog.getJsmc() + monitorLog.getHh() + monitorLog.getKtId(); + Map twoYcListClassMap = o.getYcMap(); + if(twoYcListClassMap.containsKey(key)){ + TwoYcListClass twoYcListClass = twoYcListClassMap.get(key); + //累计次数 + twoYcListClass.addJccs(1); + if(monitorLog.getLogType() == null || monitorLog.getLogType() != 1){ + //累加失败次数 + twoYcListClass.addYccs(1); + } + }else { + TwoYcListClass twoYcListClass = new TwoYcListClass(); + twoYcListClass.setYcHh(getHhName(monitorLog.getHh()));//异常节次 + twoYcListClass.setYcKcmc(monitorLog.getKtName());//异常课程名称 + twoYcListClass.setYcDate(formatDate(monitorLog.getCreateTime(), "yyyy-MM-dd")); + twoYcListClass.setJccs(1);//累计次数 + if(monitorLog.getLogType() != null && monitorLog.getLogType() == 1){ + twoYcListClass.setYccs(0);//异常次数 + }else{ + twoYcListClass.setYccs(1);//异常次数 + } // o.getYclList().add();//异常率 - + twoYcListClassMap.put(key,twoYcListClass); } + if(monitorLog.getLogType() != null && monitorLog.getLogType() == 1){ + o.addZckts(1);//正常课堂数 + }else{ + o.addYckts(1);//异常课堂数 + //ycqksm;//异常情况说明 + } + o.addKfkts(1); }else{ TwoListClass o = new TwoListClass(); o.setJxl(monitorLog.getJxlName()); @@ -304,6 +399,31 @@ public class Export extends BaseExport { // o.setZcktl(0); o.setZckts(0); o.setYckts(0); + + + String key = monitorLog.getJxlName() + monitorLog.getJsmc() + monitorLog.getHh() + monitorLog.getKtId(); + Map twoYcListClassMap = o.getYcMap(); + if(twoYcListClassMap.containsKey(key)){ + TwoYcListClass twoYcListClass = twoYcListClassMap.get(key); + //累计次数 + twoYcListClass.addJccs(1); + if(monitorLog.getLogType() == null || monitorLog.getLogType() != 1){ + //累加失败次数 + twoYcListClass.addYccs(1); + } + }else { + TwoYcListClass twoYcListClass = new TwoYcListClass(); + twoYcListClass.setYcHh(getHhName(monitorLog.getHh()));//异常节次 + twoYcListClass.setYcKcmc(monitorLog.getKtName());//异常课程名称 + twoYcListClass.setYcDate(formatDate(monitorLog.getCreateTime(), "yyyy-MM-dd")); + twoYcListClass.setJccs(1);//累计次数 + if(monitorLog.getLogType() != null && monitorLog.getLogType() == 1){ + twoYcListClass.setYccs(0);//异常次数 + }else{ + twoYcListClass.setYccs(1);//异常次数 + } + twoYcListClassMap.put(key,twoYcListClass); + } //zcktl;//正常课堂率 if(monitorLog.getLogType() != null && monitorLog.getLogType() == 1){ o.setZckts(1);//正常课堂数 @@ -327,7 +447,7 @@ public class Export extends BaseExport { //********************************取数据END*********************************************************/ //********************************通用*************************************************************/ // String today= DateUtil.today(); - result.put("监测时间", kcZhihuijiaoshiMonitorLog.getStartTime() + "-" + kcZhihuijiaoshiMonitorLog.getEndTime()); + result.put("监测时间", kcZhihuijiaoshiMonitorLog.getStartTime() + " - " + kcZhihuijiaoshiMonitorLog.getEndTime()); result.put("监测教学楼", kcZhihuijiaoshiMonitorLog.getJxlName()); result.put("教学楼数", String.valueOf(jxls)); result.put("教室数", String.valueOf(jss)); @@ -355,6 +475,29 @@ public class Export extends BaseExport { oneListMapMap.put(o.getJxlName(),m); } } + List sumList = Lists.newArrayList(); + sumList.add(new BigDecimal("0")); + sumList.add(new BigDecimal("0")); + sumList.add(new BigDecimal("0")); + + sumList.add(new BigDecimal("0")); + sumList.add(new BigDecimal("0")); + + sumList.add(new BigDecimal("0")); + sumList.add(new BigDecimal("0")); + + sumList.add(new BigDecimal("0")); + sumList.add(new BigDecimal("0")); + + sumList.add(new BigDecimal("0")); + sumList.add(new BigDecimal("0")); + + sumList.add(new BigDecimal("0")); + sumList.add(new BigDecimal("0")); + + sumList.add(new BigDecimal("0")); + sumList.add(new BigDecimal("0")); + for (String key: oneListMapMap.keySet()){ Map m = oneListMapMap.get(key); OneListClass all = new OneListClass(); @@ -441,27 +584,53 @@ public class Export extends BaseExport { list.add(String.valueOf(all.getKfnum())); list.add(String.valueOf(all.getZcnum())); list.add(String.valueOf(all.getYcnum())); + sumList.set(0,sumList.get(0).add(new BigDecimal(all.getKfnum()))); + sumList.set(1,sumList.get(1).add(new BigDecimal(all.getZcnum()))); + sumList.set(2,sumList.get(2).add(new BigDecimal(all.getYcnum()))); list.add(String.valueOf(one.getZcnum())); list.add(String.valueOf(one.getYcnum())); + sumList.set(3,sumList.get(3).add(new BigDecimal(one.getZcnum()))); + sumList.set(4,sumList.get(4).add(new BigDecimal(one.getYcnum()))); list.add(String.valueOf(two.getZcnum())); list.add(String.valueOf(two.getYcnum())); + sumList.set(5,sumList.get(5).add(new BigDecimal(two.getZcnum()))); + sumList.set(6,sumList.get(6).add(new BigDecimal(two.getYcnum()))); list.add(String.valueOf(three.getZcnum())); list.add(String.valueOf(three.getYcnum())); + sumList.set(7,sumList.get(7).add(new BigDecimal(three.getZcnum()))); + sumList.set(8,sumList.get(8).add(new BigDecimal(three.getYcnum()))); list.add(String.valueOf(four.getZcnum())); list.add(String.valueOf(four.getYcnum())); + sumList.set(9,sumList.get(9).add(new BigDecimal(four.getZcnum()))); + sumList.set(10,sumList.get(10).add(new BigDecimal(four.getYcnum()))); list.add(String.valueOf(five.getZcnum())); list.add(String.valueOf(five.getYcnum())); + sumList.set(11,sumList.get(11).add(new BigDecimal(five.getZcnum()))); + sumList.set(12,sumList.get(12).add(new BigDecimal(five.getYcnum()))); list.add(String.valueOf(six.getZcnum())); list.add(String.valueOf(six.getYcnum())); + sumList.set(13,sumList.get(13).add(new BigDecimal(six.getZcnum()))); + sumList.set(14,sumList.get(14).add(new BigDecimal(six.getYcnum()))); + mainList.add(list); } - + if(!oneListMapMap.keySet().isEmpty()){ + List sumRowlist = Lists.newArrayList(); + sumRowlist.add("合计"); + sumRowlist.add("0");//正常率 + for (BigDecimal sumNum: sumList){ + sumRowlist.add(dfzf(sumNum)); + } + //计算百分比 + sumRowlist.set(1,dfzdzzf(getPercentage(sumList.get(1), sumList.get(2)))); + mainList.add(sumRowlist); + } wo.insert2Table(0, 2, true, mainList); // index[0] += mainList.size() + 2; @@ -479,23 +648,53 @@ public class Export extends BaseExport { list.add(StringUtils.defaultString(String.valueOf(o.getZckts()),"0")); list.add(StringUtils.defaultString(String.valueOf(o.getYckts()),"0")); //1.异常节次: 异常课程: 监测次数: 异常次数: 异常率: - Integer jccs = 0; - - for (Integer x: o.getJccsList()){ - if(x == null) x = 0; - jccs += x; - } - Integer yccs = 0; -// for (Integer x: o.getYccsList()){ +// Integer jccs = 0; +// +// for (Integer x: o.getJccsList()){ // if(x == null) x = 0; -// yccs += x; +// jccs += x; // } - yccs = o.getYckts(); - String ycl = getPercentageByAll(new BigDecimal(yccs),new BigDecimal(o.getKfkts())).toString(); +// Integer yccs = 0; +//// for (Integer x: o.getYccsList()){ +//// if(x == null) x = 0; +//// yccs += x; +//// } +// yccs = o.getYckts(); +// String ycl = getPercentageByAll(new BigDecimal(yccs),new BigDecimal(o.getKfkts())).toString(); - String sm = "1.异常节次:"+ArrayUtil.join(o.getYcHhList().toArray(new String[]{}),",")+" 异常课程:"+ArrayUtil.join(o.getYcKcmcList().toArray(new String[]{}),",")+" 监测次数:"+jccs+" 异常次数:"+yccs+" 异常率:"+ycl; +// String sm = "1.异常节次:"+ArrayUtil.join(o.getYcHhList().toArray(new String[]{}),",")+" 异常课程:"+ArrayUtil.join(o.getYcKcmcList().toArray(new String[]{}),",")+" 监测次数:"+jccs+" 异常次数:"+yccs+" 异常率:"+ycl; + StringBuffer sm = new StringBuffer(); + Map twoYcListClassMap = o.getYcMap(); + int i = 1; + List nextBlockList = twoYcListClassMap.values().stream().filter(x -> x.getYccs() !=0).collect(Collectors.toList()); + for(TwoYcListClass twoYcListClass: nextBlockList){ + sm.append(String.valueOf(i)); + sm.append(".异常节次:"); + sm.append(twoYcListClass.getYcHh()); + sm.append("("); + sm.append(twoYcListClass.getYcDate()); + sm.append(")"); + sm.append(" 异常课程:"); + sm.append(twoYcListClass.getYcKcmc()); + sm.append(" 监测次数:"); + sm.append(twoYcListClass.getJccs()); + sm.append(" 异常次数:"); + sm.append(twoYcListClass.getYccs()); + sm.append(" 异常率:"); + //计算! + sm.append(getPercentageByAll(new BigDecimal(twoYcListClass.getYccs()),new BigDecimal(twoYcListClass.getJccs()))); + sm.append("\n"); + i++; + + } + + if(nextBlockList.isEmpty()){ + sm.append(" \n "); + } + +// String sm = "1.异常节次:"+ArrayUtil.join(o.getYcHhList().toArray(new String[]{}),",")+" 异常课程:"+ArrayUtil.join(o.getYcKcmcList().toArray(new String[]{}),",")+" 监测次数:"+jccs+" 异常次数:"+yccs+" 异常率:"+ycl; //list.add(o.getYcqksm()); - list.add(sm); + list.add(sm.toString()); mainList.add(list); } diff --git a/jeecg-module-main/src/main/java/org/jeecg/modules/tools/word/WordOperator.java b/jeecg-module-main/src/main/java/org/jeecg/modules/tools/word/WordOperator.java index c51a74f3..420dad08 100644 --- a/jeecg-module-main/src/main/java/org/jeecg/modules/tools/word/WordOperator.java +++ b/jeecg-module-main/src/main/java/org/jeecg/modules/tools/word/WordOperator.java @@ -904,6 +904,9 @@ public class WordOperator { // 取出这一行对应的数据,数据与单元格角标位置是一致的,一一替换文本 List colList = dataList.get(i); for (int j = 0; j < cellList.size(); j++) { + if(StringUtils.contains(colList.get(j),"\n")){ + setCellMultiLineText(cellList.get(j), colList, j); + } setCellText(cellList.get(j), colList, j); } } @@ -942,6 +945,39 @@ public class WordOperator { } } + + /** + * 替换单元格文本 + * @param cell 单元格 + * @param colList 替换文本的集合(角标越位了,就置空) + * @param j 单元格角标,也就是文本集合的角标 + */ + private void setCellMultiLineText(XWPFTableCell cell, List colList, int j) { +// cell.setColor("FF0000"); + // 无论一个单元格被切割成多少个run,只需要修改第一个即可,改完就return掉了 + List paragraphs = cell.getParagraphs(); + for (XWPFParagraph p : paragraphs) { + List runs = p.getRuns(); + //删除旧数据 + for (int i = 0; i< runs.size(); i++){ + p.removeRun(i); + } + XWPFRun r = p.createRun(); + try { + String allText = colList.get(j); + String[] texts = StringUtils.split(allText, "\n"); + for(String text: texts){ + r.setText(text); + r.addCarriageReturn(); + } + //染上背景色 +// r.getCTR().addNewRPr().addNewHighlight().setVal(STHighlightColor.YELLOW); + } catch (Exception e) { + r.setText("", 0); + } + } + } + /** * 填充颜色 * @param tableIndex 第几个表格,第一个表格为0 diff --git a/jeecg-module-main/src/main/resources/officetemplates/exp1/zhjs-tjfxbg.docx b/jeecg-module-main/src/main/resources/officetemplates/exp1/zhjs-tjfxbg.docx index f0a2ec7d56775985b2d2729904be54545e5e16f7..fde94d29d85daa052dc8d24636805d77b88eac12 100644 GIT binary patch delta 6185 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 delta 6076 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