| 
					
				 | 
			
			
				@@ -0,0 +1,944 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+package org.jeecg.modules.ProdPlan.service.impl; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.apache.commons.lang.StringUtils; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.apache.poi.hssf.usermodel.HSSFWorkbook; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.apache.poi.ss.usermodel.*; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.apache.poi.ss.util.CellRangeAddress; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.apache.poi.util.Units; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.apache.poi.xssf.usermodel.XSSFPicture; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.apache.poi.xssf.usermodel.XSSFWorkbook; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.jeecg.modules.Contact.entity.Contact; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.jeecg.modules.Contact.service.IContactService; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.jeecg.modules.DefectiveProduct.entity.DefectiveProduct; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.jeecg.modules.DefectiveProduct.service.IDefectiveProductService; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.jeecg.modules.DestRule.entity.DestRule; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.jeecg.modules.DestRule.service.IDestRuleService; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.jeecg.modules.ProdPlan.entity.DelayProduct; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.jeecg.modules.ProdPlan.entity.DeliveredQuantity; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.jeecg.modules.ProdPlan.entity.ProdPlan; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.jeecg.modules.ProdPlan.mapper.ProdPlanMapper; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.jeecg.modules.ProdPlan.service.IDelayProductService; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.jeecg.modules.ProdPlan.service.IDeliveredQuantityService; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.jeecg.modules.ProdPlan.service.IProdPlanService; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.jeecg.modules.ProdPlan.util.EmailUtil; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.jeecg.modules.ProdPlan.vo.ReportDetailVo; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.jeecg.modules.ReasonRule.entity.ReasonRule; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.jeecg.modules.ReasonRule.service.IReasonRuleService; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.jeecg.modules.RegionRule.entity.RegionRule; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.jeecg.modules.RegionRule.service.IRegionRuleService; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.jetbrains.annotations.NotNull; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.springframework.beans.BeanUtils; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.springframework.beans.factory.annotation.Autowired; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.springframework.stereotype.Service; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import java.io.ByteArrayOutputStream; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import java.io.FileInputStream; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import java.io.IOException; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import java.time.*; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import java.time.format.DateTimeFormatter; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import java.time.temporal.IsoFields; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import java.time.temporal.WeekFields; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import java.util.*; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import java.util.regex.Matcher; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import java.util.regex.Pattern; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import java.util.stream.Collectors; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @Description: 生产计划 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @Author: jeecg-boot 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @Date:   2025-06-04 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @Version: V1.0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@Service 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+public class ProdPlanServiceImpl extends ServiceImpl<ProdPlanMapper, ProdPlan> implements IProdPlanService { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    @Autowired 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private IDelayProductService delayProductService; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    @Autowired 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private IRegionRuleService regionRuleService; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    @Autowired 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private IDestRuleService destRuleService; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    @Autowired 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private IReasonRuleService reasonRuleService; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    @Autowired 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private IDefectiveProductService defectiveProductService; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    @Autowired 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private IDeliveredQuantityService deliveredQuantityService; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    @Autowired 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private IContactService contactService; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    @Override 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public List<DelayProduct> parseExcel(String filePath) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        List<DelayProduct> delayProducts = new ArrayList<>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        try (FileInputStream fis = new FileInputStream(filePath)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Workbook workbook; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 根据文件扩展名选择合适的工作簿类型 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (filePath.endsWith(".xlsx")) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                workbook = new XSSFWorkbook(fis); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } else if (filePath.endsWith(".xls")) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                workbook = new HSSFWorkbook(fis); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                throw new IllegalArgumentException("不支持的文件格式,请使用.xlsx或.xls文件"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            //第一张表 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Sheet sheet = workbook.getSheetAt(0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            //第二行为表头 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Row headerRow = sheet.getRow(1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (headerRow == null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                throw new RuntimeException("未找到表头行"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            //获取表头对应的列索引 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Map<String, Integer> columnIndices = parseHeadRow(headerRow); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            //获取表头中的日期列 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Map<String, Integer> dateColumnIndices = parseDateColumn(columnIndices); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            //从第三行开始读取数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            for (int i = 2; i <= sheet.getLastRowNum(); i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                Row row = sheet.getRow(i); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if(row==null) break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (row.getCell(columnIndices.get("Line"))==null) break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                parseDataRow(row, columnIndices, dateColumnIndices, delayProducts); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            List<RegionRule> regionRuleList = regionRuleService.list(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Map<String, RegionRule> regionRules = regionRuleList.stream().collect(Collectors.toMap(RegionRule::getSuffix, i -> i)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            List<DestRule> destRuleList = destRuleService.list(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Map<String, String> destRules = destRuleList.stream().collect(Collectors.toMap(DestRule::getDestination, DestRule::getSchedule)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            List<ReasonRule> reasonRuleList = reasonRuleService.list(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Map<String, String> reasonRules = reasonRuleList.stream().collect(Collectors.toMap(ReasonRule::getComment2, ReasonRule::getRemark)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 清洗数据,按规则匹配规定交付时间,计算超出时间,并转换延期原因 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            for (int i = 0; i < delayProducts.size(); i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                DelayProduct delayProduct = delayProducts.get(i); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                //通过后缀匹配国别规则 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                String model = delayProduct.getModel().trim(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                String suffix = model.substring(model.length() - 3); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                RegionRule regionRule = regionRules.get(suffix); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if(regionRule==null) continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                delayProduct.setRegion(regionRule.getRegion()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                // 按国别规则匹配到期规则 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                String schecule = regionRule.getSchedule(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if("EU".equals(regionRule.getRegion())){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    //EU地区需要根据目的地匹配到期规则 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    schecule = destRules.get(delayProduct.getFinalDest()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if(StringUtils.isBlank(schecule)) continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                // 根据要求周别和到期规则,计算要求完成日期 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                LocalDate dueDate = getDueDate(delayProduct.getBucket(), schecule); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if(dueDate==null) continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                delayProduct.setDueDate(dueDate); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                // 计算计划生产日期超出要求完成日期天数 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (delayProduct.getPst() != null && delayProduct.getDueDate() != null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    int days = delayProduct.getDueDate().until(delayProduct.getPst()).getDays(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//                    Long days = ChronoUnit.DAYS.between(delayProduct.getDueDate(), delayProduct.getPst()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    delayProduct.setOverdueDays(days); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                // 计算要求完成周别 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                String week = "W" + delayProduct.getDueDate().get(WeekFields.ISO.weekOfYear()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                delayProduct.setWeek(week); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                reasonRules.forEach((reason,remark)->{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    Pattern pattern = Pattern.compile("^"+reason+"$"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    Matcher matcher = pattern.matcher(delayProduct.getComment2()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    if (matcher.matches()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        String newRemark = matcher.replaceAll(remark); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        delayProduct.setRemark(newRemark); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            List<DelayProduct> overDueList = delayProducts.stream().filter(i -> i.getRemark()!=null && i.getOverdueDays()!=null && i.getOverdueDays() > 0).collect(Collectors.toList()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return overDueList; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } catch (Exception e) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            e.printStackTrace(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 获取表头对应的列索引 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @param headerRow 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    @NotNull 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private Map<String, Integer> parseHeadRow(Row headerRow) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Map<String, Integer> columnIndices = new LinkedHashMap<>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (Cell cell : headerRow) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            String headerValue = getCellValueAsString(cell); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            columnIndices.put(headerValue, cell.getColumnIndex()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return columnIndices; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 获取表头中的日期列 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @param columnIndices 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    @NotNull 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private Map<String, Integer> parseDateColumn(Map<String, Integer> columnIndices) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Map<String, Integer> dateColumnIndices = new LinkedHashMap<>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        columnIndices.forEach((key, value) -> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (key.matches("\\d{2}/\\d{2}") || key.matches("\\d{1,2}/\\d{1,2}")) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                dateColumnIndices.put(key, value); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return dateColumnIndices; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 读取明细行数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @param row 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @param columnIndices 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @param dateColumnIndices 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @param delayProducts 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private void parseDataRow(Row row, Map<String, Integer> columnIndices, Map<String, Integer> dateColumnIndices, List<DelayProduct> delayProducts) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        String Line = getCellValueAsString(row.getCell(columnIndices.get("Line"))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        String demandId = getCellValueAsString(row.getCell(columnIndices.get("Demand ID"))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        String tool = getCellValueAsString(row.getCell(columnIndices.get("Tool"))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        String model = getCellValueAsString(row.getCell(columnIndices.get("Model.Suffix"))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        String bucket = getCellValueAsString(row.getCell(columnIndices.get("Bucket"))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        String finalDest = getCellValueAsString(row.getCell(columnIndices.get("Final Dest."))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        String comment1 = getCellValueAsString(row.getCell(columnIndices.get("Comment1"))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        String comment2 = getCellValueAsString(row.getCell(columnIndices.get("Comment2"))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        dateColumnIndices.forEach((date, columnIndex) -> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Cell cell = row.getCell(columnIndex); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (cell != null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                String quantityStr = getCellValueAsString(cell); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (quantityStr != null && !quantityStr.isEmpty()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        Integer quantity = Integer.parseInt(quantityStr); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        if (quantity > 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            DelayProduct delayProduct =  new DelayProduct() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                    .setLine(Line) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                    .setDemandId(demandId) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                    .setTool(tool) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                    .setModel(model) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                    .setBucket(bucket) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                    .setFinalDest(finalDest) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                    .setComment1(comment1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                    .setComment2(comment2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                    .setPst(getDateFromMonthDayStr(date)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                    .setPo(quantity); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            delayProducts.add(delayProduct); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } catch (NumberFormatException e) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        log.error("无法解析数量: " + quantityStr, e); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 获取单元格的值,作为字符串返回 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @param cell 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private static String getCellValueAsString(Cell cell) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (cell == null) return null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        switch (cell.getCellType()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            case STRING: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return cell.getStringCellValue().trim(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            case NUMERIC: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (DateUtil.isCellDateFormatted(cell)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    return cell.getDateCellValue().toString(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    // Remove decimal if it's .0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    double num = cell.getNumericCellValue(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    if (num == (long) num) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        return String.valueOf((long) num); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        return String.valueOf(num); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            case BOOLEAN: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return String.valueOf(cell.getBooleanCellValue()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            case FORMULA: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                switch (cell.getCachedFormulaResultType()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    case STRING: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        return cell.getStringCellValue().trim(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    case NUMERIC: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        return String.valueOf(cell.getNumericCellValue()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    case BOOLEAN: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        return String.valueOf(cell.getBooleanCellValue()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    default: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        return cell.getCellFormula(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            default: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return ""; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 将日期列名字符串转换为日期 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @param monthDayStr 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private static LocalDate getDateFromMonthDayStr(String monthDayStr) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM/dd"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        MonthDay monthDay = MonthDay.parse(monthDayStr, formatter); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        LocalDate date = monthDay.atYear(LocalDate.now().getYear()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return date; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 通过周别和到期规则获取要求完成日期 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @param yearWeekStr 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @param schedule 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private static LocalDate getDueDate(String yearWeekStr,String schedule) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (StringUtils.isBlank(yearWeekStr)||yearWeekStr.length() != 6) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            throw new IllegalArgumentException("周别格式必须为YYYYWW,如:202523"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        int year = Integer.parseInt(yearWeekStr.substring(0, 4)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        int week = Integer.parseInt(yearWeekStr.substring(4, 6)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Map<String, DayOfWeek> DAYS = new HashMap<>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DAYS.put("MON", DayOfWeek.MONDAY); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DAYS.put("TUE", DayOfWeek.TUESDAY); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DAYS.put("WED", DayOfWeek.WEDNESDAY); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DAYS.put("THU", DayOfWeek.THURSDAY); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DAYS.put("FRI", DayOfWeek.FRIDAY); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DAYS.put("SAT", DayOfWeek.SATURDAY); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DAYS.put("SUN", DayOfWeek.SUNDAY); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        boolean isLast = schedule.startsWith("Last "); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        String dayStr = isLast ? schedule.substring(5).trim() : schedule; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (isLast) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            week = week - 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (week < 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                year = year - 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                week = LocalDate.of(year, 12, 31).get(IsoFields.WEEK_OF_WEEK_BASED_YEAR); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DayOfWeek dayOfWeek = DAYS.get(dayStr); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return LocalDate.now() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                .with(WeekFields.ISO.weekBasedYear(), year) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                .with(WeekFields.ISO.weekOfWeekBasedYear(), week) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                .with(WeekFields.ISO.dayOfWeek(), dayOfWeek.getValue()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    @Override 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public XSSFWorkbook report(String id, byte[] pie) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ProdPlan prodPlan = this.getById(id); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        int currentWeek = prodPlan.getPlanDate().get(WeekFields.ISO.weekOfYear()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        List<ReportDetailVo> detailVos = new ArrayList<>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // TODO 根据计划日期增加当前周期查询条件 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        List<DelayProduct> delayProductList = this.delayProductService.list(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        delayProductList.forEach(delayProduct -> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ReportDetailVo detailVo = new ReportDetailVo(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            BeanUtils.copyProperties(delayProduct, detailVo); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            detailVo.setPst(delayProduct.getPst().format(DateTimeFormatter.ofPattern("MM/dd"))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            detailVo.setDueDate(delayProduct.getDueDate().format(DateTimeFormatter.ofPattern("MM/dd"))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            LocalDate endDate = delayProduct.getPst(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            LocalDate startDate = delayProduct.getDueDate(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            while(endDate.isAfter(startDate)){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                int startWeek = startDate.get(WeekFields.ISO.weekOfYear()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if(startWeek==currentWeek-3){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    detailVo.setWeek1(detailVo.getPo()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } else if (startWeek==currentWeek-2) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    detailVo.setWeek2(detailVo.getPo()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } else if (startWeek==currentWeek-1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    detailVo.setWeek3(detailVo.getPo()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } else if (startWeek==currentWeek) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    detailVo.setWeek4(detailVo.getPo()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } else if (startWeek==currentWeek+1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    detailVo.setWeek5(detailVo.getPo()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } else if (startWeek==currentWeek+2) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    detailVo.setWeek6(detailVo.getPo()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                startDate = startDate.plusWeeks(1l); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            detailVos.add(detailVo); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        List<DefectiveProduct> defectiveProductList = this.defectiveProductService.list(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        defectiveProductList.forEach(defectiveProduct -> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ReportDetailVo detailVo = new ReportDetailVo(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            BeanUtils.copyProperties(defectiveProduct, detailVo); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            detailVo.setPo(defectiveProduct.getPo()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            detailVo.setDueDate(defectiveProduct.getDueDate().format(DateTimeFormatter.ofPattern("MM/dd"))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            int week = Integer.valueOf(defectiveProduct.getWeek().substring(1)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if(week==currentWeek-3){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                detailVo.setWeek1(detailVo.getPo()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } else if (week==currentWeek-2) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                detailVo.setWeek2(detailVo.getPo()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } else if (week==currentWeek-1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                detailVo.setWeek3(detailVo.getPo()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } else if (week==currentWeek) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                detailVo.setWeek4(detailVo.getPo()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } else if (week==currentWeek+1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                detailVo.setWeek5(detailVo.getPo()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } else if (week==currentWeek+2) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                detailVo.setWeek6(detailVo.getPo()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            detailVos.add(detailVo); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        List<DeliveredQuantity> deliveredQuantityList = this.deliveredQuantityService.list(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // TODO 按照计划日期,过滤影响到当前周的数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        XSSFWorkbook workbook=new XSSFWorkbook(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Sheet sheet = workbook.createSheet("生产数据统计"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 隐藏网格线 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sheet.setDisplayGridlines(false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sheet.setPrintGridlines(false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sheet.setDefaultRowHeightInPoints(20f); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            insertImageToSheetAtPosition(workbook,sheet,pie,"pie",0,0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } catch (Exception e) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            throw new RuntimeException(e); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 创建各种样式 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        CellStyle darkHeaderStyle = createDarkHeaderStyle(workbook); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        CellStyle subtotalStyle = createSubtotalStyle(workbook); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        CellStyle dataStyle = createDataStyle(workbook); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        CellStyle darkDataStyle = createDarkDataStyle(workbook); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        CellStyle percentStyle = createPercentStyle(workbook); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        CellStyle redPercentStyle = createRedPercentStyle(workbook); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        CellStyle totalStyle = createTotalStyle(workbook); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        CellStyle groupStyle = createGroupStyle(workbook); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        int currentRow = 30; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        int startColumn = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 第一部分:原因部门数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        currentRow = createFirstSection(currentWeek,sheet, currentRow,startColumn, darkHeaderStyle, subtotalStyle, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                dataStyle, percentStyle, totalStyle, groupStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        List<ReportDetailVo> sumDetailVos = new ArrayList<>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ReportDetailVo totalVo = getSummaryDetailVo(detailVos); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        totalVo.setComment1("合计"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Map<String, List<ReportDetailVo>> deptMap = detailVos.stream().collect(Collectors.groupingBy(ReportDetailVo::getComment1,  Collectors.toList())); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        deptMap.forEach((dept,deptList)->{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ReportDetailVo subTotalVo = getSummaryDetailVo(deptList); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            subTotalVo.setComment1(dept); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            subTotalVo.setLine("小计"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            subTotalVo.setPercent((double)subTotalVo.getPo()/totalVo.getPo()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Map<String, Map<String, List<ReportDetailVo>>> lineMap = deptList.stream().collect(Collectors.groupingBy(ReportDetailVo::getLine, Collectors.groupingBy(ReportDetailVo::getTool, Collectors.toList()))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            lineMap.forEach((line,toolMap)->{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                toolMap.forEach((tool,toolList)->{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    ReportDetailVo toolVo = getSummaryDetailVo(toolList); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    toolVo.setComment1(dept); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    toolVo.setLine(line); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    toolVo.setTool(tool); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    toolVo.setPercent((double)toolVo.getPo()/subTotalVo.getPo()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    toolVo.setRemark(toolList.get(0).getRemark()+" "+toolList.get(0).getModel()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    sumDetailVos.add(toolVo); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            sumDetailVos.add(subTotalVo); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sumDetailVos.add(totalVo); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        String currentDept = ""; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        String currentLine = ""; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        int deptStartRow = currentRow; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        int lineStartRow = currentRow; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        CellStyle cellStyle = dataStyle; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for(ReportDetailVo detailVo:sumDetailVos){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if("合计".equals(detailVo.getComment1())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                cellStyle = totalStyle; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }else if("小计".equals(detailVo.getLine())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                cellStyle = subtotalStyle; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                cellStyle = dataStyle; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Row dataRow = sheet.createRow(currentRow++); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            int currentColumn = startColumn; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            createCell(dataRow,currentColumn++,detailVo.getComment1(),cellStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            createCell(dataRow,currentColumn++,"",cellStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            createCell(dataRow,currentColumn++,"",cellStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (!currentDept.equals(detailVo.getComment1())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (!currentDept.isEmpty()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    sheet.addMergedRegion(new CellRangeAddress(deptStartRow, currentRow-2, startColumn, startColumn+2)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                currentDept = detailVo.getComment1(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                deptStartRow = currentRow-1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if("合计".equals(detailVo.getComment1())){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                sheet.addMergedRegion(new CellRangeAddress(currentRow-1, currentRow-1, startColumn, startColumn+2)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            createCell(dataRow,currentColumn++,detailVo.getLine(),cellStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (!currentLine.equals(detailVo.getLine())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (!currentLine.isEmpty() &¤tRow-2>lineStartRow) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    sheet.addMergedRegion(new CellRangeAddress(lineStartRow, currentRow-2, currentColumn-1, currentColumn-1)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                currentLine = detailVo.getLine(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                lineStartRow = currentRow-1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            createCell(dataRow,currentColumn++,detailVo.getTool(),cellStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            createCell(dataRow,currentColumn++,detailVo.getPo(),cellStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            createCell(dataRow,currentColumn++,detailVo.getWeek3()==null?0:detailVo.getWeek3(),cellStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            createCell(dataRow,currentColumn++,detailVo.getWeek4()==null?0:detailVo.getWeek4(),cellStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            createCell(dataRow,currentColumn++,detailVo.getWeek5()==null?0:detailVo.getWeek5(),cellStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            createCell(dataRow,currentColumn++,detailVo.getWeek6()==null?0:detailVo.getWeek6(),cellStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if("合计".equals(detailVo.getComment1())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                createCell(dataRow,currentColumn++,detailVo.getPercent()==null?0:detailVo.getPercent(),cellStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }else if("小计".equals(detailVo.getLine())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                createCell(dataRow,currentColumn++,detailVo.getPercent()==null?0:detailVo.getPercent(),redPercentStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                createCell(dataRow,currentColumn++,detailVo.getPercent()==null?0:detailVo.getPercent(),percentStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            createCell(dataRow,currentColumn++,detailVo.getRemark(),cellStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            sheet.addMergedRegion(new CellRangeAddress(currentRow-1, currentRow-1, currentColumn-1, currentColumn+2)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            createCell(dataRow,currentColumn++,"",cellStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            createCell(dataRow,currentColumn++,"",cellStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            createCell(dataRow,currentColumn++,"",cellStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Map<String, Integer> deliveredQuantityMap = deliveredQuantityList.stream().collect(Collectors.toMap(DeliveredQuantity::getWeek, DeliveredQuantity::getQuantity)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Row quantityRow = sheet.createRow(currentRow++); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        createCell(quantityRow,startColumn,"计划交付量",dataStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sheet.addMergedRegion(new CellRangeAddress(currentRow-1, currentRow-1, startColumn, startColumn+2)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        createCell(quantityRow,startColumn+1,"",dataStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        createCell(quantityRow,startColumn+2,"",dataStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        createCell(quantityRow,startColumn+3,"",dataStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        createCell(quantityRow,startColumn+4,"",dataStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        createCell(quantityRow,startColumn+5,"",dataStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        createCell(quantityRow,startColumn+6,deliveredQuantityMap.get("W"+(currentWeek-1))==null?0:deliveredQuantityMap.get("W"+(currentWeek-1)),dataStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        createCell(quantityRow,startColumn+7,deliveredQuantityMap.get("W"+(currentWeek))==null?0:deliveredQuantityMap.get("W"+(currentWeek)),dataStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        createCell(quantityRow,startColumn+8,deliveredQuantityMap.get("W"+(currentWeek+1))==null?0:deliveredQuantityMap.get("W"+(currentWeek+1)),dataStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        createCell(quantityRow,startColumn+9,deliveredQuantityMap.get("W"+(currentWeek+2))==null?0:deliveredQuantityMap.get("W"+(currentWeek+2)),dataStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        createCell(quantityRow,startColumn+10,"",dataStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        createCell(quantityRow,startColumn+11,"",dataStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        createCell(quantityRow,startColumn+12,"",dataStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        createCell(quantityRow,startColumn+13,"",dataStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        createCell(quantityRow,startColumn+14,"",dataStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Row lossrow = sheet.createRow(currentRow++); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        createCell(lossrow,startColumn,"OTD0 Loss率",dataStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sheet.addMergedRegion(new CellRangeAddress(currentRow-1, currentRow-1, startColumn, startColumn+2)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        createCell(lossrow,startColumn+3,"",dataStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sheet.addMergedRegion(new CellRangeAddress(currentRow-1, currentRow-1, startColumn+3, startColumn+5)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        createCell(lossrow,startColumn+10,"",dataStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sheet.addMergedRegion(new CellRangeAddress(currentRow-1, currentRow-1, startColumn+10, startColumn+14)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Row otdrow = sheet.createRow(currentRow++); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        createCell(otdrow,startColumn,"OTD0",dataStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sheet.addMergedRegion(new CellRangeAddress(currentRow-1, currentRow-1, startColumn, startColumn+2)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        createCell(otdrow,startColumn+10,"",dataStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sheet.addMergedRegion(new CellRangeAddress(currentRow-1, currentRow-1, startColumn+10, startColumn+14)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        createCell(otdrow,startColumn+3,"",dataStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sheet.addMergedRegion(new CellRangeAddress(currentRow-1, currentRow-1, startColumn+3, startColumn+5)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        createCell(lossrow,startColumn+1,"",dataStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        createCell(lossrow,startColumn+2,"",dataStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        createCell(lossrow,startColumn+3,"",dataStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        createCell(lossrow,startColumn+4,"",dataStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        createCell(lossrow,startColumn+5,"",dataStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        createCell(lossrow,startColumn+10,"",dataStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        createCell(lossrow,startColumn+11,"",dataStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        createCell(lossrow,startColumn+12,"",dataStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        createCell(lossrow,startColumn+13,"",dataStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        createCell(lossrow,startColumn+14,"",dataStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if(totalVo.getWeek3()!=null && deliveredQuantityMap.get("W" + (currentWeek - 1))!=null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            createCell(lossrow, startColumn+6, (double)totalVo.getWeek3()/ deliveredQuantityMap.get("W" + (currentWeek - 1)), percentStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            createCell(otdrow, startColumn+6, 1-(double)totalVo.getWeek3()/ deliveredQuantityMap.get("W" + (currentWeek - 1)), percentStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }else{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            createCell(lossrow, startColumn+6, "", percentStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            createCell(otdrow, startColumn+6, "", percentStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if(totalVo.getWeek4()!=null && deliveredQuantityMap.get("W" + (currentWeek))!=null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            createCell(lossrow, startColumn+7, (double)totalVo.getWeek4()/ deliveredQuantityMap.get("W" + (currentWeek)), percentStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            createCell(otdrow, startColumn+7, 1-(double)totalVo.getWeek4()/ deliveredQuantityMap.get("W" + (currentWeek)), percentStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if(totalVo.getWeek5()!=null && deliveredQuantityMap.get("W" + (currentWeek+1))!=null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            createCell(lossrow, startColumn+8, (double)totalVo.getWeek5()/ deliveredQuantityMap.get("W" + (currentWeek+1)), percentStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            createCell(otdrow, startColumn+8, 1-(double)totalVo.getWeek5()/ deliveredQuantityMap.get("W" + (currentWeek+1)), percentStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if(totalVo.getWeek6()!=null && deliveredQuantityMap.get("W" + (currentWeek+2))!=null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            createCell(lossrow, startColumn+9, (double)totalVo.getWeek6()/ deliveredQuantityMap.get("W" + (currentWeek+2)), percentStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            createCell(otdrow, startColumn+9, 1-(double)totalVo.getWeek6()/ deliveredQuantityMap.get("W" + (currentWeek+2)), percentStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 第二部分:产品需求数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        currentRow = createSecondSection(currentWeek,sheet, currentRow,startColumn, darkHeaderStyle, subtotalStyle, dataStyle, groupStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        cellStyle = darkDataStyle; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for(ReportDetailVo detailVo:detailVos){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Row dataRow = sheet.createRow(currentRow++); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            int currentColumn = startColumn; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            cellStyle = cellStyle.equals(dataStyle) ? darkDataStyle : dataStyle; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            createCell(dataRow,currentColumn++,detailVo.getRegion(),cellStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            createCell(dataRow,currentColumn++,detailVo.getModel(),cellStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            createCell(dataRow,currentColumn++,detailVo.getWeek(),cellStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            createCell(dataRow,currentColumn++,detailVo.getLine(),cellStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            createCell(dataRow,currentColumn++,detailVo.getTool(),cellStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            createCell(dataRow,currentColumn++,detailVo.getPo(),cellStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            createCell(dataRow,currentColumn++,detailVo.getWeek3()==null?0:detailVo.getWeek3(),cellStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            createCell(dataRow,currentColumn++,detailVo.getWeek4()==null?0:detailVo.getWeek4(),cellStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            createCell(dataRow,currentColumn++,detailVo.getWeek5()==null?0:detailVo.getWeek5(),cellStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            createCell(dataRow,currentColumn++,detailVo.getWeek6()==null?0:detailVo.getWeek6(),cellStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            createCell(dataRow,currentColumn++,detailVo.getPst(),cellStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            createCell(dataRow,currentColumn++,detailVo.getDueDate(),cellStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            createCell(dataRow,currentColumn++,detailVo.getOverdueDays()==null?0:detailVo.getOverdueDays(),cellStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            createCell(dataRow,currentColumn++,detailVo.getComment1(),cellStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            createCell(dataRow,currentColumn++,detailVo.getRemark(),cellStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//        // 自动调整列宽 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        autoSizeColumns(sheet, startColumn+15); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return workbook; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    @NotNull 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private ReportDetailVo getSummaryDetailVo(List<ReportDetailVo> detailVos) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Integer poQty = detailVos.stream().map(ReportDetailVo::getPo).filter(Objects::nonNull).reduce(0, Integer::sum); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Integer week1 = detailVos.stream().map(ReportDetailVo::getWeek1).filter(Objects::nonNull).reduce(0, Integer::sum); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Integer week2 = detailVos.stream().map(ReportDetailVo::getWeek2).filter(Objects::nonNull).reduce(0, Integer::sum); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Integer week3 = detailVos.stream().map(ReportDetailVo::getWeek3).filter(Objects::nonNull).reduce(0, Integer::sum); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Integer week4 = detailVos.stream().map(ReportDetailVo::getWeek4).filter(Objects::nonNull).reduce(0, Integer::sum); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Integer week5 = detailVos.stream().map(ReportDetailVo::getWeek5).filter(Objects::nonNull).reduce(0, Integer::sum); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Integer week6 = detailVos.stream().map(ReportDetailVo::getWeek6).filter(Objects::nonNull).reduce(0, Integer::sum); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ReportDetailVo totalVo = new ReportDetailVo(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        totalVo.setPo(poQty); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        totalVo.setWeek1(week1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        totalVo.setWeek2(week2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        totalVo.setWeek3(week3); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        totalVo.setWeek4(week4); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        totalVo.setWeek5(week5); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        totalVo.setWeek6(week6); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return totalVo; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private void insertImageToSheetAtPosition(Workbook workbook, Sheet sheet, byte[] imageBytes, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                              String fileName, int startRow, int startCol) throws Exception { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        int pictureIdx = workbook.addPicture(imageBytes, Workbook.PICTURE_TYPE_PNG); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Drawing drawing = sheet.createDrawingPatriarch(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ClientAnchor anchor = workbook.getCreationHelper().createClientAnchor(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 设置图片位置 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        anchor.setCol1(startCol); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        anchor.setRow1(startRow); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        anchor.setAnchorType(ClientAnchor.AnchorType.MOVE_AND_RESIZE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        XSSFPicture picture = (XSSFPicture)drawing.createPicture(anchor, pictureIdx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        picture.resize(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 创建第一部分数据表格 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private static int createFirstSection(int currentWeek,Sheet sheet, int startRow, int startColumn, CellStyle darkHeaderStyle, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                          CellStyle subtotalStyle, CellStyle dataStyle, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                          CellStyle percentStyle, CellStyle totalStyle, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                          CellStyle groupStyle) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        int currentRow = startRow; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 创建表头 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Row headerRow1 = sheet.createRow(currentRow++); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        String[] headers1 = {"原因部门", "", "", "Line", "Tool", "PO Qty", "周别累计影响数量", "", "", "", "%", "Remark"}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (int i = 0; i < headers1.length; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Cell cell = headerRow1.createCell(startColumn+i); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            cell.setCellValue(headers1[i]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            cell.setCellStyle(darkHeaderStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 第二行表头 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Row headerRow2 = sheet.createRow(currentRow++); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        String[] headers2 = {"", "", "", "", "", "", "W"+(currentWeek-1), "W"+currentWeek, "W"+(currentWeek+1), "W"+(currentWeek+2), "", ""}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (int i = 0; i < headers2.length; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Cell cell = headerRow2.createCell(startColumn+i); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            cell.setCellValue(headers2[i]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            cell.setCellStyle(darkHeaderStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 合并单元格 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sheet.addMergedRegion(new CellRangeAddress(startRow, startRow + 1, startColumn, startColumn+2)); // 原因部门 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sheet.addMergedRegion(new CellRangeAddress(startRow, startRow + 1, startColumn+3, startColumn+3)); // Line 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sheet.addMergedRegion(new CellRangeAddress(startRow, startRow + 1, startColumn+4, startColumn+4)); // Tool 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sheet.addMergedRegion(new CellRangeAddress(startRow, startRow + 1, startColumn+5, startColumn+5)); // PO Qty 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sheet.addMergedRegion(new CellRangeAddress(startRow, startRow, startColumn+6, startColumn+9)); // 周别累计影响数量 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sheet.addMergedRegion(new CellRangeAddress(startRow, startRow + 1, startColumn+10, startColumn+10)); // % 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sheet.addMergedRegion(new CellRangeAddress(startRow, startRow + 1, startColumn+11, startColumn+14)); // Remark 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return currentRow; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 创建第二部分数据表格 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private static int createSecondSection(int currentWeek,Sheet sheet, int startRow, int startColumn,CellStyle darkHeaderStyle, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                            CellStyle subtotalStyle, CellStyle dataStyle, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                            CellStyle groupStyle) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        int currentRow = startRow; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 创建第二个表格的表头 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Row headerRow = sheet.createRow(currentRow++); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        String[] headers = {"产品需求", "","", "Line", "Tool", "PO", "周别累计影响数量", "", "","", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                "当前日期", "要求完成日期", "超出天数", "原因部门", "Remark"}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (int i = 0; i < headers.length; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Cell cell = headerRow.createCell(startColumn+i); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            cell.setCellValue(headers[i]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            cell.setCellStyle(darkHeaderStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 第二行表头 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Row headerRow2 = sheet.createRow(currentRow++); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        String[] headers2 = { "Region","LG Model","Week", "", "", "", "W"+(currentWeek-1), "W"+currentWeek, "W"+(currentWeek+1), "W"+(currentWeek+2), "", "", "", "", ""}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (int i = 0; i < headers2.length; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Cell cell = headerRow2.createCell(startColumn+i); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            cell.setCellValue(headers2[i]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            cell.setCellStyle(darkHeaderStyle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 合并单元格 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sheet.addMergedRegion(new CellRangeAddress(startRow, startRow , startColumn, startColumn+2)); // 产品需求 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sheet.addMergedRegion(new CellRangeAddress(startRow, startRow + 1, startColumn+3, startColumn+3)); // Line 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sheet.addMergedRegion(new CellRangeAddress(startRow, startRow + 1, startColumn+4, startColumn+4)); // Tool 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sheet.addMergedRegion(new CellRangeAddress(startRow, startRow + 1, startColumn+5, startColumn+5)); // PO Qty 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sheet.addMergedRegion(new CellRangeAddress(startRow, startRow, startColumn+6, startColumn+9)); // 周别累计影响数量 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sheet.addMergedRegion(new CellRangeAddress(startRow, startRow + 1, startColumn+10, startColumn+10)); // 当前日期 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sheet.addMergedRegion(new CellRangeAddress(startRow, startRow + 1, startColumn+11, startColumn+11)); // 要求完成日期 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sheet.addMergedRegion(new CellRangeAddress(startRow, startRow + 1, startColumn+12, startColumn+12)); // 超出天数 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sheet.addMergedRegion(new CellRangeAddress(startRow, startRow + 1, startColumn+13, startColumn+13)); // 原因部门 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sheet.addMergedRegion(new CellRangeAddress(startRow, startRow + 1, startColumn+14, startColumn+14)); // Remark 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return currentRow; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 创建深色表头样式 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private static CellStyle createDarkHeaderStyle(Workbook workbook) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        CellStyle style = workbook.createCellStyle(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 设置深灰色背景 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        style.setFillForegroundColor(IndexedColors.GREY_80_PERCENT.getIndex()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        style.setFillPattern(FillPatternType.SOLID_FOREGROUND); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 设置白色字体 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Font font = workbook.createFont(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        font.setColor(IndexedColors.WHITE.getIndex()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        font.setBold(true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        font.setFontHeightInPoints((short) 12); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        style.setFont(font); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 设置边框 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        style.setBorderTop(BorderStyle.NONE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        style.setBorderBottom(BorderStyle.THIN); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        style.setBorderLeft(BorderStyle.NONE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        style.setBorderRight(BorderStyle.NONE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 设置对齐 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        style.setAlignment(HorizontalAlignment.CENTER); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        style.setVerticalAlignment(VerticalAlignment.CENTER); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return style; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 创建小计样式 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private static CellStyle createSubtotalStyle(Workbook workbook) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        CellStyle style = workbook.createCellStyle(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        style.setFillPattern(FillPatternType.SOLID_FOREGROUND); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Font font = workbook.createFont(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        font.setBold(true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        font.setFontHeightInPoints((short) 12); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        style.setFont(font); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        style.setBorderTop(BorderStyle.NONE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        style.setBorderBottom(BorderStyle.THIN); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        style.setBorderLeft(BorderStyle.NONE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        style.setBorderRight(BorderStyle.NONE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        style.setAlignment(HorizontalAlignment.CENTER); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        style.setVerticalAlignment(VerticalAlignment.CENTER); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return style; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 创建合计样式 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private static CellStyle createTotalStyle(Workbook workbook) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        CellStyle style = workbook.createCellStyle(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        style.setFillForegroundColor(IndexedColors.GREY_50_PERCENT.getIndex()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        style.setFillPattern(FillPatternType.SOLID_FOREGROUND); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Font font = workbook.createFont(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        font.setBold(true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        font.setFontHeightInPoints((short) 12); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        style.setFont(font); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        style.setBorderTop(BorderStyle.NONE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        style.setBorderBottom(BorderStyle.THIN); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        style.setBorderLeft(BorderStyle.NONE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        style.setBorderRight(BorderStyle.NONE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        style.setAlignment(HorizontalAlignment.CENTER); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        style.setVerticalAlignment(VerticalAlignment.CENTER); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return style; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 创建数据样式 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private static CellStyle createDataStyle(Workbook workbook) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        CellStyle style = workbook.createCellStyle(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        style.setBorderTop(BorderStyle.NONE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        style.setBorderBottom(BorderStyle.THIN); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        style.setBorderLeft(BorderStyle.NONE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        style.setBorderRight(BorderStyle.NONE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        style.setAlignment(HorizontalAlignment.CENTER); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        style.setVerticalAlignment(VerticalAlignment.CENTER); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Font font = workbook.createFont(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        font.setFontHeightInPoints((short) 11); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        style.setFont(font); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return style; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private static CellStyle createDarkDataStyle(Workbook workbook) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        CellStyle style = createDataStyle(workbook); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        style.setFillPattern(FillPatternType.SOLID_FOREGROUND); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return style; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 创建百分比样式 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private static CellStyle createPercentStyle(Workbook workbook) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        CellStyle style = createDataStyle(workbook); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DataFormat format = workbook.createDataFormat(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        style.setDataFormat(format.getFormat("0.0%")); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Font font = workbook.createFont(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        font.setBold(true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        font.setFontHeightInPoints((short) 12); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        style.setFont(font); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return style; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private static CellStyle createRedPercentStyle(Workbook workbook) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        CellStyle style = createSubtotalStyle(workbook); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DataFormat format = workbook.createDataFormat(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        style.setDataFormat(format.getFormat("0.0%")); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Font font = workbook.createFont(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        font.setColor(IndexedColors.RED.getIndex()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        font.setBold(true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        font.setFontHeightInPoints((short) 12); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        style.setFont(font); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return style; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 创建分组样式 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private static CellStyle createGroupStyle(Workbook workbook) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        CellStyle style = workbook.createCellStyle(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        style.setFillForegroundColor(IndexedColors.LIGHT_BLUE.getIndex()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        style.setFillPattern(FillPatternType.SOLID_FOREGROUND); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Font font = workbook.createFont(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        font.setBold(true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        font.setFontHeightInPoints((short) 12); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        style.setFont(font); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        style.setBorderTop(BorderStyle.NONE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        style.setBorderBottom(BorderStyle.THIN); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        style.setBorderLeft(BorderStyle.NONE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        style.setBorderRight(BorderStyle.NONE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        style.setAlignment(HorizontalAlignment.CENTER); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        style.setVerticalAlignment(VerticalAlignment.CENTER); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return style; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private static void createCell(Row row, int column, String value, CellStyle style) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Cell cell = row.createCell(column); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        cell.setCellValue(value); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        cell.setCellStyle(style); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private static void createCell(Row row, int column, int value, CellStyle style) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Cell cell = row.createCell(column); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if(value>0) cell.setCellValue(value); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        cell.setCellStyle(style); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private static void createCell(Row row, int column, double value, CellStyle style) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Cell cell = row.createCell(column); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if(value>0) cell.setCellValue(value); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        cell.setCellStyle(style); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 自动调整列宽 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private static void autoSizeColumns(Sheet sheet, int maxColumns) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (int i = 0; i < maxColumns; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            sheet.autoSizeColumn(i); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 设置最小和最大宽度 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            int currentWidth = sheet.getColumnWidth(i); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (currentWidth < 2000) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                sheet.setColumnWidth(i, 2000); // 最小宽度 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } else if (currentWidth > 8000) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                sheet.setColumnWidth(i, 8000); // 最大宽度 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    @Override 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public Boolean sendEmail(String id, byte[] pie) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ProdPlan prodPlan = this.getById(id); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        String date = prodPlan.getPlanDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        List<Contact> list = contactService.list(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        List<String> contactsTO = list.stream().filter(i -> "Y".equals(i.getIsActive()) && "TO".equals(i.getRecType())).map(Contact::getEmail).collect(Collectors.toList()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        List<String> contactsCC = list.stream().filter(i -> "Y".equals(i.getIsActive()) && "CC".equals(i.getRecType())).map(Contact::getEmail).collect(Collectors.toList()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Workbook workbook = this.report(id, pie); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        byte[] excelBytes = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            workbook.write(outputStream); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            excelBytes = outputStream.toByteArray(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            workbook.close(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Boolean success = EmailUtil.sendEmailWithExcelAttachment(contactsTO, contactsCC, "生产异常追踪表_" + date, "生产异常追踪表_" + date, excelBytes); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return success; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } catch (IOException e) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            throw new RuntimeException(e); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 |