当前位置:
解决生成的word合并单元格后预览pdf后错乱的问题
makesoft |
13人浏览
摘要:解决生成的word合并单元格后预览pdf后错乱的问题
解决问题的相关代码贴出来了
package com.doinner.csys.utils;
import fr.opensagres.xdocreport.document.IXDocReport;
import fr.opensagres.xdocreport.document.registry.XDocReportRegistry;
import fr.opensagres.xdocreport.template.IContext;
import fr.opensagres.xdocreport.template.TemplateEngineKind;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.FileInputStream;
import java.io.InputStream;
import java.math.BigInteger;
public class WordUtil {
private static final Logger log = LoggerFactory.getLogger(WordUtil.class);
/**
* 获取 Word 模板的两个操作对象 IXDocReport 和 IContext
*
* @param path 模板的绝对地址
* @return 模板数据对象
*/
public static ExportData creatExportData(String path) {
try {
IXDocReport report = createReport(path);
IContext context = report.createContext();
return new ExportData(report, context);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e.getMessage());
}
}
/**
* 加载模板的方法,主要是指定模板的路径和选择渲染数据的模板
*
* @param url 模板相对于类路径的地址
* @return word 文档操作类
*/
private static IXDocReport createReport(String url) {
try (InputStream in = new FileInputStream(url)) {
IXDocReport ix = XDocReportRegistry.getRegistry().loadReport(in, TemplateEngineKind.Freemarker);
return ix;
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e.getMessage());
}
}
public static String readTemplatePath(String courseType) {
String dir;
String path = ClassLoader.getSystemResource("template").getPath();
if ("1".equals(courseType)) {
dir = path + "/form_work_theory.docx";
} else if ("2".equals(courseType)) {
dir = path + "/form_work_practice.docx";
} else {
dir = path + "/form_work_theory&practice.docx";
}
return dir;
}
public static String readTemplatesPath() {
String path = System.getProperty("user.dir");
return path + "/template/form_work_list.docx";
}
/**
* 创建文档标题
*
* @param document XWPFDocument 对象
* @param title 标题文本
*/
public static void createTitle(XWPFDocument document, String title) {
XWPFParagraph titleParagraph = document.createParagraph();
titleParagraph.setAlignment(ParagraphAlignment.CENTER);
XWPFRun titleRun = titleParagraph.createRun();
titleRun.setText(title);
titleRun.setBold(true);
titleRun.setFontSize(18);
titleRun.setFontFamily("微软雅黑");
// 添加空行
document.createParagraph();
}
/**
* 创建标题(1-6 级)
*
* @param document XWPFDocument 对象
* @param text 标题文本
* @param level 标题级别(1-6)
*/
public static void createHeading(XWPFDocument document, String text, int level) {
XWPFParagraph paragraph = document.createParagraph();
paragraph.setAlignment(ParagraphAlignment.LEFT);
// 设置标题样式(使用字符串,避免依赖 ParagraphStyles 枚举)
String styleId = getHeadingStyleId(level);
if (styleId != null) {
paragraph.setStyle(styleId);
}
paragraph.getCTP().addNewPPr().addNewOutlineLvl().setVal(BigInteger.valueOf(level - 1));
paragraph.getCTP().addNewPPr().addNewInd().setFirstLine(BigInteger.valueOf(120 * (level - 1)));
XWPFRun run = paragraph.createRun();
run.setText(text);
run.setBold(true);
// 根据级别设置字体大小
int fontSize = getFontSizeByLevel(level);
run.setFontSize(fontSize);
run.setFontFamily("微软雅黑");
}
/**
* 根据标题级别获取字体大小
*
* @param level 标题级别
* @return 字体大小
*/
private static int getFontSizeByLevel(int level) {
switch (level) {
case 1:
return 16;
case 2:
return 14;
case 3:
return 12;
case 4:
return 10;
case 5:
return 9;
case 6:
return 8;
default:
return 7;
}
}
/**
* 获取标题样式 ID(使用字符串,不依赖枚举)
*
* @param level 标题级别
* @return 样式 ID 字符串
*/
private static String getHeadingStyleId(int level) {
switch (level) {
case 1:
return "Heading1";
case 2:
return "Heading2";
case 3:
return "Heading3";
case 4:
return "Heading4";
case 5:
return "Heading5";
case 6:
return "Heading6";
default:
return null;
}
}
/**
* 创建普通段落
*
* @param document XWPFDocument 对象
* @param text 段落文本
* @param style 样式(可为 null)
*/
public static void createParagraph(XWPFDocument document, String text, String style) {
XWPFParagraph paragraph = document.createParagraph();
paragraph.setAlignment(ParagraphAlignment.LEFT);
if (style != null) {
paragraph.setStyle(style);
}
paragraph.getCTP().addNewPPr().addNewInd().setFirstLine(BigInteger.valueOf(720));
XWPFRun run = paragraph.createRun();
run.setText(text);
run.setFontSize(12);
run.setFontFamily("宋体");
}
/**
* 合并表格单元格(水平合并)
*
* @param table XWPFTable 对象
* @param rowIndex 行号(从0开始)
* @param startCol 起始列号
* @param endCol 结束列号
*/
public static void mergeCellsHorizontal(XWPFTable table, int rowIndex, int startCol, int endCol) {
XWPFTableRow tableRow = table.getRow(rowIndex);
XWPFTableCell firstCell = tableRow.getCell(startCol);
if (ObjectUtils.isEmpty(firstCell)) {
return;
}
firstCell.getCTTc().addNewTcPr().addNewGridSpan().setVal(BigInteger.valueOf(endCol - startCol + 1));
for (int i = endCol; i > startCol; i--) {
table.getRow(rowIndex).removeCell(i);
}
}
/**
* 合并表格单元格(垂直合并)
*
* @param table XWPFTable 对象
* @param colIndex 列号(从0开始)
* @param startRow 起始行号
* @param endRow 结束行号
*/
public static void mergeCellsVertical(XWPFTable table, int colIndex, int startRow, int endRow) {
for (int r = startRow; r <= endRow; r++) {
XWPFTableCell cell = table.getRow(r).getCell(colIndex);
CTTcPr tcPr = cell.getCTTc().isSetTcPr() ? cell.getCTTc().getTcPr() : cell.getCTTc().addNewTcPr();
CTVMerge vMerge = tcPr.isSetVMerge() ? tcPr.getVMerge() : tcPr.addNewVMerge();
if (r == startRow) {
vMerge.setVal(STMerge.RESTART);
} else {
vMerge.setVal(STMerge.CONTINUE);
// 清空内容
while (cell.getParagraphs().size() > 0) {
cell.removeParagraph(0);
}
cell.addParagraph();
}
}
}
/**
* 设置表格单元格内容(单元格内文字居中、加粗、设置字体大小)
*
* @param cell XWPFTableCell 对象
* @param text 单元格文本
* @param isBold 是否加粗
* @param width 单元格宽度
*/
public static void setCellText(XWPFTableCell cell, String text, boolean isBold, String width) {
// 清空单元格默认段落
if (ObjectUtils.isEmpty(cell)) {
return;
}
while (cell.getParagraphs() != null && !cell.getParagraphs().isEmpty()) {
cell.removeParagraph(0);
}
XWPFParagraph paragraph = cell.addParagraph();
// 水平居中
paragraph.setAlignment(ParagraphAlignment.CENTER);
// 垂直居中
cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
// 设置单元格宽度
if (width != null && !width.isEmpty()) {
cell.setWidth(width);
}
// 设置文本
XWPFRun run = paragraph.createRun();
run.setFontFamily("宋体");
run.setText(text);
run.setFontSize(9);
if (isBold) {
run.setBold(true);
}
}
public static String addEndDot(String str, String dot){
if(ObjectUtils.isEmpty(str)){
return str;
}
String trim = str.trim();
char last = trim.charAt(trim.length() - 1);
String punc=".,、。,::?!“”‘’()【】{}《》——-?!\"'()[]";
if(punc.indexOf(last)==-1){
return str+dot;
}
return str;
}
public static void initTableGrid(XWPFTable table, int totalCols, int colWidthDxa) {
CTTbl ctTbl = table.getCTTbl();
// ========== 1. 表格属性 ==========
CTTblPr tblPr = ctTbl.getTblPr()!=null ? ctTbl.getTblPr() : ctTbl.addNewTblPr();
// 1.1 表格左缩进=0(解决整体缩进问题)
CTTblWidth tblInd = tblPr.isSetTblInd() ? tblPr.getTblInd() : tblPr.addNewTblInd();
tblInd.setType(STTblWidth.DXA);
tblInd.setW(BigInteger.ZERO);
// 1.2 表格总宽度(固定宽度,比百分比更可靠)
int totalWidth = totalCols * colWidthDxa;
CTTblWidth tblW = tblPr.isSetTblW() ? tblPr.getTblW() : tblPr.addNewTblW();
tblW.setType(STTblWidth.DXA);
tblW.setW(BigInteger.valueOf(totalWidth));
// 1.3 【核心】固定布局,禁止LibreOffice自动重排
CTTblLayoutType layout = tblPr.isSetTblLayout() ? tblPr.getTblLayout() : tblPr.addNewTblLayout();
layout.setType(STTblLayoutType.FIXED);
// 1.4 表格左对齐
CTJcTable jc = tblPr.getJc()!=null ? tblPr.getJc() : tblPr.addNewJc();
jc.setVal(STJcTable.LEFT);
// 1.5 表格边框(无边框容易网格错乱)
CTTblBorders borders = tblPr.isSetTblBorders() ? tblPr.getTblBorders() : tblPr.addNewTblBorders();
setTableBorders(borders);
// 1.6 单元格内边距(解决文字往里缩的问题)
CTTblCellMar cellMar = tblPr.isSetTblCellMar() ? tblPr.getTblCellMar() : tblPr.addNewTblCellMar();
setCellMargin(cellMar, 80, 80, 40, 40);
// ========== 2. 【最核心】表格列网格 tblGrid ==========
// LibreOffice靠这个识别真实列数,没有必错乱
if (ctTbl.getTblGrid() != null) {
ctTbl.setTblGrid(null);
}
CTTblGrid tblGrid = ctTbl.addNewTblGrid();
for (int i = 0; i < totalCols; i++) {
CTTblGridCol gridCol = tblGrid.addNewGridCol();
gridCol.setW(BigInteger.valueOf(colWidthDxa));
}
// ========== 3. 统一每行单元格 ==========
for (XWPFTableRow row : table.getRows()) {
// 3.1 确保每行单元格数量 = 总列数
while (row.getTableCells().size() < totalCols) {
row.addNewTableCell();
}
while (row.getTableCells().size() > totalCols) {
row.removeCell(totalCols);
}
// 3.2 每个单元格设置固定宽度
for (XWPFTableCell cell : row.getTableCells()) {
CTTcPr tcPr = cell.getCTTc().isSetTcPr() ? cell.getCTTc().getTcPr() : cell.getCTTc().addNewTcPr();
CTTblWidth cellW = tcPr.isSetTcW() ? tcPr.getTcW() : tcPr.addNewTcW();
cellW.setType(STTblWidth.DXA);
cellW.setW(BigInteger.valueOf(colWidthDxa));
// 3.3 单元格内段落缩进清零
for (XWPFParagraph p : cell.getParagraphs()) {
CTP ctp = p.getCTP();
CTPPr ppr = ctp.isSetPPr() ? ctp.getPPr() : ctp.addNewPPr();
CTInd ind = ppr.isSetInd() ? ppr.getInd() : ppr.addNewInd();
ind.setLeft(BigInteger.ZERO);
ind.setFirstLine(BigInteger.ZERO);
}
}
// 3.4 默认行高
// CTTrPr trPr = row.getCtRow().isSetTrPr() ? row.getCtRow().getTrPr() : row.getCtRow().addNewTrPr();
// CTHeight trHeight = trPr.isSetTrHeight() ? trPr.getTrHeight() : trPr.addNewTrHeight();
// trHeight.setVal(BigInteger.valueOf(400));
// trHeight.setHRule(STHeightRule.AT_LEAST);
}
}
private static void setTableBorders(CTTblBorders borders) {
// 上
CTBorder top = borders.isSetTop() ? borders.getTop() : borders.addNewTop();
top.setVal(STBorder.SINGLE);
top.setSz(BigInteger.valueOf(4));
top.setColor("000000");
// 下
CTBorder bottom = borders.isSetBottom() ? borders.getBottom() : borders.addNewBottom();
bottom.setVal(STBorder.SINGLE);
bottom.setSz(BigInteger.valueOf(4));
bottom.setColor("000000");
// 左
CTBorder left = borders.isSetLeft() ? borders.getLeft() : borders.addNewLeft();
left.setVal(STBorder.SINGLE);
left.setSz(BigInteger.valueOf(4));
left.setColor("000000");
// 右
CTBorder right = borders.isSetRight() ? borders.getRight() : borders.addNewRight();
right.setVal(STBorder.SINGLE);
right.setSz(BigInteger.valueOf(4));
right.setColor("000000");
// 内部横
CTBorder insideH = borders.isSetInsideH() ? borders.getInsideH() : borders.addNewInsideH();
insideH.setVal(STBorder.SINGLE);
insideH.setSz(BigInteger.valueOf(4));
insideH.setColor("000000");
// 内部竖
CTBorder insideV = borders.isSetInsideV() ? borders.getInsideV() : borders.addNewInsideV();
insideV.setVal(STBorder.SINGLE);
insideV.setSz(BigInteger.valueOf(4));
insideV.setColor("000000");
}
/**
* 设置单元格内边距
*/
private static void setCellMargin(CTTblCellMar cellMar, int left, int right, int top, int bottom) {
CTTblWidth leftMar = cellMar.isSetLeft() ? cellMar.getLeft() : cellMar.addNewLeft();
leftMar.setType(STTblWidth.DXA);
leftMar.setW(BigInteger.valueOf(left));
CTTblWidth rightMar = cellMar.isSetRight() ? cellMar.getRight() : cellMar.addNewRight();
rightMar.setType(STTblWidth.DXA);
rightMar.setW(BigInteger.valueOf(right));
CTTblWidth topMar = cellMar.isSetTop() ? cellMar.getTop() : cellMar.addNewTop();
topMar.setType(STTblWidth.DXA);
topMar.setW(BigInteger.valueOf(top));
CTTblWidth bottomMar = cellMar.isSetBottom() ? cellMar.getBottom() : cellMar.addNewBottom();
bottomMar.setType(STTblWidth.DXA);
bottomMar.setW(BigInteger.valueOf(bottom));
}
}
package com.doinner.csys.entity.csys;
import com.doinner.csys.constant.ConstantTrainingScheme;
import com.doinner.csys.domain.StandardGraduation;
import com.doinner.csys.entity.csys.model.*;
import com.doinner.csys.utils.TreeBuilderUtils;
import com.doinner.csys.utils.WordUtil;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.poi.xwpf.usermodel.*;
import java.io.*;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
/**
* 培养方案文档生成器 - 基于TrainingPlanModel生成培养方案Word文档
*
* 包含四个一级标题:
* 1. 培养目标
* 2. 毕业要求
* 3. 修业时间与学时学分
* 4. 教学训练体系与安排
*/
public class
TrainingPlanGenerator {
private String[] term={"第一学年秋季学期","第一学年春季学期","第二学年秋季学期","第二学年春季学期","第三学年秋季学期","第三学年春季学期","第四学年秋季学期","第四学年春季学期"};
/**
* 生成培养方案文档
*
* @param model 培养方案数据模型
* @throws IOException 生成异常
*/
public InputStream generate(TrainingPlanModel model) throws IOException {
XWPFDocument document = new XWPFDocument();
try {
// 1. 创建标题
WordUtil.createTitle(document, model.getTrainingPlanName());
// 2. 培养目标
generateTrainingTarget(model, document);
// 3. 毕业要求
generateStandardGraduations(model, document);
// 4. 修业时间与学时学分
generateDurationAndCredits(model, document);
// 5. 教学训练体系与安排(课程信息)
generateCourseArrangements(model, document);
// 输出文档
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
document.write(outputStream);
outputStream.close();
return new ByteArrayInputStream(outputStream.toByteArray());
} finally {
document.close();
}
}
public void generate(TrainingPlanModel model, String outputPath) throws IOException {
XWPFDocument document = new XWPFDocument();
try {
// 1. 创建标题
WordUtil.createTitle(document, model.getTrainingPlanName());
// 2. 培养目标
generateTrainingTarget(model, document);
// 3. 毕业要求
generateStandardGraduations(model, document);
// 4. 修业时间与学时学分
generateDurationAndCredits(model, document);
// 5. 教学训练体系与安排(课程信息)
generateCourseArrangements(model, document);
// 输出文档
FileOutputStream out = new FileOutputStream(outputPath);
document.write(out);
out.close();
} finally {
document.close();
}
}
/**
* 生成培养目标部分
*/
private void generateTrainingTarget(TrainingPlanModel model, XWPFDocument document) {
TrainingTargetModel target = model.getTrainingTarget();
if(ObjectUtils.isEmpty(target)){
return;
}
// 一级标题
WordUtil.createHeading(document, target.getFirstLevelTitle(), 1);
// 一级内容
WordUtil.createParagraph(document, target.getFirstLevelContent(), null);
// 二级标题1
WordUtil.createHeading(document, target.getSecondLevelTitle1(), 2);
WordUtil.createParagraph(document, target.getSecondLevelContent1(), null);
// 二级标题2
WordUtil.createHeading(document, target.getSecondLevelTitle2(), 2);
WordUtil.createParagraph(document, target.getSecondLevelContent2(), null);
}
/**
* 生成毕业要求部分
*/
private void generateStandardGraduations(TrainingPlanModel model, XWPFDocument document) {
// 一级标题
WordUtil.createHeading(document, "二、毕业要求", 1);
// 毕业要求内容说明
WordUtil.createParagraph(document, model.getStandardGraduationContent(), null);
List<StandardGraduation> standardGraduations = TreeBuilderUtils.buildRootTree(model.getStandardGraduations());
if(ObjectUtils.isEmpty(standardGraduations)){
return;
}
// 遍历一级标题并处理子结构
for (StandardGraduation standardGraduation : standardGraduations) {
processFirstLevel(standardGraduation, document);
}
}
/**
* 处理一级标题及其子结构
*/
private void processFirstLevel(StandardGraduation graduation, XWPFDocument document) {
WordUtil.createHeading(document, graduation.getName(), 2);
List<StandardGraduation> children = (List<StandardGraduation>) (graduation.getChildren());
if (ObjectUtils.isNotEmpty(children)) {
children.forEach(child -> processSecondLevel(child, document));
}
}
/**
* 处理二级标题及其子结构
*/
private void processSecondLevel(StandardGraduation child, XWPFDocument document) {
WordUtil.createHeading(document, child.getName(), 3);
List<StandardGraduation> childrenList = (List<StandardGraduation>) (child.getChildren());
if (ObjectUtils.isNotEmpty(childrenList)) {
String content = buildContentString(childrenList);
WordUtil.createParagraph(document, content, null);
}
}
/**
* 拼接子节点内容字符串
*/
private String buildContentString(List<StandardGraduation> nodes) {
StringBuilder stringBuilder = new StringBuilder();
for (StandardGraduation node : nodes) {
stringBuilder.append(WordUtil.addEndDot(node.getName(),","));
}
return WordUtil.addEndDot(stringBuilder.deleteCharAt(stringBuilder.length() - 1).toString(),"。");
}
/**
* 根据父项ID查找子项
*/
private List<StandardGraduation> findChildrenById(List<StandardGraduation> items, Long parentId) {
List<StandardGraduation> children = new ArrayList<>();
if (parentId == null) {
return children;
}
for (StandardGraduation item : items) {
if (parentId.equals(item.getParentId())) {
children.add(item);
}
}
return children;
}
/**
* 生成修业时间与学时学分部分
*/
private void generateDurationAndCredits(TrainingPlanModel model, XWPFDocument document) {
DurationAndCreditsModel dac = model.getDurationAndCredits();
// 一级标题
WordUtil.createHeading(document, "三、修业时间与学时学分", 1);
// (一)修业时间安排
WordUtil.createHeading(document, dac.getFirstLevelTitle1(), 2);
WordUtil.createParagraph(document, dac.getFirstLevelContent1(), null);
// (二)学时学分要求
WordUtil.createHeading(document, dac.getFirstLevelTitle2(), 2);
WordUtil.createParagraph(document, dac.getFirstLevelContent2(), null);
//学时学分要求表格
generateDurationAndCreditsTable(dac, document);
// (三)学分冲抵机制
WordUtil.createHeading(document, dac.getFirstLevelTitle3(), 2);
WordUtil.createParagraph(document, dac.getFirstLevelContent3(), null);
}
/**
* 生成修业时间与学时学分表格
*/
private XWPFTable generateDurationAndCreditsTable(DurationAndCreditsModel model, XWPFDocument document) {
// 这里可以根据需要生成具体的表格
// 计算总行数:表头6行 + 数据行 + 小计2行+合计1行
int totalRows = 8+model.getDataSize()+2;
int totalCols = 9; // 原始8列,删除第6列和第11列后实际13列
CellWidth cellWidth = new CellWidth(9);
XWPFTable table = document.createTable(totalRows, totalCols);
WordUtil.initTableGrid(table,totalCols,1000);
table.setWidthType(TableWidthType.PCT);
table.setWidth("100%");
// 创建表格
// ========== 表头第1行(行号0) ==========
// 列0:课程模块,跨行3行 3列
setCellText(table.getRow(0).getCell(0), "课程体系", true, cellWidth.getCellWidth(3));
WordUtil.mergeCellsVertical(table, 0, 0, 2);
WordUtil.mergeCellsHorizontal(table, 0, 0, 2);
WordUtil.mergeCellsHorizontal(table, 1, 0, 2);
WordUtil.mergeCellsHorizontal(table, 2, 0, 2);
// 列1:学时学分要求,跨行6列
setCellText(table.getRow(0).getCell(1), "学时学分要求", true, cellWidth.getCellWidth(6));
WordUtil.mergeCellsHorizontal(table, 0, 1, 6);
// ========== 表头第2行(行号1) ==========
// 列2:必修,跨行2行
setCellText(table.getRow(1).getCell(1), "必修", true, cellWidth.getCellWidth(2));
WordUtil.mergeCellsHorizontal(table, 1, 1, 2);
// 列3:选修,跨行2行
setCellText(table.getRow(1).getCell(2), "选修", true, cellWidth.getCellWidth(2));
WordUtil.mergeCellsHorizontal(table, 1, 2,3);
// 列3:小计,跨行2行
setCellText(table.getRow(1).getCell(3), "小计", true, cellWidth.getCellWidth(2));
WordUtil.mergeCellsHorizontal(table, 1, 3, 4);
// ========== 表头第2行(行号2) ==========
setCellText(table.getRow(2).getCell(1), "学时", true, cellWidth.getCellWidth(1));
setCellText(table.getRow(2).getCell(2), "学分", true, cellWidth.getCellWidth(1));
setCellText(table.getRow(2).getCell(3), "学时", true, cellWidth.getCellWidth(1));
setCellText(table.getRow(2).getCell(4), "学分", true, cellWidth.getCellWidth(1));
setCellText(table.getRow(2).getCell(5), "学时", true, cellWidth.getCellWidth(1));
setCellText(table.getRow(2).getCell(6), "学分", true, cellWidth.getCellWidth(1));
// deleteCol(table,0,2,totalCols);
// deleteCol(table,1,4,totalCols);
// deleteCol(table,2,7,totalCols);
// ========== 内容 ==========
int dataRow=3;
CountModel countModel = new CountModel();
setCellText(getCell(table, dataRow,0), "公共基础\n课程\n", true, cellWidth.getCellWidth(1));
WordUtil.mergeCellsVertical(table, 0, 3, 3+model.getGeneralCourses().size());
//排序
List<CreditsDetailModel> detailModelList = model.getGeneralCourses().parallelStream()
.sorted(Comparator.comparing(CreditsDetailModel::getModelNameSort)
.thenComparing(CreditsDetailModel::getChildrenNameModelSort))
.collect(Collectors.toList());
HashMap<String, int[]> mergeRowMap = new HashMap<>();
for (int i = 0; i < detailModelList.size(); i++) {
int firstCell=1;
CreditsDetailModel creditsDetailModel = model.getGeneralCourses().get(i);
if(ObjectUtils.isEmpty(creditsDetailModel.getChildrenNameModelName())||creditsDetailModel.getChildrenNameModelName().equals("-1")){
//只有一级
setCellText(getCell(table, dataRow,firstCell), creditsDetailModel.getModelName(), true, cellWidth.getCellWidth(2));
WordUtil.mergeCellsHorizontal(table, dataRow, 1,2);
// deleteCol(table,dataRow,8,totalCols);
}else{
//存在子集
setCellText(getCell(table, dataRow,firstCell), creditsDetailModel.getModelName(), true, cellWidth.getCellWidth(1));
firstCell++;
setCellText(getCell(table, dataRow,firstCell), creditsDetailModel.getChildrenNameModelName(), true, cellWidth.getCellWidth(1));
if(!mergeRowMap.containsKey(creditsDetailModel.getModelName())){
int[] rowArr=new int[2];
rowArr[0]=dataRow;
rowArr[1]=dataRow;
mergeRowMap.put(creditsDetailModel.getModelName(), rowArr);
}else{
int[] rowArr = mergeRowMap.get(creditsDetailModel.getModelName());
rowArr[1]=dataRow;
mergeRowMap.put(creditsDetailModel.getModelName(), rowArr);
}
}
firstCell++;
setCreditsAndHours(creditsDetailModel,firstCell,table,dataRow,countModel,cellWidth);
dataRow++;
}
//合并行
mergeRowMap.forEach((k,rowArr)->{
WordUtil.mergeCellsVertical(table,1,rowArr[0],rowArr[1]);
});
Map<String, CreditsDetailModel> disciplineMajorCourseMap = model.getDisciplineMajorCourseMap();
setCellText(getCell(table, dataRow,0), "学科专业\n课程\n", true, cellWidth.getCellWidth(1));
WordUtil.mergeCellsVertical(table, 0, dataRow, dataRow+1);
// deleteCol(table,dataRow,8,totalCols);
// ========== 内容 第六行:8 ==========
setCellText(getCell(table, dataRow,1), DictContent.DISCIPLINE_COURSE_NAME, true, cellWidth.getCellWidth(2));
WordUtil.mergeCellsHorizontal(table, dataRow, 1,2);
CreditsDetailModel disciplineDetail = disciplineMajorCourseMap.get(DictContent.DISCIPLINE_COURSE_NAME);
setCreditsAndHours(disciplineDetail, 2,table, dataRow,countModel, cellWidth);
// deleteCol(table,dataRow,8,totalCols);
dataRow++;
// ========== 内容 第七行:9 ==========
setCellText(getCell(table, dataRow,1), DictContent.MAJOR_COURSE_NAME, true, cellWidth.getCellWidth(2));
WordUtil.mergeCellsHorizontal(table, dataRow, 1,2);
CreditsDetailModel majorDetail = disciplineMajorCourseMap.get(DictContent.MAJOR_COURSE_NAME);
setCreditsAndHours(majorDetail,2, table, dataRow,countModel, cellWidth);
// deleteCol(table,dataRow,8,totalCols);
dataRow++;
//小计
setCellText(getCell(table, dataRow,0), "小计", true, cellWidth.getCellWidth(3));
WordUtil.mergeCellsHorizontal(table, dataRow, 0, 2);
setCellText(getCell(table, dataRow,1), countModel.getRequireHours()+"", true, cellWidth.getCellWidth(1));
setCellText(getCell(table, dataRow,2), countModel.getRequireCredit()+"", true, cellWidth.getCellWidth(1));
setCellText(getCell(table, dataRow,3), countModel.getOptionalHours()+"", true, cellWidth.getCellWidth(1));
setCellText(getCell(table, dataRow,4), countModel.getOptionalCredit()+"", true, cellWidth.getCellWidth(1));
setCellText(getCell(table, dataRow,5), countModel.getTotalHours()+"", true, cellWidth.getCellWidth(1));
setCellText(getCell(table, dataRow,6), countModel.getTotalCredit()+"", true, cellWidth.getCellWidth(1));
// deleteCol(table,dataRow,7,totalCols);
dataRow++;
//=========表2================
setCellText(getCell(table, dataRow,0), "实践训练体系", true, cellWidth.getCellWidth(3));
WordUtil.mergeCellsVertical(table, 0, dataRow, dataRow+2);
WordUtil.mergeCellsHorizontal(table, dataRow, 0, 2);
WordUtil.mergeCellsHorizontal(table, dataRow+1, 0, 2);
WordUtil.mergeCellsHorizontal(table, dataRow+2, 0, 2);
// 列1:学时学分要求,跨行6列
setCellText(getCell(table, dataRow,1), "学时学分要求", true, cellWidth.getCellWidth(6));
WordUtil.mergeCellsHorizontal(table, dataRow, 1, 6);
// deleteCol(table,dataRow,2,totalCols);
dataRow++;
// ========== 表头第2行(行号1) ==========
// 列2:必修,跨行2行
setCellText(getCell(table, dataRow,1), "必修", true, cellWidth.getCellWidth(2));
WordUtil.mergeCellsHorizontal(table, dataRow, 1, 2);
// 列3:选修,跨行2行
setCellText(getCell(table, dataRow,2), "选修", true, cellWidth.getCellWidth(2));
WordUtil.mergeCellsHorizontal(table, dataRow, 2, 3);
// 列3:小计,跨行2行
setCellText(getCell(table, dataRow,3), "小计", true, cellWidth.getCellWidth(2));
WordUtil.mergeCellsHorizontal(table, dataRow, 3, 4);
// deleteCol(table,dataRow,4,totalCols);
dataRow++;
setCellText(getCell(table, dataRow,1), "学时", true, cellWidth.getCellWidth(1));
setCellText(getCell(table, dataRow,2), "学分", true, cellWidth.getCellWidth(1));
setCellText(getCell(table, dataRow,3), "学时", true, cellWidth.getCellWidth(1));
setCellText(getCell(table, dataRow,4), "学分", true, cellWidth.getCellWidth(1));
setCellText(getCell(table, dataRow,5), "学时", true, cellWidth.getCellWidth(1));
setCellText(getCell(table, dataRow,6), "学分", true, cellWidth.getCellWidth(1));
// deleteCol(table,dataRow,7,totalCols);
dataRow++;
//小计
setCellText(getCell(table, dataRow,0), "小计", true, cellWidth.getCellWidth(3));
WordUtil.mergeCellsHorizontal(table, dataRow, 0, 2);
CreditsDetailModel trainingProjectCourse = model.getTrainingProjectCourses();
//实践训练一共就一行 直接用countModel去加 算出合计
setCreditsAndHours(trainingProjectCourse, 1,table, dataRow,countModel, cellWidth);
// deleteCol(table,dataRow,7,totalCols);
dataRow++;
//合计
setCellText(getCell(table, dataRow,0), "合计", true, cellWidth.getCellWidth(3));
WordUtil.mergeCellsHorizontal(table, dataRow, 0, 2); setCellText(getCell(table, dataRow,1), countModel.getRequireHours()+"", true, "25%");
setCellText(getCell(table, dataRow,1), countModel.getRequireHours()+"", true, cellWidth.getCellWidth(1));
setCellText(getCell(table, dataRow,2), countModel.getRequireCredit()+"", true, cellWidth.getCellWidth(1));
setCellText(getCell(table, dataRow,3), countModel.getOptionalHours()+"", true, cellWidth.getCellWidth(1));
setCellText(getCell(table, dataRow,4), countModel.getOptionalCredit()+"", true, cellWidth.getCellWidth(1));
setCellText(getCell(table, dataRow,5), countModel.getTotalHours()+"", true, cellWidth.getCellWidth(1));
setCellText(getCell(table, dataRow,6), countModel.getTotalCredit()+"", true, cellWidth.getCellWidth(1));
// deleteCol(table,dataRow,7,totalCols);
return table;
}
private static XWPFTableCell getCell(XWPFTable table, int dataRow,int cell) {
if(ObjectUtils.isEmpty(table.getRow(dataRow))) {
table.createRow().createCell();
}
return table.getRow(dataRow).getCell(cell);
}
private void setCreditsAndHours(CreditsDetailModel creditsDetailModel, int firstCell, XWPFTable table, int dataRow , CountModel countModel, CellWidth cellWidth) {
if(ObjectUtils.isEmpty(creditsDetailModel)){
return;
}
setCellText(getCell(table, dataRow,firstCell), creditsDetailModel.getRequiredHours() + "", true, cellWidth.getCellWidth(1));
countModel.setRequireHours(countModel.getRequireHours()+creditsDetailModel.getRequiredHours());
setCellText(getCell(table, dataRow,firstCell+1), creditsDetailModel.getRequiredCredits() + "", true, cellWidth.getCellWidth(1));
countModel.setRequireCredit(countModel.getRequireCredit()+creditsDetailModel.getRequiredCredits());
setCellText(getCell(table, dataRow,firstCell+2), creditsDetailModel.getOptionalHours() + "", true, cellWidth.getCellWidth(1));
countModel.setOptionalHours(countModel.getOptionalHours()+creditsDetailModel.getOptionalHours());
setCellText(getCell(table, dataRow,firstCell+3), creditsDetailModel.getOptionalCredits() + "", true, cellWidth.getCellWidth(1));
countModel.setOptionalCredit(countModel.getOptionalCredit()+creditsDetailModel.getOptionalCredits());
setCellText(getCell(table, dataRow,firstCell+4), creditsDetailModel.getTotalHours() + "", true, cellWidth.getCellWidth(1));
countModel.setTotalHours(countModel.getTotalHours()+creditsDetailModel.getTotalHours());
setCellText(getCell(table, dataRow,firstCell+5), creditsDetailModel.getTotalCredits() + "", true, cellWidth.getCellWidth(1));
countModel.setTotalCredit(countModel.getTotalCredit()+creditsDetailModel.getTotalCredits());
}
/**
* 生成教学训练体系与安排(课程信息表格)
*/
private void generateCourseArrangements(TrainingPlanModel model, XWPFDocument document) {
// 一级标题
WordUtil.createHeading(document, "四、教学训练体系与安排", 1);
WordUtil.createParagraph(document,"通识课程任选课程安排表见附录1、专业任选课程安排表见附录2、其他课程和实践训练安排如下:",null);
//二级标题
WordUtil.createHeading(document, "(一)课程安排", 2);
// 公共基础课程教学安排
if (model.getGeneralCourses() != null && !model.getGeneralCourses().isEmpty()) {
XWPFTable table = generateCourseTable(document, "1.公共基础课程教学安排", model.getGeneralCourses());
WordUtil.createParagraph(document, "", null); // 空行
}
// 添加备注
XWPFParagraph remarkParagraph = document.createParagraph();
XWPFRun remarkRun = remarkParagraph.createRun();
remarkRun.setText("备注:1.B代表必修课程、X代表限选课程、R代表任选课程;S代表考试,C代表考查(下同)。\n 2.《大学英语》免修规则:请军政基础教育学院补充。");
remarkRun.setFontSize(10);
// 学科基础课程
if (model.getDisciplineCourses() != null && !model.getDisciplineCourses().isEmpty()) {
XWPFTable table = disciplineCoursesTable(document, "2.学科基础课程教学安排", model.getDisciplineCourses());
WordUtil.createParagraph(document, "", null); // 空行
}
// 专业课程
if (model.getMajorCourses() != null && !model.getMajorCourses().isEmpty()) {
XWPFTable table = majorCoursesTable(document, "3.专业课程教学安排", model.getMajorCourses());
WordUtil.createParagraph(document, "", null); // 空行
}
//二级标题
WordUtil.createHeading(document, "(二)实践训练安排", 2);
//实践项目训练课程
if (model.getTrainingSubjectCourses() != null && !model.getTrainingSubjectCourses().isEmpty()) {
XWPFTable table = practicalProjectCourseTable(document, "1.实践训练课目与安排", model.getTrainingSubjectCourses());
WordUtil.createParagraph(document, "", null); // 空行
}
//2.实践项目与安排
if (model.getPracticalProjectCourse() != null && !model.getPracticalProjectCourse().isEmpty()) {
XWPFTable table = trainingSubjectCoursesTable(document, "2.实践项目与安排", model.getPracticalProjectCourse());
WordUtil.createParagraph(document, "", null); // 空行
}
}
/**
* 生成课程教学安排表格 - 严格按照TableCreateGenerator中的表头结构
*
* 表格结构:
* - 列数:16列(删除第6列和第11列后实际为13列)
* - 行数:表头3行 + 模块行 + 小计1行
*
* 表头结构(3行):
* 行0:课程模块 | 课程名称 | 修读要求 | 考核方式 | 学时安排(跨3列) | 学期安排(跨8列)
* 行1:[ Module行跨3行 ] | | | | 小计 | 讲授 | 实践 | 第一学年(跨2列) | 第二学年(跨2列) | 第三学年(跨2列) | 第四学年(跨2列)
* 行2:[ Module行跨3行 ] | | | | | | | 秋 | 春 | 秋 | 春 | 秋 | 春 | 秋 | 春
*
* 删除第6列(空列)和第11列(空列),所以实际使用13列
*/
private XWPFTable generateCourseTable(XWPFDocument document, String title, List<TrainingSchemeCourseModel> courses) {
// 创建表格标题
WordUtil.createHeading(document, title, 3);
// 计算总行数:表头3行 + 数据行 + 小计1行
int dataRows = courses.size();
int totalRows = 3 + dataRows + 1;
int totalCols = 16; // 原始16列,删除第6列和第11列后实际13列
CellWidth cellWidth = new CellWidth(17);
XWPFTable table = document.createTable(totalRows, totalCols);
WordUtil.initTableGrid(table,totalCols,1000);
table.setWidthType(TableWidthType.PCT);
table.setWidth("100%");
// 生成表头(3行)
generateCourseHeader(table,cellWidth);
int dataRowStart = 3;
Map<String, Map<String, List<TrainingSchemeCourseModel>>> couseMap = TrainingSchemeCourseModel.groupCourses(courses);
// 处理每一门课程,确定其所属模块
AtomicInteger dataRow = new AtomicInteger(dataRowStart);
CountModel countModel = new CountModel();
couseMap.forEach((modelName,courseFourLevelMap) -> {
int moduleRowStart = dataRow.get();
AtomicInteger moduleRowEnd = new AtomicInteger(moduleRowStart);
courseFourLevelMap.forEach((fourLevelName,courseModels) -> {
int fourMoudleStart = dataRow.get();
int fourMoudleEnd = fourMoudleStart + courseModels.size();
int initCell=1;
XWPFTableRow row = table.getRow(fourMoudleStart);
//判断科学文化下的基础科学等子模块
if(DictContent.FOUR_LEVEL_NAME_NULL .equals(fourLevelName)){
for (int i = fourMoudleStart; i < fourMoudleEnd; i++) {
WordUtil.mergeCellsHorizontal(table, i, 0, 1);
// deleteCol(table,i,15,15);
}
}else{
initCell=2;
XWPFTableCell cell1 = row.getCell(1);
WordUtil.setCellText(cell1, fourLevelName, false, cellWidth.getCellWidth(1));
WordUtil.mergeCellsVertical(table, 1, fourMoudleStart, fourMoudleStart+courseModels.size() - 1);
}
for (int i = 0; i < courseModels.size(); i++) {
TrainingSchemeCourseModel course = courseModels.get(i);
// 设置课程数据行
int dataRowIndex = fourMoudleStart + i;
setCourseDataRow(table, dataRowIndex, course,initCell,countModel,cellWidth);
}
// 前进到下一个模块的起始行
dataRow.set(fourMoudleEnd);
// 更新模块结束行
moduleRowEnd.set(fourMoudleEnd);
});
XWPFTableRow row = table.getRow(moduleRowStart);
XWPFTableCell cell1 = row.getCell(0);
WordUtil.setCellText(cell1, modelName, false, cellWidth.getCellWidth(1));
WordUtil.mergeCellsVertical(table, 0, moduleRowStart, moduleRowEnd.get() - 1);
});
// 设置小计行
int totalRow = totalRows - 1;
setTotalRow(table, totalRow,countModel,4,7,cellWidth);
// deleteCol(table,totalRow,15,16);
return table;
}
private XWPFTable disciplineCoursesTable(XWPFDocument document, String title, List<TrainingSchemeCourseModel> courses) {
// 创建表格标题
WordUtil.createHeading(document, title, 3);
// 计算总行数:表头3行 + 数据行 + 小计1行
int dataRows = courses.size();
int totalRows = 3 + dataRows + 1;
int totalCols = 14; //原始15列,删除第6列和第11列后实际13列
XWPFTable table = document.createTable(totalRows, totalCols);
WordUtil.initTableGrid(table,totalCols,1000);
table.setWidthType(TableWidthType.PCT);
table.setWidth("100%");
CellWidth cellWidth = new CellWidth(15);
// 生成表头(3行)
disciplineCoursesHeader(table,cellWidth);
int dataRowStart = 3;
// 处理每一门课程,确定其所属模块
CountModel countModel = new CountModel();
for (int i = 0; i < courses.size(); i++) {
TrainingSchemeCourseModel course = courses.get(i);
// 设置课程数据行
int dataRowIndex = dataRowStart + i;
setCourseDataRow(table, dataRowIndex, course,0,countModel, cellWidth);
}
// 设置小计行
int totalRow = totalRows - 1;
setTotalRow(table, totalRow,countModel,2,5, cellWidth);
return table;
}
private XWPFTable majorCoursesTable(XWPFDocument document, String title, List<TrainingSchemeCourseModel> courses) {
// 创建表格标题
WordUtil.createHeading(document, title, 3);
Map<String, List<TrainingSchemeCourseModel>> couseMap = courses.stream().collect(Collectors.groupingBy(course -> course.getSubMajorName()==null?"**专业方向":course.getSubMajorName()));
// 计算总行数:表头3行 + 数据行 + 小计1行
int dataRows = courses.size();
int totalRows = 3 + dataRows +couseMap.size();
int totalCols = 15; // 原始15列,删除第6列和第11列后实际13列
XWPFTable table = document.createTable(totalRows, totalCols);
WordUtil.initTableGrid(table,totalCols,1000);
table.setWidthType(TableWidthType.PCT);
table.setWidth("100%");
CellWidth cellWidth = new CellWidth(16);
// 生成表头(3行)
majorCoursesHeader(table,cellWidth);
int dataRowStart = 3;
// 处理每一门课程,确定其所属模块
//todo 专业方向字段
AtomicInteger dataRow = new AtomicInteger(dataRowStart);
couseMap.forEach((majorName,courseModels) -> {
int moduleRowStart = dataRow.get();
int moduleRowEnd = dataRow.get()+courseModels.size();
CountModel countModel = new CountModel();
for (int i = 0; i < courseModels.size(); i++) {
TrainingSchemeCourseModel course = courseModels.get(i);
// 设置课程数据行
int dataRowIndex = moduleRowStart + i;
setCourseDataRow(table, dataRowIndex, course,1,countModel, cellWidth);
}
XWPFTableRow row = table.getRow(moduleRowStart);
XWPFTableCell cell1 = row.getCell(0);
WordUtil.setCellText(cell1, majorName, false, "1134");
WordUtil.mergeCellsVertical(table, 0, moduleRowStart, moduleRowEnd - 1);
// 设置小计行
setTotalRow(table, moduleRowEnd,countModel,3,6, cellWidth);
// deleteCol(table,moduleRowEnd,14,15);
dataRow.set(moduleRowEnd+1);
});
return table;
}
private XWPFTable practicalProjectCourseTable(XWPFDocument document, String title, List<TrainingSchemeCourseModel> courses) {
WordUtil.createHeading(document, title, 3);
// 计算总行数:表头1行 + 数据行+小计
int dataRows = courses.size();
int totalRows = dataRows + 1;
int totalCols = 6; // 原始6
XWPFTable table = document.createTable(totalRows, totalCols);
WordUtil.initTableGrid(table,totalCols,1000);
table.setWidthType(TableWidthType.PCT);
table.setWidth("100%");
CellWidth cellWidth = new CellWidth(6);
// 生成表头(1行)
practicalProjectCourseHeader(table,cellWidth);
int dataRowStart = 1;
Map<String, List<TrainingSchemeCourseModel>> courseMap = courses.stream().collect(Collectors.groupingBy(c -> c.getTrainingCourseModelName() == null ? "" : c.getTrainingCourseModelName()));
// 处理每一门课程,确定其所属模块
AtomicInteger moduleRowStart = new AtomicInteger(dataRowStart);
CountModel countModel = new CountModel();
courseMap.forEach((modelName,courseModels) -> {
int moduleRowEnd = moduleRowStart.get()+courseModels.size();
for (int i = 0; i < courseModels.size(); i++) {
TrainingSchemeCourseModel course = courseModels.get(i);
// 设置课程数据行
int dataRowIndex = moduleRowStart.get() + i;
XWPFTableRow row = table.getRow(dataRowIndex);
//课程名称
XWPFTableCell cell1 = row.getCell(1);
WordUtil.setCellText(cell1, course.getName(), false, cellWidth.getCellWidth(1));
//修读要求
XWPFTableCell cell2 = row.getCell(2);
String attrText = getAttrText(course.getCourseAttr());
WordUtil.setCellText(cell2, attrText, false, cellWidth.getCellWidth(1));
//时间安排
XWPFTableCell cell3 = row.getCell(3);
String timeWeek = course.getTimeWeek() == null ? "" : course.getTimeWeek().toString();
String timeWeekText = timeWeek + (course.getUnit() == null ? "" : course.getUnit());
WordUtil.setCellText(cell3, timeWeekText, false, cellWidth.getCellWidth(1));
//学期安排
XWPFTableCell cell4 = row.getCell(4);
StringBuilder opentermStr=new StringBuilder();
for (Integer openTerm : course.getOpenTerm()) {
if(ObjectUtils.isNotEmpty(openTerm)){
opentermStr.append(term[openTerm-1]+",");
}
}
if(ObjectUtils.isNotEmpty(opentermStr)){
WordUtil.setCellText(cell4,opentermStr.deleteCharAt(opentermStr.length()-1).toString(), false, cellWidth.getCellWidth(1));
}
//支撑课程或实践训练课目
XWPFTableCell cell5 = row.getCell(5);
WordUtil.setCellText(cell5, course.getRemark(), false, cellWidth.getCellWidth(1));
}
//设置模块行
XWPFTableRow row = table.getRow(moduleRowStart.get());
XWPFTableCell cell1 = row.getCell(0);
WordUtil.setCellText(cell1, modelName, false, cellWidth.getCellWidth(1));
WordUtil.mergeCellsVertical(table, 0, moduleRowStart.get(), moduleRowEnd - 1);
moduleRowStart.set(moduleRowEnd);
});
return table;
}
private XWPFTable trainingSubjectCoursesTable(XWPFDocument document, String title, List<TrainingSchemeCourseModel> courses) {
WordUtil.createHeading(document, title, 3);
// 计算总行数:表头1行 + 数据行
int dataRows = courses.size();
int totalRows = dataRows + 1;
int totalCols = 7; // 专业方向 + 项目层级 + 项目名称 + 修读要求 + 时间安排 + 学期安排 + 支撑课程
XWPFTable table = document.createTable(totalRows, totalCols);
WordUtil.initTableGrid(table,totalCols,1000);
table.setWidthType(TableWidthType.PCT);
table.setWidth("100%");
CellWidth cellWidth = new CellWidth(totalCols);
// 生成表头(1行)
trainingSubjectCoursesHeader(table,cellWidth);
int dataRowStart = 1;
// 两层分组:外层专业方向(subMajorName) -> 内层项目层级(projectLevelName),使用 LinkedHashMap 保持输入顺序
Map<String, Map<String, List<TrainingSchemeCourseModel>>> subMajorMap = courses.stream().collect(
Collectors.groupingBy(
c -> c.getSubMajorName() == null ? "" : c.getSubMajorName(),
LinkedHashMap::new,
Collectors.groupingBy(
c -> c.getProjectLevelName() == null ? "**" : c.getProjectLevelName(),
LinkedHashMap::new,
Collectors.toList())));
// 处理每一门课程,确定其所属模块
AtomicInteger moduleRowStart = new AtomicInteger(dataRowStart);
subMajorMap.forEach((subMajorName, levelMap) -> {
int subMajorStart = moduleRowStart.get();
levelMap.forEach((levelName, courseModels) -> {
int levelStart = moduleRowStart.get();
int levelEnd = levelStart + courseModels.size();
for (int i = 0; i < courseModels.size(); i++) {
TrainingSchemeCourseModel course = courseModels.get(i);
// 设置课程数据行
int dataRowIndex = levelStart + i;
XWPFTableRow row = table.getRow(dataRowIndex);
//项目名称
XWPFTableCell cell1 = row.getCell(2);
WordUtil.setCellText(cell1, course.getName(), false, cellWidth.getCellWidth(1));
//修读要求
XWPFTableCell cell2 = row.getCell(3);
String attrText = getAttrText(course.getCourseAttr());
WordUtil.setCellText(cell2, attrText, false, cellWidth.getCellWidth(1));
//时间安排
XWPFTableCell cell3 = row.getCell(4);
String timeWeek = course.getTimeWeek() == null ? "" : course.getTimeWeek().toString();
String timeWeekText = timeWeek + (course.getUnit() == null ? "" : course.getUnit());
WordUtil.setCellText(cell3, timeWeekText, false, cellWidth.getCellWidth(1));
//学期安排
XWPFTableCell cell4 = row.getCell(5);
StringBuilder opentermStr=new StringBuilder();
for (Integer openTerm : course.getOpenTerm()) {
if(ObjectUtils.isNotEmpty(openTerm)){
opentermStr.append(term[openTerm-1]+",");
}
}
if(ObjectUtils.isNotEmpty(opentermStr)){
WordUtil.setCellText(cell4,opentermStr.deleteCharAt(opentermStr.length()-1).toString(), false, cellWidth.getCellWidth(1));
}
//支撑课程或实践训练课目
XWPFTableCell cell5 = row.getCell(6);
WordUtil.setCellText(cell5, course.getSupportingCourseNames(), false, cellWidth.getCellWidth(1));
}
//设置项目层级列(col1)合并
XWPFTableRow levelRow = table.getRow(levelStart);
WordUtil.setCellText(levelRow.getCell(1), levelName, false, cellWidth.getCellWidth(1));
WordUtil.mergeCellsVertical(table, 1, levelStart, levelEnd - 1);
moduleRowStart.set(levelEnd);
});
//设置专业方向列(col0)合并,字段为空显示为空
int subMajorEnd = moduleRowStart.get();
if (subMajorEnd > subMajorStart) {
XWPFTableRow subMajorRow = table.getRow(subMajorStart);
WordUtil.setCellText(subMajorRow.getCell(0), subMajorName == null ? "" : subMajorName, false, cellWidth.getCellWidth(1));
WordUtil.mergeCellsVertical(table, 0, subMajorStart, subMajorEnd - 1);
}
});
// 设置小计行
// int totalRow = totalRows - 1;
// setTotalRow(table, totalRow);
// // deleteCol(table,totalRow,5,6);
return table;
}
/**
* 填充通识课程表格表头(3行)
*/
private void generateCourseHeader(XWPFTable table, CellWidth cellWidth) {
// ========== 表头第1行(行号0) ==========
// 列0:课程模块,跨行3行
setCellText(table.getRow(0).getCell(0), "课程模块", true, cellWidth.getCellWidth(3));
WordUtil.mergeCellsVertical(table, 0, 0, 2);
WordUtil.mergeCellsHorizontal(table, 0, 0, 1);
WordUtil.mergeCellsHorizontal(table, 1, 0, 1);
WordUtil.mergeCellsHorizontal(table, 2, 0, 1);
// 列1:课程名称,跨行3行
setCellText(table.getRow(0).getCell(1), "课程名称", true, cellWidth.getCellWidth(1));
WordUtil.mergeCellsVertical(table, 1, 0, 2);
// 列2:修读要求,跨行3行
setCellText(table.getRow(0).getCell(2), "修读\n要求", true, cellWidth.getCellWidth(1));
WordUtil.mergeCellsVertical(table, 2, 0, 2);
// 列3:考核方式,跨行3行
setCellText(table.getRow(0).getCell(3), "考核\n方式", true, cellWidth.getCellWidth(1));
WordUtil.mergeCellsVertical(table, 3, 0, 2);
// 列4-6:学时安排,跨列3列(小计、讲授、实践)
setCellText(table.getRow(0).getCell(4), "学时安排", true, cellWidth.getCellWidth(3));
WordUtil.mergeCellsHorizontal(table, 0, 4, 6);
// 列7-14:学期安排,跨列8列(4个学年,每个学年2个学期)
setCellText(table.getRow(0).getCell(5), "学期安排", true, cellWidth.getCellWidth(8));
WordUtil.mergeCellsHorizontal(table, 0, 5, 12);
// ========== 表头第2行(行号1) ==========
// 列4-6:学时子项
setCellText(table.getRow(1).getCell(4), "小计", true, cellWidth.getCellWidth(1));
WordUtil.mergeCellsVertical(table, 4, 1, 2);
setCellText(table.getRow(1).getCell(5), "讲授", true, cellWidth.getCellWidth(1));
WordUtil.mergeCellsVertical(table, 5, 1, 2);
setCellText(table.getRow(1).getCell(6), "实践", true, cellWidth.getCellWidth(1));
WordUtil.mergeCellsVertical(table, 6, 1, 2);
// 列7-8:第一学年,跨列2列
setCellText(table.getRow(1).getCell(7), "第一学年", true, cellWidth.getCellWidth(2));
WordUtil.mergeCellsHorizontal(table, 1, 7, 8);
// 列9-10:第二学年,跨列2列
setCellText(table.getRow(1).getCell(8), "第二学年", true, cellWidth.getCellWidth(2));
WordUtil.mergeCellsHorizontal(table, 1, 8, 9);
// 列11-12:第三学年,跨列2列
setCellText(table.getRow(1).getCell(9), "第三学年", true, cellWidth.getCellWidth(2));
WordUtil.mergeCellsHorizontal(table, 1, 9, 10);
// 列13-14:第四学年,跨列2列
setCellText(table.getRow(1).getCell(10), "第四学年", true, cellWidth.getCellWidth(2));
WordUtil.mergeCellsHorizontal(table, 1, 10, 11);
// ========== 表头第3行(行号2) ==========
// 列7-14:学期子项(秋、春交替)
setCellText(table.getRow(2).getCell(7), "秋", true, cellWidth.getCellWidth(1));
setCellText(table.getRow(2).getCell(8), "春", true, cellWidth.getCellWidth(1));
setCellText(table.getRow(2).getCell(9), "秋", true, cellWidth.getCellWidth(1));
setCellText(table.getRow(2).getCell(10), "春", true, cellWidth.getCellWidth(1));
setCellText(table.getRow(2).getCell(11), "秋", true, cellWidth.getCellWidth(1));
setCellText(table.getRow(2).getCell(12), "春", true, cellWidth.getCellWidth(1));
setCellText(table.getRow(2).getCell(13), "秋", true, cellWidth.getCellWidth(1));
setCellText(table.getRow(2).getCell(14), "春", true, cellWidth.getCellWidth(1));
// 删除第一行第二行多余的列
// deleteCol(table,0,6,15); // 删除第6列(索引5)
// deleteCol(table,1,11,15);// 删除第11列(索引10)
// deleteCol(table,2,15,15);// 删除第11列(索引10)
}
/**
* 专业大类课程教学安排
*
* @param table
* @param cellWidth
*/
private void disciplineCoursesHeader(XWPFTable table, CellWidth cellWidth) {
// ========== 表头第1行(行号0) ==========
// 列1:课程名称,跨行3行
setCellText(table.getRow(0).getCell(0), "课程名称", true, cellWidth.getCellWidth(1));
WordUtil.mergeCellsVertical(table, 0, 0, 2);
// 列2:修读要求,跨行3行
setCellText(table.getRow(0).getCell(1), "修读\n要求", true, cellWidth.getCellWidth(1));
WordUtil.mergeCellsVertical(table, 1, 0, 2);
// 列3:考核方式,跨行3行
setCellText(table.getRow(0).getCell(2), "考核\n方式", true, cellWidth.getCellWidth(1));
WordUtil.mergeCellsVertical(table, 2, 0, 2);
// 列4-6:学时安排,跨列3列(小计、讲授、实践)
setCellText(table.getRow(0).getCell(3), "学时安排", true, cellWidth.getCellWidth(3));
WordUtil.mergeCellsHorizontal(table, 0, 3, 5);
// 列7-14:学期安排,跨列8列(4个学年,每个学年2个学期)
setCellText(table.getRow(0).getCell(4), "学期安排", true, cellWidth.getCellWidth(8));
WordUtil.mergeCellsHorizontal(table, 0, 4, 11);
// ========== 表头第2行(行号1) ==========
// 列4-6:学时子项
setCellText(table.getRow(1).getCell(3), "小计", true, cellWidth.getCellWidth(1));
WordUtil.mergeCellsVertical(table, 3, 1, 2);
setCellText(table.getRow(1).getCell(4), "讲授", true, cellWidth.getCellWidth(1));
WordUtil.mergeCellsVertical(table, 4, 1, 2);
setCellText(table.getRow(1).getCell(5), "实践", true, cellWidth.getCellWidth(1));
WordUtil.mergeCellsVertical(table, 5, 1, 2);
// 列7-8:第一学年,跨列2列
setCellText(table.getRow(1).getCell(6), "第一学年", true, cellWidth.getCellWidth(2));
WordUtil.mergeCellsHorizontal(table, 1, 6, 7);
// 列9-10:第二学年,跨列2列
setCellText(table.getRow(1).getCell(7), "第二学年", true, cellWidth.getCellWidth(2));
WordUtil.mergeCellsHorizontal(table, 1, 7, 8);
// 列11-12:第三学年,跨列2列
setCellText(table.getRow(1).getCell(8), "第三学年", true, cellWidth.getCellWidth(2));
WordUtil.mergeCellsHorizontal(table, 1, 8, 9);
// 列13-14:第四学年,跨列2列
setCellText(table.getRow(1).getCell(9), "第四学年", true, cellWidth.getCellWidth(2));
WordUtil.mergeCellsHorizontal(table, 1, 9, 10);
// ========== 表头第3行(行号2) ==========
// 列7-14:学期子项(秋、春交替)
setCellText(table.getRow(2).getCell(6), "秋", true, cellWidth.getCellWidth(1));
setCellText(table.getRow(2).getCell(7), "春", true, cellWidth.getCellWidth(1));
setCellText(table.getRow(2).getCell(8), "秋", true, cellWidth.getCellWidth(1));
setCellText(table.getRow(2).getCell(9), "春", true, cellWidth.getCellWidth(1));
setCellText(table.getRow(2).getCell(10), "秋", true, cellWidth.getCellWidth(1));
setCellText(table.getRow(2).getCell(11), "春", true, cellWidth.getCellWidth(1));
setCellText(table.getRow(2).getCell(12), "秋", true, cellWidth.getCellWidth(1));
setCellText(table.getRow(2).getCell(13), "春", true, cellWidth.getCellWidth(1));
// 删除第一行第二行多余的列
// deleteCol(table,0,5,15); // 删除第6列(索引5)
// deleteCol(table,1,10,15);// 删除第11列(索引10)
}
/**
* 专业方向课程教学安排
*
* @param table
* @param cellWidth
*/
private void majorCoursesHeader(XWPFTable table, CellWidth cellWidth) {
// ========== 表头第1行(行号0) ==========
// 列0:课程模块,跨行3行
setCellText(table.getRow(0).getCell(0), "专业方向", true, cellWidth.getCellWidth(1));
WordUtil.mergeCellsVertical(table, 0, 0, 2);
// 列1:课程名称,跨行3行
setCellText(table.getRow(0).getCell(1), "课程名称", true, cellWidth.getCellWidth(1));
WordUtil.mergeCellsVertical(table, 1, 0, 2);
// 列2:修读要求,跨行3行
setCellText(table.getRow(0).getCell(2), "修读\n要求", true, cellWidth.getCellWidth(1));
WordUtil.mergeCellsVertical(table, 2, 0, 2);
// 列3:考核方式,跨行3行
setCellText(table.getRow(0).getCell(3), "考核\n方式", true, cellWidth.getCellWidth(1));
WordUtil.mergeCellsVertical(table, 3, 0, 2);
// 列4-6:学时安排,跨列3列(小计、讲授、实践)
setCellText(table.getRow(0).getCell(4), "学时安排", true, cellWidth.getCellWidth(3));
WordUtil.mergeCellsHorizontal(table, 0, 4, 6);
// 列7-14:学期安排,跨列8列(4个学年,每个学年2个学期)
setCellText(table.getRow(0).getCell(5), "学期安排", true, cellWidth.getCellWidth(8));
WordUtil.mergeCellsHorizontal(table, 0, 5, 12);
// ========== 表头第2行(行号1) ==========
// 列4-6:学时子项
setCellText(table.getRow(1).getCell(4), "小计", true, cellWidth.getCellWidth(1));
WordUtil.mergeCellsVertical(table, 4, 1, 2);
setCellText(table.getRow(1).getCell(5), "讲授", true, cellWidth.getCellWidth(1));
WordUtil.mergeCellsVertical(table, 5, 1, 2);
setCellText(table.getRow(1).getCell(6), "实践", true, cellWidth.getCellWidth(1));
WordUtil.mergeCellsVertical(table, 6, 1, 2);
// 列7-8:第一学年,跨列2列
setCellText(table.getRow(1).getCell(7), "第一学年", true, cellWidth.getCellWidth(2));
WordUtil.mergeCellsHorizontal(table, 1, 7, 8);
// 列9-10:第二学年,跨列2列
setCellText(table.getRow(1).getCell(8), "第二学年", true, cellWidth.getCellWidth(2));
WordUtil.mergeCellsHorizontal(table, 1, 8, 9);
// 列11-12:第三学年,跨列2列
setCellText(table.getRow(1).getCell(9), "第三学年", true, cellWidth.getCellWidth(2));
WordUtil.mergeCellsHorizontal(table, 1, 9, 10);
// 列13-14:第四学年,跨列2列
setCellText(table.getRow(1).getCell(10), "第四学年", true, cellWidth.getCellWidth(2));
WordUtil.mergeCellsHorizontal(table, 1, 10, 11);
// ========== 表头第3行(行号2) ==========
// 列7-14:学期子项(秋、春交替)
setCellText(table.getRow(2).getCell(7), "秋", true, cellWidth.getCellWidth(1));
setCellText(table.getRow(2).getCell(8), "春", true, cellWidth.getCellWidth(1));
setCellText(table.getRow(2).getCell(9), "秋", true, cellWidth.getCellWidth(1));
setCellText(table.getRow(2).getCell(10), "春", true, cellWidth.getCellWidth(1));
setCellText(table.getRow(2).getCell(11), "秋", true, cellWidth.getCellWidth(1));
setCellText(table.getRow(2).getCell(12), "春", true, cellWidth.getCellWidth(1));
setCellText(table.getRow(2).getCell(13), "秋", true, cellWidth.getCellWidth(1));
setCellText(table.getRow(2).getCell(14), "春", true, cellWidth.getCellWidth(1));
// 删除第一行第二行多余的列
// deleteCol(table,0,6,15); // 删除第6列(索引5)
// deleteCol(table,1,11,15);// 删除第11列(索引10)
}
private void practicalProjectCourseHeader(XWPFTable table, CellWidth cellWidth) {
setCellText(table.getRow(0).getCell(0), "课目模块", true, cellWidth.getCellWidth(1));
setCellText(table.getRow(0).getCell(1), "课目名称", true, cellWidth.getCellWidth(1));
setCellText(table.getRow(0).getCell(2), "修读要求", true, cellWidth.getCellWidth(1));
setCellText(table.getRow(0).getCell(3), "时间安排", true, cellWidth.getCellWidth(1));
setCellText(table.getRow(0).getCell(4), "学期安排", true, cellWidth.getCellWidth(1));
setCellText(table.getRow(0).getCell(5), "备注", true, cellWidth.getCellWidth(1));
}
private void trainingSubjectCoursesHeader(XWPFTable table, CellWidth cellWidth) {
setCellText(table.getRow(0).getCell(0), "专业方向", true, cellWidth.getCellWidth(1));
setCellText(table.getRow(0).getCell(1), "项目层级", true, cellWidth.getCellWidth(1));
setCellText(table.getRow(0).getCell(2), "项目名称", true, cellWidth.getCellWidth(1));
setCellText(table.getRow(0).getCell(3), "修读要求", true, cellWidth.getCellWidth(1));
setCellText(table.getRow(0).getCell(4), "时间安排", true, cellWidth.getCellWidth(1));
setCellText(table.getRow(0).getCell(5), "学期安排", true, cellWidth.getCellWidth(1));
setCellText(table.getRow(0).getCell(6), "支撑课程或实践训练课目", true, cellWidth.getCellWidth(1));
}
/**
* 删除指定行列的单元格(用于删除空列)
*/
private void deleteCol(XWPFTable table, int row, int startCol, int endCol) {
XWPFTableRow currentRow = table.getRow(row);
for (int col = endCol; col >= startCol; col--) {
if (currentRow.getCell(col) != null) {
currentRow.removeCell(col); // 删除指定列的冗余单元格
}
}
}
/**
* 设置表格单元格内容 - 带所有属性
*/
private void setCellText(XWPFTableCell cell, String text, boolean isBold, String width) {
if(ObjectUtils.isEmpty(cell)){
return;
}
// 清空单元格默认段落
while (cell.getParagraphs() != null && !cell.getParagraphs().isEmpty()) {
cell.removeParagraph(0);
}
XWPFParagraph paragraph = cell.addParagraph();
// 水平居中
paragraph.setAlignment(ParagraphAlignment.CENTER);
// 垂直居中
cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
// 设置单元格宽度
if (width != null && !width.isEmpty()) {
cell.setWidth(width);
}
// 设置文本
XWPFRun run = paragraph.createRun();
run.setFontFamily("宋体");
run.setText(text);
run.setFontSize(9);
if (isBold) {
run.setBold(true);
}
}
/**
* 设置课程数据行
*/
private void setCourseDataRow(XWPFTable table, int rowIndex, TrainingSchemeCourseModel course, int initCell, CountModel countModel, CellWidth cellWidth) {
XWPFTableRow row = table.getRow(rowIndex);
// 列1:课程名称
XWPFTableCell cell1 = row.getCell(initCell);
WordUtil.setCellText(cell1, course.getName(), false, cellWidth.getCellWidth(1));
// 列2:修读要求(B=必修,X=限选,R=任选)
XWPFTableCell cell2 = row.getCell(initCell+1);
String attrText = getAttrText(course.getCourseAttr());
WordUtil.setCellText(cell2, attrText, false, cellWidth.getCellWidth(1));
// 列3:考核方式(S=考试,C=考查)
XWPFTableCell cell3 = row.getCell(initCell+2);
String assessText = getAssessText(course.getExaMethod());
WordUtil.setCellText(cell3, assessText, false, cellWidth.getCellWidth(1));
// 列4:小计
XWPFTableCell cell4 = row.getCell(initCell+3);
WordUtil.setCellText(cell4, course.getHours() != null ? course.getHours().toString() : "", false, cellWidth.getCellWidth(1));
countModel.setTotalHours(countModel.getTotalHours()+course.getHours());
// 列5:讲授
XWPFTableCell cell5 = row.getCell(initCell+4);
WordUtil.setCellText(cell5, course.getTeachHours() != null ? course.getTeachHours().toString() : "", false, cellWidth.getCellWidth(1));
countModel.setTeachHours(countModel.getTeachHours()+course.getTeachHours());
// 列6:实践
XWPFTableCell cell6 = row.getCell(initCell+5);
WordUtil.setCellText(cell6, course.getPracticeHours() != null ? course.getPracticeHours().toString() : "", false, cellWidth.getCellWidth(1));
countModel.setPracticeHours(countModel.getPracticeHours()+course.getPracticeHours());
// 列7-12:学期安排(在开课学期填写对应学时)
setTermCheckmarks(row, course,initCell+6,cellWidth,countModel);
}
// private void setGenerateCourseDataRow(XWPFTable table, int rowIndex, TrainingSchemeCourseModel course,int initCell) {
// XWPFTableRow row = table.getRow(rowIndex);
// //列0:课程模块
//
// // 列1:课程名称
// XWPFTableCell cell1 = row.getCell(initCell);
// WordUtil.setCellText(cell1, course.getName(), false, "1985");
//
// // 列2:修读要求(B=必修,X=限选,R=任选)
// XWPFTableCell cell2 = row.getCell(initCell+1);
// String attrText = getAttrText(course.getCourseAttrName());
// WordUtil.setCellText(cell2, attrText, false, "1021");
//
// // 列3:考核方式(S=考试,C=考查)
// XWPFTableCell cell3 = row.getCell(initCell+2);
// String assessText = getAssessText(course.getExaMethod());
// WordUtil.setCellText(cell3, assessText, false, "1021");
//
// // 列4:小计
// XWPFTableCell cell4 = row.getCell(initCell+3);
// WordUtil.setCellText(cell4, course.getHours() != null ? course.getHours().toString() : "", false, "851");
//
// // 列5:讲授
// XWPFTableCell cell5 = row.getCell(initCell+4);
// WordUtil.setCellText(cell5, course.getTeachHours() != null ? course.getTeachHours().toString() : "", false, "851");
//
// // 列6:实践
// XWPFTableCell cell6 = row.getCell(initCell+5);
// WordUtil.setCellText(cell6, course.getPracticeHours() != null ? course.getPracticeHours().toString() : "", false, "851");
//
// // 列7-12:学期安排(根据semesterSchedule和springAutumn判断是否打勾)
// setTermCheckmarks(row, course,initCell+6);
// }
/**
* 设置学期安排:在开课学期填写该学期对应的拆分学时(讲授+实践),未开课学期留空
* 并将各学期学时累加到countModel中,供小计行统计该列总学时
* 拆分学时优先取course.termHoursMap;若无(数据缺失),则按开课学期数均分课程总学时
*/
private void setTermCheckmarks(XWPFTableRow row, TrainingSchemeCourseModel course, int initCell, CellWidth cellWidth, CountModel countModel) {
List<Integer> openTermList = course.getOpenTerm();
Map<Integer, Double> termHoursMap = course.getTermHoursMap();
Double totalHours = course.getHours();
// 默认值:8个学期(第一学年秋季~第四学年春季)均留空
String[] termValues = {"", "", "", "", "", "", "", ""};
if (ObjectUtils.isNotEmpty(openTermList)) {
//过滤出有效的开课学期
List<Integer> validTerms = openTermList.stream()
.filter(Objects::nonNull)
.filter(t -> t >= 1 && t <= 8)
.collect(Collectors.toList());
for (Integer openTerm : validTerms) {
int idx = openTerm - 1;
//优先使用按学期拆分的学时;若无拆分数据则按开课学期数均分总学时
Double termHours = (termHoursMap != null) ? termHoursMap.get(openTerm) : null;
if (termHours == null && totalHours != null && !validTerms.isEmpty()) {
termHours = totalHours / validTerms.size();
}
if (termHours != null) {
termValues[idx] = formatHours(termHours);
if (countModel != null) {
countModel.addTermHours(idx, termHours);
}
}
}
}
// 设置单元格(8个学期对应列)
for (int i = 0; i < 8; i++) {
WordUtil.setCellText(row.getCell(initCell + i), termValues[i], false, cellWidth.getCellWidth(1));
}
}
/**
* 格式化学时:整数显示为整型,否则保留有效小数
*/
private String formatHours(Double hours) {
if (hours == null) {
return "";
}
double v = hours;
if (v == Math.rint(v) && !Double.isInfinite(v)) {
return String.valueOf((long) v);
}
return new java.math.BigDecimal(v).stripTrailingZeros().toPlainString();
}
/**
* 设置小计行
*
* @param dataCell 学时安排(小计/讲授/实践)三列的起始列
* @param termStartCell 学期安排8列的起始列,用于填写各学期总学时
*/
private void setTotalRow(XWPFTable table, int rowIndex, CountModel countModel, int dataCell, int termStartCell, CellWidth cellWidth) {
XWPFTableRow row = table.getRow(rowIndex);
// 列0:小计
XWPFTableCell cell0 = row.getCell(0);
WordUtil.setCellText(cell0, "小 计", true, cellWidth.getCellWidth(3));
// 合并列0-3
WordUtil.mergeCellsHorizontal(table, rowIndex, 0, 1);
XWPFTableCell cell1 = row.getCell(dataCell);
WordUtil.setCellText(cell1, countModel.getTotalHours()+"", true, cellWidth.getCellWidth(1));
XWPFTableCell cell2 = row.getCell(dataCell+1);
WordUtil.setCellText(cell2, countModel.getTeachHours()+"", true, cellWidth.getCellWidth(1));
XWPFTableCell cell3 = row.getCell(dataCell+2);
WordUtil.setCellText(cell3, countModel.getPracticeHours()+"", true, cellWidth.getCellWidth(1));
// 学期安排各列总学时
Double[] termHours = countModel.getTermHours();
for (int i = 0; i < 8; i++) {
WordUtil.setCellText(row.getCell(termStartCell + i), formatHours(termHours[i]), true, cellWidth.getCellWidth(1));
}
}
/**
* 获取修读要求文本(B=必修,X=限选,R=任选)
*/
private String getAttrText(String attrName) {
if (attrName == null) {
return "";
}
// 根据课程属性名称获取对应代码
if (attrName.contains(ConstantTrainingScheme.COMPULSORY_COURSE) ) {
return "B";
} else if (attrName.contains(ConstantTrainingScheme.ELECTIVE_COURSE) ) {
return "X";
} else if (attrName.contains(ConstantTrainingScheme.OPTIONAL_COURSE) ) {
return "R";
}
return attrName;
}
/**
* 获取考核方式文本(S=考试,C=考查)
*/
private String getAssessText(String exaMethod) {
if (exaMethod == null) {
return "";
}
// 根据开课学期判断考核方式
if (exaMethod.contains("1") || exaMethod.contains("S")) {
return "S";
} else if (exaMethod.contains("2") || exaMethod.contains("C")) {
return "C";
}
return exaMethod;
}
}
下一篇: 暂无相关文章
排名:
经验值
0
文章
0
评论
0
勋章
0
动态
0
粉丝
0
关注
获得勋章:
