| | |
| | | } |
| | | |
| | | /** 表1 项目行填充(模板行/插入行共用;cityText 与模板 B 列格式一致) */ |
| | | private void fillInvestPlanProjectRow(HSSFRow row, InvestmentProject p, InvestmentMonthly m, int seq, String cityText) { |
| | | private void fillInvestPlanProjectRow(HSSFRow row, InvestmentProject p, InvestmentMonthly m, int seq, String cityText, String displayName) { |
| | | hssfNum(row, 0, (double) seq); |
| | | hssfText(row, 1, cityText); |
| | | hssfText(row, 2, valueOf(p.getCounty())); |
| | | hssfText(row, 3, p.getProjectName()); |
| | | hssfText(row, 3, displayName != null && !displayName.trim().isEmpty() ? displayName.trim() : p.getProjectName()); |
| | | hssfText(row, 4, valueOf(p.getConstructNature())); |
| | | hssfNum(row, 5, parseYearNum(p.getStartTime())); |
| | | hssfNum(row, 6, parseYearNum(p.getEndTime())); |
| | |
| | | // 原位逐行替换:合计/块标题/市州小节/分组/项目行;未匹配的模板行清空样例数据(结构/合并/列宽不变) |
| | | int seq = 0; |
| | | int si = -1; |
| | | java.util.Set<Long> usedProjectIds = new HashSet<>(); |
| | | for (int r = 5; r <= lastRow; r++) { |
| | | HSSFRow row = sheet.getRow(r); |
| | | if (row == null) continue; |
| | |
| | | // 项目行:按 模板名称+市州+块类别 匹配 DB 项目,未匹配整行清空 |
| | | blankInvestRow(row, 25); |
| | | if (blockCategory == null) continue; // 老旧货车段无数据源 |
| | | InvestmentProject p = matchInvest(projects, d, b, blockCategory); |
| | | InvestmentProject p = matchInvest(projects, d, b, blockCategory, usedProjectIds); |
| | | if (p == null) continue; |
| | | usedProjectIds.add(p.getId()); |
| | | if (sec != null) sec.matched.add(p.getId()); |
| | | InvestmentMonthly m = mByProject.get(p.getId()); |
| | | fillInvestPlanProjectRow(row, p, m, ++seq, b); |
| | | fillInvestPlanProjectRow(row, p, m, ++seq, b, d); |
| | | } |
| | | // 动态插行:DB 项目数 > 模板预留行数时,在市州小节末尾补齐(自底向上插行,避免行号错位) |
| | | for (int i = sections.size() - 1; i >= 0; i--) { |
| | |
| | | HSSFRow row = sheet.getRow(first + j); |
| | | if (row == null) continue; |
| | | InvestmentProject p = extra.get(j); |
| | | fillInvestPlanProjectRow(row, p, mByProject.get(p.getId()), 0, p.getCity()); |
| | | fillInvestPlanProjectRow(row, p, mByProject.get(p.getId()), 0, p.getCity(), p.getProjectName()); |
| | | } |
| | | } |
| | | renumberInvestSeq(sheet, "investPlan"); |
| | |
| | | |
| | | /** 在候选项目池中按名称匹配 DB 项目(可选 市州/类别 过滤 + 县区前缀消歧),未命中返回 null */ |
| | | private InvestmentProject matchInvest(List<InvestmentProject> pool, String name, String cityFull, String category) { |
| | | return matchInvest(pool, name, cityFull, category, null); |
| | | } |
| | | |
| | | /** 带已占用排除的匹配:同一 DB 项目只允许填充一行(避免模板一期/二期同名行重复输出) */ |
| | | private InvestmentProject matchInvest(List<InvestmentProject> pool, String name, String cityFull, String category, Set<Long> excludeIds) { |
| | | if (name == null || name.trim().isEmpty()) return null; |
| | | String norm = normInvestName(name); |
| | | if (norm.isEmpty()) return null; |
| | |
| | | String county = extractInvestCounty(name); |
| | | List<InvestmentProject> cands = new java.util.ArrayList<>(); |
| | | for (InvestmentProject p : pool) { |
| | | if (excludeIds != null && excludeIds.contains(p.getId())) continue; |
| | | if (category != null && !category.equals(p.getCategory())) continue; |
| | | if (cityCanon != null && !cityCanon.equals(RegionUtil.normalizeCityName(p.getCity()))) continue; |
| | | cands.add(p); |