新增导出测试用例章节模板

This commit is contained in:
zwz 2025-06-06 15:44:52 +08:00
parent 77381ea173
commit 60eeb05560
1 changed files with 171 additions and 40 deletions

View File

@ -5,6 +5,7 @@ import com.microservices.common.core.exception.ServiceException;
import com.microservices.common.core.utils.DateUtils;
import com.microservices.common.core.utils.JSONUtils;
import com.microservices.common.core.utils.PageUtils;
import com.microservices.common.core.utils.PinYinStringUtils;
import com.microservices.common.core.utils.bean.BeanUtils;
import com.microservices.common.core.web.page.GenericsTableDataInfo;
import com.microservices.common.security.utils.SecurityUtils;
@ -49,6 +50,7 @@ import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import static com.microservices.common.core.utils.PageUtils.startPage;
@ -894,17 +896,19 @@ public class PmsProjectTestcaseServiceImpl implements IPmsProjectTestcaseService
// 添加表格标题应该是<章节号>-<表格序号>
private static void addNumberedTableTitle(XWPFDocument doc, String titleText, int chapter, int tableCount) {
private static void addNumberedTableTitle(XWPFDocument doc, String titleText, int tableCount) {
int chapter = 4;
XWPFParagraph titleParagraph = doc.createParagraph();
titleParagraph.setAlignment(ParagraphAlignment.CENTER);
XWPFRun run = titleParagraph.createRun();
run.setText("");
//run.setText("" + chapter + "-" + tableNumber);
// run.setText("" + titleText);
// // 设置标题样式
// 设置标题样式
run.setFontFamily("Times New Roman");
run.setFontFamily("宋体", XWPFRun.FontCharRange.eastAsia);
run.setFontSize(12);
CTRPr rPr0 = run.getCTR().isSetRPr() ? run.getCTR().getRPr() : run.getCTR().addNewRPr();
rPr0.addNewSz().setVal(BigInteger.valueOf(21));
rPr0.addNewSzCs().setVal(BigInteger.valueOf(21));
// 创建域开始字符
XWPFRun startRun = titleParagraph.createRun();
@ -915,19 +919,29 @@ public class PmsProjectTestcaseServiceImpl implements IPmsProjectTestcaseService
XWPFRun codeRun = titleParagraph.createRun();
String domainCode = " SEQ Table \\* ARABIC \\s " + chapter;
codeRun.setText(domainCode);
codeRun.setFontSize(12); // 设置字体大小可根据需要调整
// 设置字体大小可根据需要调整
CTRPr rPr1 = codeRun.getCTR().isSetRPr() ? codeRun.getCTR().getRPr() : codeRun.getCTR().addNewRPr();
rPr1.addNewSz().setVal(BigInteger.valueOf(21));
rPr1.addNewSzCs().setVal(BigInteger.valueOf(21));
codeRun.setFontFamily("Times New Roman");
codeRun.setFontFamily("宋体", XWPFRun.FontCharRange.eastAsia);
// 创建域分隔字符
XWPFRun sepRun = titleParagraph.createRun();
CTFldChar sepFldChar = sepRun.getCTR().addNewFldChar();
// 设置字体大小可根据需要调整
CTRPr rPr2 = sepRun.getCTR().isSetRPr() ? sepRun.getCTR().getRPr() : sepRun.getCTR().addNewRPr();
rPr2.addNewSz().setVal(BigInteger.valueOf(21));
rPr2.addNewSzCs().setVal(BigInteger.valueOf(21));
sepFldChar.setFldCharType(STFldCharType.SEPARATE);
// 创建域结果
XWPFRun resultRun = titleParagraph.createRun();
resultRun.setText(chapter + " - " + tableCount);
resultRun.setFontSize(12); // 设置字体大小可根据需要调整
// 设置字体大小可根据需要调整
CTRPr rPr3 = resultRun.getCTR().isSetRPr() ? resultRun.getCTR().getRPr() : resultRun.getCTR().addNewRPr();
rPr3.addNewSz().setVal(BigInteger.valueOf(21));
rPr3.addNewSzCs().setVal(BigInteger.valueOf(21));
resultRun.setFontFamily("Times New Roman");
resultRun.setFontFamily("宋体", XWPFRun.FontCharRange.eastAsia);
@ -938,7 +952,10 @@ public class PmsProjectTestcaseServiceImpl implements IPmsProjectTestcaseService
XWPFRun titlerun = titleParagraph.createRun();
titlerun.setText(titleText);
titlerun.setFontSize(12); // 设置字体大小可根据需要调整
// 设置字体大小可根据需要调整
CTRPr rPr4 = titlerun.getCTR().isSetRPr() ? titlerun.getCTR().getRPr() : titlerun.getCTR().addNewRPr();
rPr4.addNewSz().setVal(BigInteger.valueOf(21));
rPr4.addNewSzCs().setVal(BigInteger.valueOf(21));
titlerun.setFontFamily("Times New Roman");
titlerun.setFontFamily("宋体", XWPFRun.FontCharRange.eastAsia);
}
@ -994,14 +1011,11 @@ public class PmsProjectTestcaseServiceImpl implements IPmsProjectTestcaseService
// 设置字体样式
CTRPr rpr = ctStyle.addNewRPr();
CTFonts fonts = rpr.addNewRFonts();
fonts.setEastAsia("");
fonts.setEastAsia("");
fonts.setAscii("Times New Roman");
fonts.setHAnsi("Times New Roman");
if(styles.getNumberOfStyles() < 4){
rpr.addNewSz().setVal(BigInteger.valueOf(fontSize * 2));
}else{
rpr.addNewSz().setVal(BigInteger.valueOf(24));
}
rpr.addNewSz().setVal(BigInteger.valueOf(21));
rpr.addNewSzCs().setVal(BigInteger.valueOf(21));
// 将样式添加到样式管理器中
styles.addStyle(new XWPFStyle(ctStyle));
@ -1077,32 +1091,155 @@ public class PmsProjectTestcaseServiceImpl implements IPmsProjectTestcaseService
return BigInteger.ONE;
}
private static void addNumberedHeading(XWPFDocument doc, String text, int level) {
private static String getFirstPinyin(String text){
String regEx = "\\pP|\\pS|\\s+";
String reqTitleIdentifier = Pattern.compile(regEx).matcher(text).replaceAll("").trim();
reqTitleIdentifier = PinYinStringUtils.toFirstChar(reqTitleIdentifier).toUpperCase();
text = text + reqTitleIdentifier;
return text;
}
private static void addNumberedHeading(XWPFDocument doc, String text, int level , boolean isGetPinYin) {
XWPFParagraph para = doc.createParagraph();
para.setStyle("Heading" + level);
XWPFRun run = para.createRun();
if (isGetPinYin) {
text = getFirstPinyin(text);
}
run.setText(text);
}
// 插入分页符另起一页,生成最后一个表格后不用插入
private void insertTable(XWPFDocument doc,List<PendingOutputDataVo> pendingOutputDatas, int chapter) {
// 插入分页符另起一页
private int insertTable(XWPFDocument doc,List<PendingOutputDataVo> pendingOutputDatas, int counts) {
for (int i = 0; i < pendingOutputDatas.size(); i++) {
counts = counts + 1;
PendingOutputDataVo pendingOutputData = pendingOutputDatas.get(i);
//addNumberedTableTitle(doc, pendingOutputData.getTitle());
addNumberedTableTitle(doc, pendingOutputData.getTitle(), chapter,i + 1);
addNumberedTableTitle(doc, pendingOutputData.getTitle(), counts);
creatTableTemplate(doc,pendingOutputData);
if (i < pendingOutputDatas.size() - 1){
XWPFParagraph pageBreak = doc.createParagraph();
XWPFRun pageBreakRun = pageBreak.createRun();
pageBreakRun.addBreak(BreakType.PAGE);
}
XWPFParagraph pageBreak = doc.createParagraph();
XWPFRun pageBreakRun = pageBreak.createRun();
pageBreakRun.addBreak(BreakType.PAGE);
}
return counts;
}
private void fillMainContent(XWPFDocument document, String text) {
XWPFParagraph paragraph = document.createParagraph();
paragraph.setAlignment(ParagraphAlignment.LEFT); // 居中
// 400 = 2 * 200一个中文字符大约200单位
paragraph.setIndentationFirstLine(400);
// 设置自动换行
paragraph.setWordWrapped(true);
XWPFRun titleRun = paragraph.createRun();
titleRun.setText(text);
// 字体大小
//设置字体为五号 10.5*2
CTRPr rPr = titleRun.getCTR().isSetRPr() ? titleRun.getCTR().getRPr() : titleRun.getCTR().addNewRPr();
rPr.addNewSz().setVal(BigInteger.valueOf(21));
rPr.addNewSzCs().setVal(BigInteger.valueOf(21));
// 字体样式
titleRun.setFontFamily("Times New Roman");
titleRun.setFontFamily("宋体", XWPFRun.FontCharRange.eastAsia);
}
private void fillFixedContent(XWPFDocument document, Long projectId, List<TreeSelect> treeSelects){
String mainText = "格式说明: 正文宋体、五号、段落间距固定值20磅各级标题黑体、五号、段落间距固定值20磅";
fillMainContent(document,mainText);
// 写入第一章内容
addNumberedHeading(document,"范围",1, false);
// 1.1
addNumberedHeading(document,"标识",2, false);
mainText = "本条应描述本文档所适用系统和软件的完整标识,(若适用)包括其标识号、名称、缩略名、版本号和发布号。";
fillMainContent(document,mainText);
//1.2
addNumberedHeading(document,"系统概述",2, false);
mainText = "本条应概述本文档适用的系统和软件的用途;描述系统和软件的一般特性(如规模、安全性、可靠性、实时性、技术风险等特性)"+
"概述系统开发、运行和维护的历史;标识项目的需方、用户、开发方和保障机构等;标识当前和计划的运行现场;列出其他有关文档。";
fillMainContent(document,mainText);
//1.3
addNumberedHeading(document,"文档概述",2, false);
mainText = "本条应概述本文档的用途和内容,并描述与它的使用有关的安全保密方面的要求。";
fillMainContent(document,mainText);
// 写入第二章内容
addNumberedHeading(document,"引用文档",1, false);
mainText = "本章应列出引用文档的编号、标题、编写单位、修订版及日期,还应给出不能通过正常渠道得到的文档的来源。";
fillMainContent(document,mainText);
// 写入第三章内容
addNumberedHeading(document,"测试准备",1, false);
mainText = "本章应分为以下子条。(若适用)应包括用“警告”或“注意”所标志的安全提示,以及保密性考虑。";
fillMainContent(document,mainText);
// 3.1
addNumberedHeading(document,"(测试唯一标识符)",2, false);
mainText = "本条应使用项目的唯一标识符来标识一个测试,并对测试进行简要说明,同时应分为以下子条描述。" +
"若与另一个测试所要求的信息存在重复时,可直接引用。";
fillMainContent(document,mainText);
// 3.1.1
addNumberedHeading(document,"硬件准备",3, false);
mainText = "本条应描述测试工作所需的硬件准备规程。有关这些规程,可以引用已发布的操作手册。(若适用)应提供以下内容:";
fillMainContent(document,mainText);
mainText = "a) 用名称和(若适用)编号标识要使用的特定硬件;";
fillMainContent(document,mainText);
mainText = "b) 所有连接硬件所需的开关装置和电缆;";
fillMainContent(document,mainText);
mainText = "c) 说明硬件、互联控制和数据路径的一个或多个图示;";
fillMainContent(document,mainText);
mainText = "d) 使硬件处于就绪状态的逐步的操作说明;";
fillMainContent(document,mainText);
//3.1.2
addNumberedHeading(document,"软件准备",3, false);
mainText = "本条应描述准备被测项、相关软件以及数据的必要规程。有关这些规程,可以引用已发布的软件手册。(若适用)应提供下述信息:";
fillMainContent(document,mainText);
mainText = "a) 测试中要使用的特定软件;";
fillMainContent(document,mainText);
mainText = "b) 被测项的存储介质(如光盘、磁盘)";
fillMainContent(document,mainText);
mainText = "c) 所有相关软件(如模拟器、测试驱动程序、数据库)的存储介质;";
fillMainContent(document,mainText);
mainText = "d) 加载软件的说明,包括所需的顺序;";
fillMainContent(document,mainText);
mainText = "e) 多个测试用例共用的软件初始化说明;";
fillMainContent(document,mainText);
//3.1.3
addNumberedHeading(document,"其它测试前准备",3, false);
mainText = "本条应描述其他测试前所需的人员活动、准备工作或规程。";
fillMainContent(document,mainText);
// 写入第四章内容
addNumberedHeading(document,"测试说明",1, false);
mainText = "本章应分为以下子条。(若适用)应包括用“警告”或“注意”所标志的安全提示,以及保密性考虑。";
fillMainContent(document,mainText);
// 添加带自动编号的内容
iterateTraversl(projectId, treeSelects, document);
//写入第五章内容
addNumberedHeading(document,"需求的可追踪性",1, false);
mainText = "本条应描述:";
fillMainContent(document,mainText);
mainText = "a) 从软件测试说明中的测试用例到它所涉及的系统或CSCI需求的可追踪性。" +
"若一个测试用例涉及多个需求,应包含从每一组测试规程步骤到所涉及的需求的可追踪性(亦可在4.X.Y.1中提供)。";
fillMainContent(document,mainText);
mainText = "b) 从本软件测试说明所提及的每项系统或CSCI需求到涉及它们的测试用例的可追踪性。" +
"对于CSCI测试是从CSCI的软件需求规格说明(SRS)和有关接口需求规格说明(IRS)中的每项CSCI需求到涉及它们的测试用例的可追踪性。" +
"对于系统测试,是从系统的系统/子系统规格说明(SSS)及有关IRS中的每项系统需求到涉及它们的测试用例的可追踪性。" +
"如果一个测试用例涉及多项需求,则可追踪性应指明涉及每项需求的特定测试规程步骤。";
fillMainContent(document,mainText);
mainText = "软件测试说明可通过软件测试计划建立与系统或CSCI需求双向可追踪性";
fillMainContent(document,mainText);
//写入第六章内容
addNumberedHeading(document,"注释",1, false);
mainText = "本章应包括有助于了解文档的所有信息(例如:背景、术语、缩略语或公式)。";
fillMainContent(document,mainText);
}
private void iterateTraversl(Long projectId, List<TreeSelect> treeSelects, XWPFDocument document){
// 获取文档的样式管理器
//XWPFStyles styles = document.createStyles();
// 使用栈进行迭代遍历
Stack<TreeSelect> stack = new Stack<>();
// 先将所有根节点压入栈
@ -1112,31 +1249,25 @@ public class PmsProjectTestcaseServiceImpl implements IPmsProjectTestcaseService
}
}
int chapter = 0;
int tableCounts = 0;
while (!stack.isEmpty()) {
TreeSelect current = stack.pop();
// 处理当前节点这里简单打印节点信息你可以根据需求修改
// System.out.println("ID: " + current.getId() + ", 名称: " + current.getLabel() + ", 层级:" + current.getLevel() + ", 父ID: " + current.getParentId() + ", 是否叶子节点: " + current.getIsLeaf() );
//System.out.println("ID: " + current.getId() + ", 名称: " + current.getLabel() + ", 层级:" + current.getLevel() + ", 父ID: " + current.getParentId() + ", 是否叶子节点: " + current.getIsLeaf() );
if (current.getIsLeaf()) {
if (current.getLevel() == 1){
chapter = chapter + 1;
}
if(current.getId() > 0){
addNumberedHeading(document, current.getLabel(), current.getLevel());
addNumberedHeading(document, current.getLabel(), current.getLevel() + 1, true);
List<PendingOutputDataVo> pendingOutputDatas = GetPendingOutputData(projectId, current.getId());
insertTable(document, pendingOutputDatas, chapter);
tableCounts = insertTable(document, pendingOutputDatas, tableCounts);
} else {
addNumberedHeading(document, current.getLabel(), current.getLevel());
addNumberedHeading(document, current.getLabel(), current.getLevel() + 1, true);
List<PendingOutputDataVo> pendingOutputDatas = GetPendingOutputData(projectId, null);
insertTable(document, pendingOutputDatas, chapter);
tableCounts = insertTable(document, pendingOutputDatas, tableCounts);
}
} else{
if (current.getLevel() == 1){
chapter = chapter + 1;
}
if(current.getId() > 0){
addNumberedHeading(document, current.getLabel(), current.getLevel());
if (current.getId() > 0){
addNumberedHeading(document, current.getLabel(), current.getLevel() + 1, true);
}
}
//处理当前节点结束
@ -1170,8 +1301,8 @@ public class PmsProjectTestcaseServiceImpl implements IPmsProjectTestcaseService
titleRun.setText("测试用例");
titleRun.setFontSize(22); // 字体大小
titleRun.setFontFamily("宋体"); // 字体样式
// 添加带自动编号的内容
iterateTraversl(projectId, treeSelects, document);
// 增加固定格式内容
fillFixedContent(document,projectId, treeSelects);
// 设置响应头
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);