feat(excel): 支持导入发生时间字段并优化表头匹配

- 添加 occurrenceTime2 字段支持导入发生时间数据
- 实现表头单元格标准化处理,移除多余空格和特殊字符
- 解决因表头包含空白字符导致的列映射失败问题
- 支持对 "原告/上诉人" 等包含特殊分隔符的表头进行标准化
- 通过 WorkbookFactory 读取并重新写入 Excel 文件实现表头清理
This commit is contained in:
2026-01-31 02:17:52 +08:00
parent ede52b6309
commit 175708716c
3 changed files with 80 additions and 2 deletions

View File

@@ -410,11 +410,15 @@ public class CreditCourtAnnouncementController extends BaseController {
? param.getInvolvedAmount2() ? param.getInvolvedAmount2()
: param.getInvolvedAmount(); : param.getInvolvedAmount();
String occurrenceTime = !ImportHelper.isBlank(param.getOccurrenceTime2())
? param.getOccurrenceTime2()
: param.getOccurrenceTime();
entity.setDataType(dataType); entity.setDataType(dataType);
entity.setPlaintiffAppellant(plaintiffAppellant); entity.setPlaintiffAppellant(plaintiffAppellant);
entity.setAppellee(param.getAppellee()); entity.setAppellee(param.getAppellee());
entity.setOtherPartiesThirdParty(otherPartiesThirdParty); entity.setOtherPartiesThirdParty(otherPartiesThirdParty);
entity.setOccurrenceTime(param.getOccurrenceTime()); entity.setOccurrenceTime(occurrenceTime);
entity.setCaseNumber(param.getCaseNumber()); entity.setCaseNumber(param.getCaseNumber());
entity.setCauseOfAction(param.getCauseOfAction()); entity.setCauseOfAction(param.getCauseOfAction());
entity.setCourtName(param.getCourtName()); entity.setCourtName(param.getCourtName());

View File

@@ -15,6 +15,8 @@ import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream; import java.io.InputStream;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
@@ -267,7 +269,76 @@ public class ExcelImportSupport {
importParams.setHeadRows(headRows); importParams.setHeadRows(headRows);
importParams.setStartSheetIndex(sheetIndex); importParams.setStartSheetIndex(sheetIndex);
importParams.setSheetNum(1); importParams.setSheetNum(1);
return ExcelImportUtil.importExcel(file.getInputStream(), clazz, importParams);
// Easypoi matches headers by exact string. Some upstream files contain extra spaces/tabs/newlines in header cells
// (e.g. "原告 / 上诉人" or "原告/上诉人\t"), which makes specific columns silently not mapped.
// Normalize header cells first to make imports robust.
try (InputStream is = file.getInputStream(); Workbook workbook = WorkbookFactory.create(is)) {
if (workbook.getNumberOfSheets() > sheetIndex) {
Sheet sheet = workbook.getSheetAt(sheetIndex);
if (sheet != null) {
normalizeHeaderCells(sheet, titleRows, headRows);
}
}
try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
workbook.write(bos);
try (ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray())) {
return ExcelImportUtil.importExcel(bis, clazz, importParams);
}
}
}
}
private static void normalizeHeaderCells(Sheet sheet, int titleRows, int headRows) {
if (sheet == null || headRows <= 0) {
return;
}
int headerStart = Math.max(titleRows, 0);
int headerEnd = headerStart + headRows - 1;
for (int r = headerStart; r <= headerEnd; r++) {
Row row = sheet.getRow(r);
if (row == null) {
continue;
}
short last = row.getLastCellNum();
for (int c = 0; c < last; c++) {
Cell cell = row.getCell(c);
if (cell == null) {
continue;
}
String text = null;
CellType type = cell.getCellType();
if (type == CellType.STRING) {
text = cell.getStringCellValue();
} else if (type == CellType.FORMULA && cell.getCachedFormulaResultType() == CellType.STRING) {
text = cell.getStringCellValue();
} else {
continue;
}
String normalized = normalizeHeaderText(text);
if (normalized != null && !normalized.equals(text)) {
cell.setCellValue(normalized);
}
}
}
}
private static String normalizeHeaderText(String text) {
if (text == null) {
return null;
}
// Remove common invisible whitespace characters, including full-width space.
return text
.replace("", "/")
.replace(" ", "")
.replace("\t", "")
.replace("\r", "")
.replace("\n", "")
.replace("\u00A0", "")
.replace(" ", "")
.trim();
} }
private static <T> List<T> filterEmptyRows(List<T> rawList, Predicate<T> emptyRowPredicate) { private static <T> List<T> filterEmptyRows(List<T> rawList, Predicate<T> emptyRowPredicate) {

View File

@@ -54,6 +54,9 @@ public class CreditCourtAnnouncementImportParam implements Serializable {
@Excel(name = "刊登日期") @Excel(name = "刊登日期")
private String occurrenceTime; private String occurrenceTime;
@Excel(name = "发生时间")
private String occurrenceTime2;
@Excel(name = "备注") @Excel(name = "备注")
private String comments; private String comments;