wwh 1 неделя назад
Родитель
Сommit
3d54fc7c95

+ 71 - 2
baqing-admin/src/main/java/com/ruoyi/web/modules/industryservice/support/YakHerdInventoryExcelExporter.java

@@ -125,6 +125,8 @@ public class YakHerdInventoryExcelExporter
125
             updateTitleYearMonth(sheet, statYear, statMonth);
125
             updateTitleYearMonth(sheet, statYear, statMonth);
126
             updateFiller(sheet, fillerName);
126
             updateFiller(sheet, fillerName);
127
             int dataStartRow = headerRowIndex + 3;
127
             int dataStartRow = headerRowIndex + 3;
128
+            CellStyle[] dataRowStyles = captureDataRowStyles(sheet, dataStartRow);
129
+            Float dataRowHeight = captureRowHeight(sheet, dataStartRow);
128
             clearTemplateDataRegion(sheet, dataStartRow);
130
             clearTemplateDataRegion(sheet, dataStartRow);
129
             Totals totals = new Totals();
131
             Totals totals = new Totals();
130
             int rowIndex = dataStartRow;
132
             int rowIndex = dataStartRow;
@@ -142,6 +144,7 @@ public class YakHerdInventoryExcelExporter
142
                     setIntegerCell(row, COL_SEQ, seq++);
144
                     setIntegerCell(row, COL_SEQ, seq++);
143
                     setStringCell(row, YakHerdInventoryExcelParser.COL_TOWN, inv.getTownName());
145
                     setStringCell(row, YakHerdInventoryExcelParser.COL_TOWN, inv.getTownName());
144
                     fillDataRow(row, inv);
146
                     fillDataRow(row, inv);
147
+                    applyDataRowStyles(row, dataRowStyles, dataRowHeight);
145
                     if (inv.getVillageDeptId() != null || inv.getYakTotal() != null || inv.getBullTotal() != null
148
                     if (inv.getVillageDeptId() != null || inv.getYakTotal() != null || inv.getBullTotal() != null
146
                             || inv.getCowTotal() != null || inv.getGrandTotal() != null)
149
                             || inv.getCowTotal() != null || inv.getGrandTotal() != null)
147
                     {
150
                     {
@@ -153,8 +156,9 @@ public class YakHerdInventoryExcelExporter
153
             Row totalRow = getOrCreateRow(sheet, rowIndex);
156
             Row totalRow = getOrCreateRow(sheet, rowIndex);
154
             clearDataCells(totalRow);
157
             clearDataCells(totalRow);
155
             setStringCell(totalRow, COL_SEQ, "合计");
158
             setStringCell(totalRow, COL_SEQ, "合计");
156
-            mergeTotalLabelCells(sheet, rowIndex);
157
             totals.writeToRow(totalRow);
159
             totals.writeToRow(totalRow);
160
+            applyDataRowStyles(totalRow, dataRowStyles, dataRowHeight);
161
+            mergeTotalLabelCells(sheet, rowIndex);
158
             removeRowsAfter(sheet, rowIndex);
162
             removeRowsAfter(sheet, rowIndex);
159
             workbook.write(out);
163
             workbook.write(out);
160
             return out.toByteArray();
164
             return out.toByteArray();
@@ -273,7 +277,8 @@ public class YakHerdInventoryExcelExporter
273
                     continue;
277
                     continue;
274
                 }
278
                 }
275
                 String text = formatter.formatCellValue(cell);
279
                 String text = formatter.formatCellValue(cell);
276
-                if (StringUtils.isEmpty(text) || !text.contains("年") || text.contains("填表时间"))
280
+                // 跳过填表人/填表时间行,避免把占位年月改成统计年导致填表时间无法落到当月
281
+                if (StringUtils.isEmpty(text) || !text.contains("年") || isFillerMetaText(text))
277
                 {
282
                 {
278
                     continue;
283
                     continue;
279
                 }
284
                 }
@@ -292,11 +297,20 @@ public class YakHerdInventoryExcelExporter
292
                 {
297
                 {
293
                     updated = monthMatcher.replaceFirst("(" + statMonth + "月)");
298
                     updated = monthMatcher.replaceFirst("(" + statMonth + "月)");
294
                 }
299
                 }
300
+                else if (updated.contains("(X月)") || updated.contains("(X月)"))
301
+                {
302
+                    updated = updated.replace("(X月)", "(" + statMonth + "月)").replace("(X月)", "(" + statMonth + "月)");
303
+                }
295
                 cell.setCellValue(updated);
304
                 cell.setCellValue(updated);
296
             }
305
             }
297
         }
306
         }
298
     }
307
     }
299
 
308
 
309
+    private static boolean isFillerMetaText(String text)
310
+    {
311
+        return text.contains("填表人") || text.contains("填表时间");
312
+    }
313
+
300
     /**
314
     /**
301
      * 填写「填表人」与「填表时间」;填表时间固定为导出当日的当前年月。
315
      * 填写「填表人」与「填表时间」;填表时间固定为导出当日的当前年月。
302
      */
316
      */
@@ -413,6 +427,61 @@ public class YakHerdInventoryExcelExporter
413
         return row;
427
         return row;
414
     }
428
     }
415
 
429
 
430
+    private static CellStyle[] captureDataRowStyles(Sheet sheet, int styleSourceRow)
431
+    {
432
+        CellStyle[] styles = new CellStyle[YakHerdInventoryExcelParser.COL_LAST + 1];
433
+        Row src = sheet.getRow(styleSourceRow);
434
+        if (src == null)
435
+        {
436
+            return styles;
437
+        }
438
+        for (int col = 0; col < styles.length; col++)
439
+        {
440
+            Cell cell = src.getCell(col);
441
+            if (cell != null)
442
+            {
443
+                styles[col] = cell.getCellStyle();
444
+            }
445
+        }
446
+        return styles;
447
+    }
448
+
449
+    private static Float captureRowHeight(Sheet sheet, int styleSourceRow)
450
+    {
451
+        Row src = sheet.getRow(styleSourceRow);
452
+        if (src == null)
453
+        {
454
+            return null;
455
+        }
456
+        return src.getHeightInPoints();
457
+    }
458
+
459
+    private static void applyDataRowStyles(Row row, CellStyle[] styles, Float rowHeight)
460
+    {
461
+        if (row == null || styles == null)
462
+        {
463
+            return;
464
+        }
465
+        if (rowHeight != null && rowHeight > 0)
466
+        {
467
+            row.setHeightInPoints(rowHeight);
468
+        }
469
+        for (int col = 0; col < styles.length; col++)
470
+        {
471
+            CellStyle style = styles[col];
472
+            if (style == null)
473
+            {
474
+                continue;
475
+            }
476
+            Cell cell = row.getCell(col);
477
+            if (cell == null)
478
+            {
479
+                cell = row.createCell(col);
480
+            }
481
+            cell.setCellStyle(style);
482
+        }
483
+    }
484
+
416
     private static void fillDataRow(Row row, BizYakHerdInventory inv)
485
     private static void fillDataRow(Row row, BizYakHerdInventory inv)
417
     {
486
     {
418
         YakHerdInventoryValidation.recalculateDerived(inv);
487
         YakHerdInventoryValidation.recalculateDerived(inv);

+ 90 - 0
baqing-admin/src/test/java/com/ruoyi/web/modules/industryservice/support/YakHerdInventoryExcelExporterTest.java

@@ -139,4 +139,94 @@ class YakHerdInventoryExcelExporterTest
139
             }
139
             }
140
         }
140
         }
141
     }
141
     }
142
+
143
+    @Test
144
+    @DisplayName("导出标题使用所选年月,填表时间为当月")
145
+    void exportTitleUsesSelectedYearMonth() throws Exception
146
+    {
147
+        java.time.LocalDate today = java.time.LocalDate.now();
148
+        int exportMonth = today.getMonthValue() == 1 ? 12 : today.getMonthValue() - 1;
149
+        int exportYear = today.getMonthValue() == 1 ? today.getYear() - 1 : today.getYear();
150
+        if (!YakHerdInventoryYearSupport.isAllowedYear(exportYear))
151
+        {
152
+            exportYear = today.getYear();
153
+            exportMonth = Math.max(1, today.getMonthValue() - 1);
154
+        }
155
+
156
+        BizYakHerdInventory inv = new BizYakHerdInventory();
157
+        inv.setTownName("雅安镇");
158
+        inv.setVillageName("测试村");
159
+        inv.setVillageDeptId(201L);
160
+        inv.setVillageCount(1);
161
+        inv.setHerdsmanHouseholdCount(1);
162
+        inv.setBreedingBullCount(1);
163
+        inv.setBullCastratedCount(1);
164
+        inv.setCowYoungCount(1);
165
+        inv.setCowAdultCount(1);
166
+        inv.setMilkingCowCount(1);
167
+        inv.setFertileCowCount(1);
168
+        inv.setSheepTotal(1);
169
+        inv.setMilkingSheepCount(0);
170
+        inv.setInsuredYakCount(0);
171
+        YakHerdInventoryValidation.recalculateDerived(inv);
172
+
173
+        byte[] bytes = exporter.export(exportYear, exportMonth, Collections.singletonList(inv), "admin");
174
+        try (org.apache.poi.ss.usermodel.Workbook wb = org.apache.poi.ss.usermodel.WorkbookFactory.create(
175
+                new java.io.ByteArrayInputStream(bytes)))
176
+        {
177
+            org.apache.poi.ss.usermodel.DataFormatter fmt = new org.apache.poi.ss.usermodel.DataFormatter();
178
+            String title = fmt.formatCellValue(wb.getSheetAt(0).getRow(0).getCell(0));
179
+            String filler = fmt.formatCellValue(wb.getSheetAt(0).getRow(1).getCell(0));
180
+            assertTrue(title.contains(exportYear + "年"), title);
181
+            assertTrue(title.contains("(" + exportMonth + "月)"), title);
182
+            assertTrue(filler.contains("填表时间:" + today.getYear() + "年" + today.getMonthValue() + "月"), filler);
183
+        }
184
+    }
185
+
186
+    @Test
187
+    @DisplayName("导出合计行应保留边框(数据行多于模板样例时)")
188
+    void exportTotalRowKeepsBorders() throws Exception
189
+    {
190
+        java.util.List<BizYakHerdInventory> list = new java.util.ArrayList<>();
191
+        for (int i = 0; i < 3; i++)
192
+        {
193
+            BizYakHerdInventory inv = new BizYakHerdInventory();
194
+            inv.setTownName("雅安镇");
195
+            inv.setVillageName("村" + i);
196
+            inv.setVillageDeptId(200L + i);
197
+            inv.setVillageCount(10);
198
+            inv.setHerdsmanHouseholdCount(10);
199
+            inv.setBreedingBullCount(1);
200
+            inv.setBullCastratedCount(2);
201
+            inv.setCowYoungCount(3);
202
+            inv.setCowAdultCount(4);
203
+            inv.setMilkingCowCount(5);
204
+            inv.setFertileCowCount(6);
205
+            inv.setSheepTotal(7);
206
+            inv.setMilkingSheepCount(1);
207
+            inv.setInsuredYakCount(1);
208
+            YakHerdInventoryValidation.recalculateDerived(inv);
209
+            list.add(inv);
210
+        }
211
+
212
+        byte[] bytes = exporter.export(2026, 7, list, "admin");
213
+        try (org.apache.poi.ss.usermodel.Workbook wb = org.apache.poi.ss.usermodel.WorkbookFactory.create(
214
+                new java.io.ByteArrayInputStream(bytes)))
215
+        {
216
+            org.apache.poi.ss.usermodel.Sheet sheet = wb.getSheetAt(0);
217
+            int header = YakHerdInventoryExcelParser.detectHeaderRow(sheet);
218
+            int totalIdx = header + 3 + list.size();
219
+            org.apache.poi.ss.usermodel.Row totalRow = sheet.getRow(totalIdx);
220
+            assertNotNull(totalRow);
221
+            org.apache.poi.ss.usermodel.DataFormatter fmt = new org.apache.poi.ss.usermodel.DataFormatter();
222
+            assertEquals("合计", fmt.formatCellValue(totalRow.getCell(0)));
223
+            for (int col = 0; col <= YakHerdInventoryExcelParser.COL_LAST; col++)
224
+            {
225
+                org.apache.poi.ss.usermodel.Cell cell = totalRow.getCell(col);
226
+                assertNotNull(cell, "合计行列 " + col + " 应存在");
227
+                assertTrue(cell.getCellStyle().getBorderBottom() != org.apache.poi.ss.usermodel.BorderStyle.NONE,
228
+                        "合计行列 " + col + " 应有下边框");
229
+            }
230
+        }
231
+    }
142
 }
232
 }