人才培养方案

This commit is contained in:
2026-09-20 11:59:04 +08:00
parent e4f4720113
commit 9f0c0ac873
9 changed files with 280 additions and 48 deletions
@@ -450,11 +450,17 @@ public class ExcelParseUtil {
return true;
}
/**
* 人才培养方案(专业表)导入模板列头。下载模板与解析共用,按列名匹配,顺序可调整。
*/
public static final String[] TRAINING_PROGRAM_IMPORT_HEADERS = {
"专业代号", "专业名称", "专业代码", "专业版本", "培训类型", "培训层次",
"学年制", "学期数", "专业方向", "专业备注", "学员类别", "简称", "培训类型2"
};
/**
* 解析培养方案(专业表)导入 Excel 文件(支持 .xls / .xlsx)。
* <p>表头顺序:</p>
* 专业代号, 专业名称, 专业代码, 专业版本, 培训类型, 培训层次, 学年制, 学期数,
* 专业方向, 专业备注, 学员类别, 简称, 培训类型2
* <p>按 {@link #TRAINING_PROGRAM_IMPORT_HEADERS} 列名匹配;未识别表头则拒绝导入。</p>
*
* @return 专业实体列表
* @throws Exception 解析异常
@@ -464,29 +470,53 @@ public class ExcelParseUtil {
Workbook workbook = createWorkbook(inputStream, fileName);
try {
Sheet sheet = workbook.getSheetAt(0);
int lastRowNum = sheet.getLastRowNum();
for (int rowNum = 1; rowNum <= lastRowNum; rowNum++) {
int firstRowNum = sheet.getFirstRowNum();
Row headerRow = sheet.getRow(firstRowNum);
if (headerRow == null) {
throw new IllegalArgumentException("导入文件缺少表头行,请先下载「人才培养方案目录模板」填写");
}
Map<String, Integer> headerIndex = new LinkedHashMap<>();
for (int col = headerRow.getFirstCellNum(); col < headerRow.getLastCellNum(); col++) {
String title = normalizeHeader(getCellStringValue(headerRow.getCell(col)));
if (!title.isEmpty() && !headerIndex.containsKey(title)) {
headerIndex.put(title, col);
}
}
int matched = 0;
for (String header : TRAINING_PROGRAM_IMPORT_HEADERS) {
if (headerIndex.containsKey(header)) {
matched++;
}
}
if (matched == 0) {
throw new IllegalArgumentException(
"未识别到人才培养方案目录模板表头,请下载「人才培养方案目录模板」并按表头填写(须含学年制、学期数等列)");
}
if (!headerIndex.containsKey("学年制") && headerIndex.containsKey("学制")) {
headerIndex.put("学年制", headerIndex.get("学制"));
}
for (int rowNum = firstRowNum + 1; rowNum <= sheet.getLastRowNum(); rowNum++) {
Row row = sheet.getRow(rowNum);
if (row == null) {
continue;
}
ZYB entity = new ZYB();
entity.setZydh(getCellStringValue(row.getCell(0)));
entity.setZymc(getCellStringValue(row.getCell(1)));
entity.setZydm(getCellStringValue(row.getCell(2)));
entity.setZybb(getCellStringValue(row.getCell(3)));
entity.setPxlx(getCellStringValue(row.getCell(4)));
entity.setPxcc(getCellStringValue(row.getCell(5)));
entity.setXnz(getCellStringValue(row.getCell(6)));
entity.setXqs(parseIntCell(row.getCell(7)));
entity.setZyfx(getCellStringValue(row.getCell(8)));
entity.setZybz(getCellStringValue(row.getCell(9)));
entity.setXylb(getCellStringValue(row.getCell(10)));
entity.setJc(getCellStringValue(row.getCell(11)));
entity.setPxlx2(getCellStringValue(row.getCell(12)));
// 至少要有专业代号或名称才视为有效行
if (entity.getZydh() != null && !entity.getZydh().isEmpty()
|| entity.getZymc() != null && !entity.getZymc().isEmpty()) {
entity.setZydh(cellText(row, headerIndex, "专业代号"));
entity.setZymc(cellText(row, headerIndex, "专业名称"));
entity.setZydm(cellText(row, headerIndex, "专业代码"));
entity.setZybb(cellText(row, headerIndex, "专业版本"));
entity.setPxlx(cellText(row, headerIndex, "培训类型"));
entity.setPxcc(cellText(row, headerIndex, "培训层次"));
entity.setXnz(cellText(row, headerIndex, "学年制"));
entity.setXqs(cellInt(row, headerIndex, "学期数"));
entity.setZyfx(cellText(row, headerIndex, "专业方向"));
entity.setZybz(cellText(row, headerIndex, "专业备注"));
entity.setXylb(cellText(row, headerIndex, "学员类别"));
entity.setJc(cellText(row, headerIndex, "简称"));
entity.setPxlx2(cellText(row, headerIndex, "培训类型2"));
if (isNotBlank(entity.getZydh()) || isNotBlank(entity.getZymc())) {
result.add(entity);
}
}