feat(excel): 优化Excel导入功能支持动态工作表查找
- 添加findSheetIndex方法支持根据工作表名称查找索引 - 实现精确匹配、前缀匹配和包含匹配的查找逻辑 - 在各个控制器中使用动态工作表索引替换固定索引 - 优化CreditCompanyController中的必填字段验证逻辑 - 移除对code字段的必填验证要求 - 添加工作表名称标准化处理功能
This commit is contained in:
@@ -197,14 +197,14 @@ public class CreditCompanyController extends BaseController {
|
||||
}
|
||||
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
|
||||
// 验证必填字段
|
||||
if (item.getName() == null || item.getName().trim().isEmpty()) {
|
||||
if (item.getMatchName() == null || item.getMatchName().trim().isEmpty()) {
|
||||
errorMessages.add("第" + excelRowNumber + "行:项目名称不能为空");
|
||||
continue;
|
||||
}
|
||||
if (item.getCode() == null || item.getCode().trim().isEmpty()) {
|
||||
errorMessages.add("第" + excelRowNumber + "行:唯一标识不能为空");
|
||||
continue;
|
||||
}
|
||||
// if (item.getCode() == null || item.getCode().trim().isEmpty()) {
|
||||
// errorMessages.add("第" + excelRowNumber + "行:唯一标识不能为空");
|
||||
// continue;
|
||||
// }
|
||||
|
||||
boolean saved = creditCompanyService.save(item);
|
||||
if (!saved) {
|
||||
|
||||
@@ -141,8 +141,9 @@ public class CreditCompetitorController extends BaseController {
|
||||
int successCount = 0;
|
||||
|
||||
try {
|
||||
int sheetIndex = ExcelImportSupport.findSheetIndex(file, "竞争对手", 2);
|
||||
ExcelImportSupport.ImportResult<CreditCompetitorImportParam> importResult = ExcelImportSupport.read(
|
||||
file, CreditCompetitorImportParam.class, this::isEmptyImportRow,2);
|
||||
file, CreditCompetitorImportParam.class, this::isEmptyImportRow, sheetIndex);
|
||||
List<CreditCompetitorImportParam> list = importResult.getData();
|
||||
int usedTitleRows = importResult.getTitleRows();
|
||||
int usedHeadRows = importResult.getHeadRows();
|
||||
|
||||
@@ -141,8 +141,9 @@ public class CreditExternalController extends BaseController {
|
||||
int successCount = 0;
|
||||
|
||||
try {
|
||||
int sheetIndex = ExcelImportSupport.findSheetIndex(file, "对外投资", 0);
|
||||
ExcelImportSupport.ImportResult<CreditExternalImportParam> importResult = ExcelImportSupport.read(
|
||||
file, CreditExternalImportParam.class, this::isEmptyImportRow);
|
||||
file, CreditExternalImportParam.class, this::isEmptyImportRow, sheetIndex);
|
||||
List<CreditExternalImportParam> list = importResult.getData();
|
||||
int usedTitleRows = importResult.getTitleRows();
|
||||
int usedHeadRows = importResult.getHeadRows();
|
||||
|
||||
@@ -141,9 +141,9 @@ public class CreditRiskRelationController extends BaseController {
|
||||
int successCount = 0;
|
||||
|
||||
try {
|
||||
// 风险关系数据位于第二个选项卡,sheetIndex = 1
|
||||
int sheetIndex = ExcelImportSupport.findSheetIndex(file, "风险关系", 1);
|
||||
ExcelImportSupport.ImportResult<CreditRiskRelationImportParam> importResult = ExcelImportSupport.read(
|
||||
file, CreditRiskRelationImportParam.class, this::isEmptyImportRow, 1);
|
||||
file, CreditRiskRelationImportParam.class, this::isEmptyImportRow, sheetIndex);
|
||||
List<CreditRiskRelationImportParam> list = importResult.getData();
|
||||
int usedTitleRows = importResult.getTitleRows();
|
||||
int usedHeadRows = importResult.getHeadRows();
|
||||
|
||||
@@ -141,8 +141,9 @@ public class CreditSupplierController extends BaseController {
|
||||
int successCount = 0;
|
||||
|
||||
try {
|
||||
int sheetIndex = ExcelImportSupport.findSheetIndex(file, "供应商", 3);
|
||||
ExcelImportSupport.ImportResult<CreditSupplierImportParam> importResult = ExcelImportSupport.read(
|
||||
file, CreditSupplierImportParam.class, this::isEmptyImportRow,3);
|
||||
file, CreditSupplierImportParam.class, this::isEmptyImportRow, sheetIndex);
|
||||
List<CreditSupplierImportParam> list = importResult.getData();
|
||||
int usedTitleRows = importResult.getTitleRows();
|
||||
int usedHeadRows = importResult.getHeadRows();
|
||||
|
||||
@@ -20,6 +20,7 @@ import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
@@ -192,6 +193,50 @@ public class ExcelImportSupport {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 sheet 名称查找下标(优先精确匹配,其次前缀匹配/包含匹配)。
|
||||
*
|
||||
* @return 找不到返回 -1
|
||||
*/
|
||||
public static int findSheetIndex(MultipartFile file, String sheetName) throws Exception {
|
||||
if (file == null || sheetName == null || sheetName.trim().isEmpty()) {
|
||||
return -1;
|
||||
}
|
||||
String target = normalizeSheetName(sheetName);
|
||||
if (target.isEmpty()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
try (InputStream is = file.getInputStream(); Workbook workbook = WorkbookFactory.create(is)) {
|
||||
int sheetCount = workbook.getNumberOfSheets();
|
||||
for (int i = 0; i < sheetCount; i++) {
|
||||
String candidate = normalizeSheetName(workbook.getSheetName(i));
|
||||
if (Objects.equals(candidate, target)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < sheetCount; i++) {
|
||||
String candidate = normalizeSheetName(workbook.getSheetName(i));
|
||||
if (candidate.startsWith(target) || candidate.contains(target) || target.startsWith(candidate)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public static int findSheetIndex(MultipartFile file, String sheetName, int defaultIndex) throws Exception {
|
||||
int idx = findSheetIndex(file, sheetName);
|
||||
return idx >= 0 ? idx : defaultIndex;
|
||||
}
|
||||
|
||||
private static String normalizeSheetName(String sheetName) {
|
||||
if (sheetName == null) {
|
||||
return "";
|
||||
}
|
||||
return sheetName.replace(" ", "").replace(" ", "").trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取指定列(由表头名定位)的超链接,返回:单元格显示值 -> 超链接地址。
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user