refactor(credit): 优化Excel导入功能并改进表头匹配
- 移除过时的Excel导入相关依赖和方法 - 使用ExcelImportSupport替代原有的多配置尝试导入方式 - 添加表头文本标准化处理以解决空白字符导致的匹配问题 - 引入ExcelHeaderAlias注解支持表头别名匹配 - 简化导入逻辑并提高表头识别准确性
This commit is contained in:
@@ -1,9 +1,7 @@
|
|||||||
package com.gxwebsoft.credit.controller;
|
package com.gxwebsoft.credit.controller;
|
||||||
|
|
||||||
import cn.afterturn.easypoi.excel.ExcelExportUtil;
|
import cn.afterturn.easypoi.excel.ExcelExportUtil;
|
||||||
import cn.afterturn.easypoi.excel.ExcelImportUtil;
|
|
||||||
import cn.afterturn.easypoi.excel.entity.ExportParams;
|
import cn.afterturn.easypoi.excel.entity.ExportParams;
|
||||||
import cn.afterturn.easypoi.excel.entity.ImportParams;
|
|
||||||
import com.gxwebsoft.common.core.annotation.OperationLog;
|
import com.gxwebsoft.common.core.annotation.OperationLog;
|
||||||
import com.gxwebsoft.common.core.web.ApiResult;
|
import com.gxwebsoft.common.core.web.ApiResult;
|
||||||
import com.gxwebsoft.common.core.web.BaseController;
|
import com.gxwebsoft.common.core.web.BaseController;
|
||||||
@@ -205,19 +203,11 @@ public class CreditUserController extends BaseController {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
int sheetIndex = ExcelImportSupport.findSheetIndex(file, "招投标", 0);
|
int sheetIndex = ExcelImportSupport.findSheetIndex(file, "招投标", 0);
|
||||||
List<CreditUserImportParam> list = null;
|
ExcelImportSupport.ImportResult<CreditUserImportParam> importResult =
|
||||||
int usedTitleRows = 0;
|
ExcelImportSupport.read(file, CreditUserImportParam.class, this::isEmptyImportRow, sheetIndex);
|
||||||
int usedHeadRows = 0;
|
List<CreditUserImportParam> list = importResult.getData();
|
||||||
int[][] tryConfigs = new int[][]{{1, 1}, {0, 1}, {0, 2}, {0, 3}};
|
int usedTitleRows = importResult.getTitleRows();
|
||||||
|
int usedHeadRows = importResult.getHeadRows();
|
||||||
for (int[] config : tryConfigs) {
|
|
||||||
list = filterEmptyRows(tryImport(file, config[0], config[1], sheetIndex));
|
|
||||||
if (!CollectionUtils.isEmpty(list)) {
|
|
||||||
usedTitleRows = config[0];
|
|
||||||
usedHeadRows = config[1];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (CollectionUtils.isEmpty(list)) {
|
if (CollectionUtils.isEmpty(list)) {
|
||||||
return fail("未读取到数据,请确认模板表头与示例格式一致", null);
|
return fail("未读取到数据,请确认模板表头与示例格式一致", null);
|
||||||
}
|
}
|
||||||
@@ -354,15 +344,6 @@ public class CreditUserController extends BaseController {
|
|||||||
workbook.close();
|
workbook.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<CreditUserImportParam> tryImport(MultipartFile file, int titleRows, int headRows, int sheetIndex) throws Exception {
|
|
||||||
ImportParams importParams = new ImportParams();
|
|
||||||
importParams.setTitleRows(titleRows);
|
|
||||||
importParams.setHeadRows(headRows);
|
|
||||||
importParams.setStartSheetIndex(sheetIndex);
|
|
||||||
importParams.setSheetNum(1);
|
|
||||||
return ExcelImportUtil.importExcel(file.getInputStream(), CreditUserImportParam.class, importParams);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 读取“项目名称”列的超链接,按数据行顺序返回。
|
* 读取“项目名称”列的超链接,按数据行顺序返回。
|
||||||
*/
|
*/
|
||||||
@@ -379,7 +360,7 @@ public class CreditUserController extends BaseController {
|
|||||||
if (headerRow != null) {
|
if (headerRow != null) {
|
||||||
for (int c = headerRow.getFirstCellNum(); c < headerRow.getLastCellNum(); c++) {
|
for (int c = headerRow.getFirstCellNum(); c < headerRow.getLastCellNum(); c++) {
|
||||||
Cell cell = headerRow.getCell(c);
|
Cell cell = headerRow.getCell(c);
|
||||||
if (cell != null && "项目名称".equals(cell.getStringCellValue())) {
|
if (cell != null && "项目名称".equals(normalizeHeaderText(cell.getStringCellValue()))) {
|
||||||
nameColIndex = c;
|
nameColIndex = c;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -404,14 +385,20 @@ public class CreditUserController extends BaseController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 过滤掉完全空白的导入行,避免空行导致导入失败
|
* 用于表头匹配:仅做最常见的空白字符规整(避免表头中存在换行/空格导致无法定位列)。
|
||||||
*/
|
*/
|
||||||
private List<CreditUserImportParam> filterEmptyRows(List<CreditUserImportParam> rawList) {
|
private static String normalizeHeaderText(String text) {
|
||||||
if (CollectionUtils.isEmpty(rawList)) {
|
if (text == null) {
|
||||||
return rawList;
|
return "";
|
||||||
}
|
}
|
||||||
rawList.removeIf(this::isEmptyImportRow);
|
return text
|
||||||
return rawList;
|
.replace(" ", "")
|
||||||
|
.replace("\t", "")
|
||||||
|
.replace("\r", "")
|
||||||
|
.replace("\n", "")
|
||||||
|
.replace("\u00A0", "")
|
||||||
|
.replace(" ", "")
|
||||||
|
.trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isEmptyImportRow(CreditUserImportParam param) {
|
private boolean isEmptyImportRow(CreditUserImportParam param) {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.gxwebsoft.credit.param;
|
package com.gxwebsoft.credit.param;
|
||||||
|
|
||||||
import cn.afterturn.easypoi.excel.annotation.Excel;
|
import cn.afterturn.easypoi.excel.annotation.Excel;
|
||||||
|
import com.gxwebsoft.credit.excel.ExcelHeaderAlias;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
@@ -56,6 +57,7 @@ public class CreditUserImportParam implements Serializable {
|
|||||||
private String procurementName;
|
private String procurementName;
|
||||||
|
|
||||||
@Excel(name = "中标单位")
|
@Excel(name = "中标单位")
|
||||||
|
@ExcelHeaderAlias({"中标单位(最多展示50家)"})
|
||||||
private String winningName;
|
private String winningName;
|
||||||
|
|
||||||
@Excel(name = "中标金额")
|
@Excel(name = "中标金额")
|
||||||
|
|||||||
Reference in New Issue
Block a user