package com.ruoyi.requier.handler; import cn.hutool.core.util.ObjectUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.deepoove.poi.data.*; import com.deepoove.poi.data.style.*; import com.ruoyi.framework.util.MyUtil; import com.ruoyi.inspect.dto.SampleProductDto; import com.ruoyi.inspect.mapper.InsOrderMapper; import com.ruoyi.inspect.mapper.InsSampleMapper; import com.ruoyi.inspect.pojo.InsProduct; import com.ruoyi.inspect.pojo.InsReport; import com.ruoyi.requier.service.impl.InsOrderPlanServiceImpl; import org.apache.commons.lang3.StringUtils; import org.apache.poi.xwpf.usermodel.ParagraphAlignment; import org.apache.poi.xwpf.usermodel.TableRowAlign; import org.apache.poi.xwpf.usermodel.XWPFTable; import org.apache.poi.xwpf.usermodel.XWPFTableCell; import java.text.Collator; import java.util.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; /** * 基础报告处理类 */ public class BasicReportHandler { /** * 默认表格宽度 */ private final static int[] DEFAULT_COL_WIDTHS = {650, 1600, 2000, 750, 2800, 1100, 1100}; /** * 光纤表格宽度 */ private final static int[] FIBER_COL_WIDTHS = {650, 1700, 2000, 750, 2000, 1800, 1100}; private final InsOrderMapper baseMapper; private final InsOrderPlanServiceImpl insOrderPlanServiceImpl; private final InsSampleMapper insSampleMapper; public BasicReportHandler(InsOrderMapper insOrderMapper, InsOrderPlanServiceImpl insOrderPlanServiceImpl, InsSampleMapper insSampleMapper){ this.baseMapper = insOrderMapper; this.insOrderPlanServiceImpl = insOrderPlanServiceImpl; this.insSampleMapper = insSampleMapper; } /** * 写入方法 * @param samples 所有样品 * @param insReport report对象 * @param tables 检验项表格数据 * @param standardMethod 标准方法 * @param models 所有样品的型号 * @param unEqualSet 去重的所有检验项目数量 * @param modelDl 电力特殊型号处理 * @param deviceSet 去重的所有检验项使用设备列表 */ public void doWrite(List samples, InsReport insReport, List> tables, Set standardMethod, Set models, Set unEqualSet, List modelDl, Set deviceSet){ //处理光纤项目和松套管,排除温度循环 List fiberList = new ArrayList<>(); samples.forEach(s->{ fiberList.addAll(s.getInsProduct().stream().filter(p->(p.getSonLaboratory().equals("光纤试验室")&&Objects.isNull(p.getSpecialItemParentId()) ||(p.getSonLaboratory().equals("材料试验室")&&Objects.nonNull(p.getInsFiberId())) ||(p.getInspectionItem().contains("松套管")||p.getInspectionItemSubclass().contains("松套管"))) &&!p.getInspectionItem().equals("温度循环")).collect(Collectors.toList())); }); if(!fiberList.isEmpty()){ //根据检验项分组 Map> groupMap = fiberList.stream().collect(Collectors.groupingBy(g -> MyUtil.joinChars("",g.getInspectionItem(),g.getInspectionItemSubclass()))); SampleProductDto sampleProductDto = new SampleProductDto(); List handleProductList = new ArrayList<>(); for (String s : groupMap.keySet()) { if(!groupMap.get(s).isEmpty()){ List lastValueList = groupMap.get(s).stream().map(InsProduct::getLastValue).map(String::trim).collect(Collectors.toList()); String lastValue = ""; boolean a = lastValueList.contains("符合"); if(lastValueList.contains("符合") || lastValueList.contains("不符合") || lastValueList.contains("不判定")){ long count1 = lastValueList.stream().filter(f->f.equals("符合")).count(); long count2 = lastValueList.stream().filter(f->f.equals("不符合")).count(); if(count1>0&&count2==0){ lastValue = "符合"; }else if(count2>0){ lastValue = "不符合"; }else{ lastValue="不判定"; } }else { double maxLastValue = lastValueList.stream().mapToDouble(Double::parseDouble).max().orElse(0); double minLastValue = lastValueList.stream().mapToDouble(Double::parseDouble).min().orElse(0); lastValue = minLastValue+"-"+maxLastValue; } InsProduct insProduct = groupMap.get(s).get(0); sampleProductDto.setModel(insProduct.getModel()); insProduct.setLastValue(lastValue); handleProductList.add(insProduct); } } handleProductList.sort((o1,o2)->{ //根据检验项排序 if(!Objects.equals(o1.getInspectionItem(),o2.getInspectionItem())){ List specialItems = Arrays.asList("耐环境应力开裂","热收缩率"); if(specialItems.contains(o1.getInspectionItem()) && specialItems.contains(o2.getInspectionItem())){ return Integer.MAX_VALUE; } Collator instance = Collator.getInstance(Locale.CHINA); return instance.compare(o1.getInspectionItem(),o2.getInspectionItem()); } //检验子项排序 if(StringUtils.isNotBlank(o1.getInspectionItemSubclass())&& StringUtils.isNotBlank(o2.getInspectionItemSubclass())){ if(!Objects.equals(o1.getInspectionItemSubclass(),o2.getInspectionItemSubclass())){ Collator instance = Collator.getInstance(Locale.CHINA); return instance.compare(o1.getInspectionItemSubclass(),o2.getInspectionItemSubclass()); } } return 0; }); sampleProductDto.setInsProduct(handleProductList); //写入表格 writeTableRow(sampleProductDto,insReport,tables,FIBER_COL_WIDTHS); } samples.forEach(a -> { Set set = new HashSet<>(); Map map2 = new HashMap<>(); //添加所有检验项 unEqualSet.addAll(a.getInsProduct().stream().map(m->m.getInspectionItem()+m.getInspectionItemSubclass()).collect(Collectors.toList())); models.add(a.getModel()); standardMethod.add(baseMapper.getStandardMethodCode(a.getStandardMethodListId())); insOrderPlanServiceImpl.getTemplateThing(set, map2, a.getInsProduct()); for (InsProduct b : a.getInsProduct()) { if("电力试验室".equals(b.getSonLaboratory()) && Arrays.asList("钢材","铝材").contains(b.getSample())){ modelDl.add(b.getModel()); } if (b.getInsProductResult() != null) { if (ObjectUtils.isNotEmpty(b.getInsProductResult().getEquipValue())) { List jsonObjects = JSON.parseArray(b.getInsProductResult().getEquipValue(), JSONObject.class); for (JSONObject jsonObject : jsonObjects) { if (!(jsonObject.get("v") + "").isEmpty()) { deviceSet.add(jsonObject.get("v") + ""); } } } } } //写入表格 //排除光纤试验室的项目和松套管,除了温度循环 a.setInsProduct(a.getInsProduct().stream() .filter(p->(!p.getSonLaboratory().equals("光纤试验室")&&Objects.isNull(p.getInsFiberId()))||p.getInspectionItem().equals("温度循环")) .filter(p->!p.getInspectionItem().contains("松套管")&&!p.getInspectionItemSubclass().contains("松套管")) .collect(Collectors.toList())); writeTableRow(a,insReport,tables,DEFAULT_COL_WIDTHS); }); } /** * 写入表格行 * @param a 样品信息 * @param insReport report对象 * @param tables 检验项表格对象 * @param colWidths 表格列宽设置 */ private static void writeTableRow(SampleProductDto a,InsReport insReport,List> tables,int[] colWidths){ List rows = new ArrayList<>(); AtomicInteger index = new AtomicInteger(); Set itemSet = new HashSet<>(); for (int i = 0; i < 3 + a.getInsProduct().size(); i++) { RowRenderData rowRenderData = new RowRenderData(); RowStyle rowStyle = new RowStyle(); rowStyle.setHeight(40); rowRenderData.setRowStyle(rowStyle); List cells = new ArrayList<>(); if (i >= 2 && i < 2 + a.getInsProduct().size()) { if (itemSet.add(a.getInsProduct().get(i - 2).getInspectionItem())) { index.getAndIncrement(); } } //列数 for (int j = 0; j < 7; j++) { CellRenderData cellRenderData = new CellRenderData(); CellStyle cellStyle = new CellStyle(); cellStyle.setVertAlign(XWPFTableCell.XWPFVertAlign.CENTER); cellRenderData.setCellStyle(cellStyle); List paragraphRenderDataList = new ArrayList<>(); ParagraphRenderData paragraphRenderData = new ParagraphRenderData(); ParagraphStyle paragraphStyle = new ParagraphStyle(); paragraphStyle.setAlign(ParagraphAlignment.CENTER); paragraphRenderData.setParagraphStyle(paragraphStyle); List renderData = new ArrayList<>(); TextRenderData textRenderData = new TextRenderData(); Style style = new Style(); style.setFontFamily("宋体"); style.setFontSize(10); style.setColor("000000"); textRenderData.setStyle(style); if (i == 0) { //第一行 if (j == 0 || j == 1) { //第一列和第二列 if(StringUtils.isNotBlank(a.getSampleCode())){ textRenderData.setText("样品编号@Sample number∑1"); }else{ textRenderData.setText("规格型号@Type∑0302"); } renderData.add(textRenderData); paragraphRenderData.setContents(renderData); paragraphRenderDataList.add(paragraphRenderData); cellRenderData.setParagraphs(paragraphRenderDataList); cells.add(cellRenderData); } else if (j == 2 || j == 3) { //第三列和第四列 if(StringUtils.isNotBlank(a.getSampleCode())){ textRenderData.setText(a.getSampleCode() + "∑2"); }else{ textRenderData.setText("规格型号@Type∑0302"); } renderData.add(textRenderData); paragraphRenderData.setContents(renderData); paragraphRenderDataList.add(paragraphRenderData); cellRenderData.setParagraphs(paragraphRenderDataList); cells.add(cellRenderData); } else if (j == 4) { //第五列 textRenderData.setText("规格型号@Type∑0302"); renderData.add(textRenderData); paragraphRenderData.setContents(renderData); paragraphRenderDataList.add(paragraphRenderData); cellRenderData.setParagraphs(paragraphRenderDataList); cells.add(cellRenderData); } else { //第六列和第七列 textRenderData.setText(a.getModel() + "∑3"); renderData.add(textRenderData); paragraphRenderData.setContents(renderData); paragraphRenderDataList.add(paragraphRenderData); cellRenderData.setParagraphs(paragraphRenderDataList); cells.add(cellRenderData); } } else if (i == 1) { //第二行 if (j == 0) { //第一列 textRenderData.setText("序号@No."); renderData.add(textRenderData); paragraphRenderData.setContents(renderData); paragraphRenderDataList.add(paragraphRenderData); cellRenderData.setParagraphs(paragraphRenderDataList); cells.add(cellRenderData); } else if (j == 1 || j == 2) { //第二列和第三列 textRenderData.setText("检测项目@Testing item∑4"); renderData.add(textRenderData); paragraphRenderData.setContents(renderData); paragraphRenderDataList.add(paragraphRenderData); cellRenderData.setParagraphs(paragraphRenderDataList); cells.add(cellRenderData); } else if (j == 3) { //第四列 textRenderData.setText("单位@Unit"); renderData.add(textRenderData); paragraphRenderData.setContents(renderData); paragraphRenderDataList.add(paragraphRenderData); cellRenderData.setParagraphs(paragraphRenderDataList); cells.add(cellRenderData); } else if (j == 4) { //第五列 textRenderData.setText("标准要求@Requirement"); renderData.add(textRenderData); paragraphRenderData.setContents(renderData); paragraphRenderDataList.add(paragraphRenderData); cellRenderData.setParagraphs(paragraphRenderDataList); cells.add(cellRenderData); } else if (j == 5) { //第六列 textRenderData.setText("检验结果@Test result"); renderData.add(textRenderData); paragraphRenderData.setContents(renderData); paragraphRenderDataList.add(paragraphRenderData); cellRenderData.setParagraphs(paragraphRenderDataList); cells.add(cellRenderData); } else { //第七列 textRenderData.setText("结论@Conclusion"); renderData.add(textRenderData); paragraphRenderData.setContents(renderData); paragraphRenderDataList.add(paragraphRenderData); cellRenderData.setParagraphs(paragraphRenderDataList); cells.add(cellRenderData); } } else if (i == 2 + a.getInsProduct().size()) { //最后一行 if (j == 0 || j == 1) { //第一列和第二列 textRenderData.setText("备注∑5"); renderData.add(textRenderData); paragraphRenderData.setContents(renderData); paragraphRenderDataList.add(paragraphRenderData); cellRenderData.setParagraphs(paragraphRenderDataList); cells.add(cellRenderData); } else { //其余列 textRenderData.setText("“√”表示项目合格,“×”表示项目不合格。@“√” indicates test item is qualified,“×” indicates test item is not qualified ∑6"); renderData.add(textRenderData); paragraphRenderData.setContents(renderData); paragraphRenderDataList.add(paragraphRenderData); cellRenderData.setParagraphs(paragraphRenderDataList); cells.add(cellRenderData); } } else { //其余行 if (j == 0) { //第一列 textRenderData.setText(index + "∑2" + index); renderData.add(textRenderData); paragraphRenderData.setContents(renderData); paragraphRenderDataList.add(paragraphRenderData); cellRenderData.setParagraphs(paragraphRenderDataList); cells.add(cellRenderData); } else if (j == 1) { //第二列 InsProduct insProduct = a.getInsProduct().get(i - 2); if (ObjectUtil.isNotEmpty(insProduct.getInspectionItemSubclass())) { if (ObjectUtil.isNotEmpty(insProduct.getInspectionItemEn())) { String str = MyUtil.joinChars("@",insProduct.getInspectionItem(),insProduct.getInspectionItemEn()); textRenderData.setText(str + "∑3" + str); } else { textRenderData.setText(insProduct.getInspectionItem() + "∑3" + insProduct.getInspectionItem()); } } else { if (ObjectUtil.isNotEmpty(insProduct.getInspectionItemEn())) { String str = MyUtil.joinChars("@",insProduct.getInspectionItem(),insProduct.getInspectionItemEn()); textRenderData.setText(str + "∑3" + str); } else { textRenderData.setText(insProduct.getInspectionItem() + "∑3" + insProduct.getInspectionItem()); } } renderData.add(textRenderData); paragraphRenderData.setContents(renderData); paragraphRenderDataList.add(paragraphRenderData); cellRenderData.setParagraphs(paragraphRenderDataList); cells.add(cellRenderData); } else if (j == 2) { //第三列 InsProduct insProduct = a.getInsProduct().get(i - 2); if (ObjectUtil.isNotEmpty(insProduct.getInspectionItemSubclass())) { if (ObjectUtil.isNotEmpty(insProduct.getInspectionItemSubclassEn())) { String str = MyUtil.joinChars("@",insProduct.getInspectionItemSubclass(),insProduct.getInspectionItemSubclassEn()); textRenderData.setText(str); } else { textRenderData.setText(insProduct.getInspectionItemSubclass()); } } else { if (ObjectUtil.isNotEmpty(insProduct.getInspectionItemEn())) { String str = MyUtil.joinChars("@",insProduct.getInspectionItem(),insProduct.getInspectionItemEn()); textRenderData.setText(str + "∑3" + str); } else { textRenderData.setText(insProduct.getInspectionItem() + "∑3" + insProduct.getInspectionItem()); } } renderData.add(textRenderData); paragraphRenderData.setContents(renderData); paragraphRenderDataList.add(paragraphRenderData); cellRenderData.setParagraphs(paragraphRenderDataList); cells.add(cellRenderData); } else if (j == 3) { //第四列 textRenderData.setText(ObjectUtil.isNotEmpty(a.getInsProduct().get(i - 2).getUnit()) ? a.getInsProduct().get(i - 2).getUnit() : ""); renderData.add(textRenderData); paragraphRenderData.setContents(renderData); paragraphRenderDataList.add(paragraphRenderData); cellRenderData.setParagraphs(paragraphRenderDataList); cells.add(cellRenderData); } else if (j == 4) { //第五列 textRenderData.setText(a.getInsProduct().get(i - 2).getTell()); renderData.add(textRenderData); paragraphRenderData.setContents(renderData); paragraphRenderDataList.add(paragraphRenderData); cellRenderData.setParagraphs(paragraphRenderDataList); cells.add(cellRenderData); } else if (j == 5) { //第六列 textRenderData.setText(a.getInsProduct().get(i - 2).getLastValue()); renderData.add(textRenderData); paragraphRenderData.setContents(renderData); paragraphRenderDataList.add(paragraphRenderData); cellRenderData.setParagraphs(paragraphRenderDataList); cells.add(cellRenderData); } else { //第七列 InsProduct p = a.getInsProduct().get(i - 2); if (p.getInsResult() == 0) { textRenderData.setText("×"); } else if (a.getInsProduct().get(i - 2).getInsResult() == 1) { textRenderData.setText("√"); } else { textRenderData.setText("-"); } renderData.add(textRenderData); paragraphRenderData.setContents(renderData); paragraphRenderDataList.add(paragraphRenderData); cellRenderData.setParagraphs(paragraphRenderDataList); cells.add(cellRenderData); } } } rowRenderData.setCells(cells); if (!rowRenderData.getCells().isEmpty()) { rows.add(rowRenderData); } } //写入表格的行 TableRenderData tableRenderData = new TableRenderData(); tableRenderData.setRows(rows); List tables1 = new ArrayList<>(); tableRenderData.setRows(new ArrayList<>()); double totalHeight = 0; double heightThreshold = 700.0; // 单页高度阈值 List firstTwoRows = new ArrayList<>(); // 保存前两行以便复制到新表格 List endRows = new ArrayList<>(); // 保存前两行以便复制到新表格 // 保存前两行以便复制到新表格 firstTwoRows.add(rows.get(0)); firstTwoRows.add(rows.get(1)); endRows.add(rows.get(rows.size() - 1)); for (RowRenderData row : rows) { double rowHeight = row.getRowStyle().getHeight(); // 获取当前行的行高 // 判断字体内容是否有多的, 多的行高乘倍数 RowRenderData lastRaw = rows.get(rows.size() - 1); // 排除最后一行 if (rows.get(0) != row && rows.get(1) != row && lastRaw != row) { // 调整高度 rowHeight = adjustRowHeight(row, rowHeight); } totalHeight += rowHeight; // 更新总行高 if (totalHeight> heightThreshold) { tableRenderData.getRows().addAll(endRows); // 创建新表格并复制前两行 TableRenderData newTableRenderData = new TableRenderData(); newTableRenderData.setRows(new ArrayList<>(firstTwoRows)); //设置样式 TableStyle tableStyle = new TableStyle(); tableStyle.setColWidths(colWidths); tableStyle.setWidth("10000"); tableStyle.setAlign(TableRowAlign.CENTER); BorderStyle borderStyle = new BorderStyle(); borderStyle.setColor("000000"); borderStyle.setType(XWPFTable.XWPFBorderType.THICK); borderStyle.setSize(14); tableStyle.setLeftBorder(borderStyle); tableStyle.setTopBorder(borderStyle); tableStyle.setRightBorder(borderStyle); tableStyle.setBottomBorder(borderStyle); tableRenderData.setTableStyle(tableStyle); newTableRenderData.setTableStyle(tableStyle); // 添加最后一行 tableRenderData.addRow(rows.get(rows.size() - 1)); tables1.add(tableRenderData); tableRenderData = newTableRenderData; totalHeight = 180 + rowHeight;//180为新页面表头和最后一行的高度 } tableRenderData.getRows().add(row); } if (!tableRenderData.getRows().isEmpty() && tableRenderData.getRows().size() != 3) { //设置样式 TableStyle tableStyle = new TableStyle(); tableStyle.setColWidths(colWidths); tableStyle.setWidth("10000"); tableStyle.setAlign(TableRowAlign.CENTER); BorderStyle borderStyle = new BorderStyle(); borderStyle.setColor("000000"); borderStyle.setType(XWPFTable.XWPFBorderType.THICK); borderStyle.setSize(14); tableStyle.setLeftBorder(borderStyle); tableStyle.setTopBorder(borderStyle); tableStyle.setRightBorder(borderStyle); tableStyle.setBottomBorder(borderStyle); tableRenderData.setTableStyle(tableStyle); tables1.add(tableRenderData); } tables1.forEach(table -> { Map tableMap = new HashMap<>(); tableMap.put("table", table); tableMap.put("report", insReport); tables.add(tableMap); }); } /** * 调整高度 * @param row * @param rowHeight * @return */ private static double adjustRowHeight(RowRenderData row, double rowHeight) { // 根据检验项目名称进行高度调整 //根据检验项(i:1)、检验子项(i:2)、标准要求(i:4)中字符最长的来计算 TextRenderData insItemData = (TextRenderData) row.getCells().get(1).getParagraphs().get(0).getContents().get(0); if(insItemData.getText().contains("成分分析")){ return rowHeight; } TextRenderData insSubItemData = (TextRenderData) row.getCells().get(2).getParagraphs().get(0).getContents().get(0); TextRenderData requiredData = (TextRenderData) row.getCells().get(4).getParagraphs().get(0).getContents().get(0); String dataText = insItemData.getText(); if(insSubItemData.getText().length()>dataText.length()){ dataText = insSubItemData.getText(); } if(Objects.nonNull(requiredData) && requiredData.getText().length()>dataText.length()){ dataText = requiredData.getText(); } TextRenderData valueData = (TextRenderData) row.getCells().get(5).getParagraphs().get(0).getContents().get(0); String valueText = valueData.getText(); // 获取检测内容判断是否超出 if (StringUtils.isNotBlank(dataText)) { double number = 1; double chinaLength = 10; double englishLength = 20; double valueLength = 2; // 根据@符号截取中英文 String[] splits = dataText.split("∑"); String[] split; if(splits.length>0){ split = splits[0].split("@"); }else{ split = dataText.split("@"); } // 文字倍数 double chinaMultiple = (Math.ceil(split[0].length() / chinaLength)) - 1; // 英文倍数 double englishMultiple = 0; if(split.length>1){ englishMultiple = (Math.ceil(split[1].length() / englishLength)) - 1; } double multiple = number + chinaMultiple * 0.5 + englishMultiple * 0.5; if (StringUtils.isNotBlank(valueText)) { double valueMultiple = (Math.ceil(valueText.length() / valueLength)) - 1; if (multiple < number + valueMultiple * 0.4) { multiple = number + valueMultiple * 0.4; } } rowHeight = rowHeight * multiple; } return rowHeight; } }