Compare commits
3 Commits
102a45ef3a
...
af5a0d352e
| Author | SHA1 | Date | |
|---|---|---|---|
| af5a0d352e | |||
| 5cc9219801 | |||
| 5f6a8ab089 |
@@ -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) {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import cn.afterturn.easypoi.excel.ExcelImportUtil;
|
|||||||
import cn.afterturn.easypoi.excel.annotation.Excel;
|
import cn.afterturn.easypoi.excel.annotation.Excel;
|
||||||
import cn.afterturn.easypoi.excel.entity.ExportParams;
|
import cn.afterturn.easypoi.excel.entity.ExportParams;
|
||||||
import cn.afterturn.easypoi.excel.entity.ImportParams;
|
import cn.afterturn.easypoi.excel.entity.ImportParams;
|
||||||
|
import com.gxwebsoft.credit.excel.ExcelHeaderAlias;
|
||||||
import org.apache.poi.ss.usermodel.Cell;
|
import org.apache.poi.ss.usermodel.Cell;
|
||||||
import org.apache.poi.ss.usermodel.CellType;
|
import org.apache.poi.ss.usermodel.CellType;
|
||||||
import org.apache.poi.ss.usermodel.DataFormatter;
|
import org.apache.poi.ss.usermodel.DataFormatter;
|
||||||
@@ -353,6 +354,20 @@ public class ExcelImportSupport {
|
|||||||
// key -> canonical annotation name
|
// key -> canonical annotation name
|
||||||
map.putIfAbsent(key, name);
|
map.putIfAbsent(key, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Allow import-time header aliases without changing the exported template header.
|
||||||
|
ExcelHeaderAlias alias = field.getAnnotation(ExcelHeaderAlias.class);
|
||||||
|
if (alias != null && alias.value() != null) {
|
||||||
|
for (String aliasName : alias.value()) {
|
||||||
|
if (aliasName == null || aliasName.trim().isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String aliasKey = normalizeHeaderKey(aliasName);
|
||||||
|
if (!aliasKey.isEmpty()) {
|
||||||
|
map.putIfAbsent(aliasKey, name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
current = current.getSuperclass();
|
current = current.getSuperclass();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package com.gxwebsoft.credit.excel;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Excel 导入表头别名。
|
||||||
|
*
|
||||||
|
* <p>EasyPOI 的 {@code @Excel(name=...)} 仅支持一个表头名;当上游模板存在多种表头写法时,
|
||||||
|
* 可用此注解声明别名,让 {@link com.gxwebsoft.credit.controller.ExcelImportSupport} 在导入前把别名规范化为 canonical 表头。</p>
|
||||||
|
*/
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(ElementType.FIELD)
|
||||||
|
public @interface ExcelHeaderAlias {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 允许匹配的表头别名列表(任意一个匹配即视为该列)。
|
||||||
|
*/
|
||||||
|
String[] value();
|
||||||
|
}
|
||||||
|
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
<!-- 关联查询sql -->
|
<!-- 关联查询sql -->
|
||||||
<sql id="selectSql">
|
<sql id="selectSql">
|
||||||
SELECT a.*, COALESCE(match_name, a.company_name) AS companyName, u.real_name AS realName
|
SELECT a.*, b.match_name AS companyName, u.real_name AS realName
|
||||||
FROM credit_branch a
|
FROM credit_branch a
|
||||||
LEFT JOIN credit_company b ON a.company_id = b.id
|
LEFT JOIN credit_company b ON a.company_id = b.id
|
||||||
LEFT JOIN gxwebsoft_core.sys_user u ON a.user_id = u.user_id
|
LEFT JOIN gxwebsoft_core.sys_user u ON a.user_id = u.user_id
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
<!-- 关联查询sql -->
|
<!-- 关联查询sql -->
|
||||||
<sql id="selectSql">
|
<sql id="selectSql">
|
||||||
SELECT a.*, COALESCE(match_name, a.company_name) AS companyName, u.real_name AS realName
|
SELECT a.*, b.match_name AS companyName, u.real_name AS realName
|
||||||
FROM credit_historical_legal_person a
|
FROM credit_historical_legal_person a
|
||||||
LEFT JOIN credit_company b ON a.company_id = b.id
|
LEFT JOIN credit_company b ON a.company_id = b.id
|
||||||
LEFT JOIN gxwebsoft_core.sys_user u ON a.user_id = u.user_id
|
LEFT JOIN gxwebsoft_core.sys_user u ON a.user_id = u.user_id
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
<!-- 关联查询sql -->
|
<!-- 关联查询sql -->
|
||||||
<sql id="selectSql">
|
<sql id="selectSql">
|
||||||
SELECT a.*, COALESCE(match_name, a.company_name) AS companyName, u.real_name AS realName
|
SELECT a.*, b.match_name AS companyName, u.real_name AS realName
|
||||||
FROM credit_nearby_company a
|
FROM credit_nearby_company a
|
||||||
LEFT JOIN credit_company b ON a.company_id = b.id
|
LEFT JOIN credit_company b ON a.company_id = b.id
|
||||||
LEFT JOIN gxwebsoft_core.sys_user u ON a.user_id = u.user_id
|
LEFT JOIN gxwebsoft_core.sys_user u ON a.user_id = u.user_id
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
<!-- 关联查询sql -->
|
<!-- 关联查询sql -->
|
||||||
<sql id="selectSql">
|
<sql id="selectSql">
|
||||||
SELECT a.*, COALESCE(match_name, a.company_name) AS companyName, u.real_name AS realName
|
SELECT a.*, b.match_name AS companyName, u.real_name AS realName
|
||||||
FROM credit_suspected_relationship a
|
FROM credit_suspected_relationship a
|
||||||
LEFT JOIN credit_company b ON a.company_id = b.id
|
LEFT JOIN credit_company b ON a.company_id = b.id
|
||||||
LEFT JOIN gxwebsoft_core.sys_user u ON a.user_id = u.user_id
|
LEFT JOIN gxwebsoft_core.sys_user u ON a.user_id = u.user_id
|
||||||
|
|||||||
@@ -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 lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
@@ -31,6 +32,7 @@ public class CreditExternalImportParam implements Serializable {
|
|||||||
private String shareholdingRatio;
|
private String shareholdingRatio;
|
||||||
|
|
||||||
@Excel(name = "认缴出资额")
|
@Excel(name = "认缴出资额")
|
||||||
|
@ExcelHeaderAlias({"认缴出资额/持股数"})
|
||||||
private String subscribedInvestmentAmount;
|
private String subscribedInvestmentAmount;
|
||||||
|
|
||||||
@Excel(name = "认缴出资日期")
|
@Excel(name = "认缴出资日期")
|
||||||
|
|||||||
@@ -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