|
@@ -1,481 +1,481 @@
|
|
-package com.qmth.cqb.paper.service.export;
|
|
|
|
-
|
|
|
|
-import java.math.BigDecimal;
|
|
|
|
-import java.util.ArrayList;
|
|
|
|
-import java.util.HashMap;
|
|
|
|
-import java.util.HashSet;
|
|
|
|
-import java.util.List;
|
|
|
|
-import java.util.Map;
|
|
|
|
-import java.util.Set;
|
|
|
|
-import java.util.stream.Collectors;
|
|
|
|
-
|
|
|
|
-import javax.servlet.http.HttpServletResponse;
|
|
|
|
-import javax.xml.bind.JAXBElement;
|
|
|
|
-
|
|
|
|
-import org.apache.commons.lang3.StringUtils;
|
|
|
|
-import org.docx4j.XmlUtils;
|
|
|
|
-import org.docx4j.jaxb.Context;
|
|
|
|
-import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
|
|
|
|
-import org.docx4j.wml.Body;
|
|
|
|
-import org.docx4j.wml.P;
|
|
|
|
-import org.docx4j.wml.R;
|
|
|
|
-import org.docx4j.wml.Text;
|
|
|
|
-import org.slf4j.Logger;
|
|
|
|
-import org.slf4j.LoggerFactory;
|
|
|
|
-import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
-
|
|
|
|
-import cn.com.qmth.examcloud.common.dto.core.enums.CourseLevel;
|
|
|
|
-import cn.com.qmth.examcloud.common.dto.question.enums.QuesStructType;
|
|
|
|
-
|
|
|
|
-import com.qmth.cqb.paper.dao.PaperDetailRepo;
|
|
|
|
-import com.qmth.cqb.paper.dao.PaperDetailUnitRepo;
|
|
|
|
-import com.qmth.cqb.paper.dao.PaperRepo;
|
|
|
|
-import com.qmth.cqb.paper.dto.PaperDetailExp;
|
|
|
|
-import com.qmth.cqb.paper.dto.PaperDetailUnitExp;
|
|
|
|
-import com.qmth.cqb.paper.dto.PaperExp;
|
|
|
|
-import com.qmth.cqb.paper.model.Paper;
|
|
|
|
-import com.qmth.cqb.paper.model.PaperDetail;
|
|
|
|
-import com.qmth.cqb.paper.model.PaperDetailUnit;
|
|
|
|
-import com.qmth.cqb.paper.service.PaperService;
|
|
|
|
-import com.qmth.cqb.question.dao.QuesRepo;
|
|
|
|
-import com.qmth.cqb.question.model.QuesOption;
|
|
|
|
-import com.qmth.cqb.question.model.Question;
|
|
|
|
-import com.qmth.cqb.utils.BeanCopierUtil;
|
|
|
|
-import com.qmth.cqb.utils.CommonUtils;
|
|
|
|
-import com.qmth.cqb.utils.exception.PaperException;
|
|
|
|
-import com.qmth.cqb.utils.word.DocxProcessUtil;
|
|
|
|
-
|
|
|
|
-import freemarker.template.Configuration;
|
|
|
|
-import freemarker.template.Template;
|
|
|
|
-
|
|
|
|
-public abstract class ExportPaperAbstractService {
|
|
|
|
-
|
|
|
|
- private static final Logger logger = LoggerFactory.getLogger(ExportPaperAbstractService.class);
|
|
|
|
-
|
|
|
|
- @Autowired
|
|
|
|
- PaperRepo paperRepo;
|
|
|
|
-
|
|
|
|
- @Autowired
|
|
|
|
- PaperService paperService;
|
|
|
|
-
|
|
|
|
- @Autowired
|
|
|
|
- PaperDetailRepo paperDetailRepo;
|
|
|
|
-
|
|
|
|
- @Autowired
|
|
|
|
- PaperDetailUnitRepo paperDetailUnitRepo;
|
|
|
|
-
|
|
|
|
- @Autowired
|
|
|
|
- QuesRepo quesRepo;
|
|
|
|
-
|
|
|
|
- private static final String FILL_BLANK_QUESTION_FLAG = "###";
|
|
|
|
-
|
|
|
|
- public static Configuration CONFIGURATION;
|
|
|
|
-
|
|
|
|
- public static final String ENCODING = "UTF-8";
|
|
|
|
-
|
|
|
|
- //陕西师范模板
|
|
|
|
- protected static Template SXSF_TEMPLATE_PAPER;
|
|
|
|
- protected static Template SXSF_TEMPLATE_ANSWER;
|
|
|
|
- //电子科大模板
|
|
|
|
- protected static Template DZKD_TEMPLATE_PAPER;
|
|
|
|
- protected static Template DZKD_TEMPLATE_ANSWER;
|
|
|
|
- //石油大学模板
|
|
|
|
- //protected static Template SYDX_TEMPLATE_NORMAL;
|
|
|
|
-
|
|
|
|
- static {
|
|
|
|
- try {
|
|
|
|
- CONFIGURATION = new Configuration(Configuration.VERSION_2_3_25);
|
|
|
|
- // 设置编码
|
|
|
|
- CONFIGURATION.setDefaultEncoding(ENCODING);
|
|
|
|
- // 设置ftl模板路径
|
|
|
|
- CONFIGURATION.setClassForTemplateLoading(DocxProcessUtil.class, "/");
|
|
|
|
-
|
|
|
|
- SXSF_TEMPLATE_PAPER = CONFIGURATION.getTemplate("sxsf_paper_template.ftl", ENCODING);
|
|
|
|
- SXSF_TEMPLATE_ANSWER = CONFIGURATION.getTemplate("sxsf_answer_template.ftl", ENCODING);
|
|
|
|
-
|
|
|
|
- DZKD_TEMPLATE_PAPER = CONFIGURATION.getTemplate("dzkd_paper_template.ftl", ENCODING);
|
|
|
|
- DZKD_TEMPLATE_ANSWER = CONFIGURATION.getTemplate("dzkd_answer_template.ftl", ENCODING);
|
|
|
|
-
|
|
|
|
- //SYDX_TEMPLATE_NORMAL = CONFIGURATION.getTemplate("paper_template.ftl", ENCODING);
|
|
|
|
- } catch (Exception e) {
|
|
|
|
- e.printStackTrace();
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 下载试卷
|
|
|
|
- * @param id
|
|
|
|
- * @param response
|
|
|
|
- * @throws Exception
|
|
|
|
- */
|
|
|
|
- public abstract void downloadPaper(String id, HttpServletResponse response)throws Exception;
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 初始化导出试卷DTO
|
|
|
|
- *
|
|
|
|
- * @param id
|
|
|
|
- * @return
|
|
|
|
- */
|
|
|
|
- protected Map<String,Object> initExportPaper(String id) throws Exception {
|
|
|
|
- // 创建返回Map
|
|
|
|
- Map<String,Object> returnMap = new HashMap<String,Object>();
|
|
|
|
- // 获取paper
|
|
|
|
- Paper paper = paperRepo.findOne(id);
|
|
|
|
- paperService.formatPaper(paper, null);
|
|
|
|
- if (paper == null) {
|
|
|
|
- throw new PaperException("该试卷不存在");
|
|
|
|
- }
|
|
|
|
- // 创建paperDto
|
|
|
|
- PaperExp paperExp = BeanCopierUtil.copyProperties(paper, PaperExp.class);
|
|
|
|
- paperExp.setCourseLevel(paper.getLevel()==null?CourseLevel.ALL.name():paper.getLevel().name());
|
|
|
|
- List<PaperDetailExp> objectiveDetails = new ArrayList<PaperDetailExp>();// 客观题
|
|
|
|
- List<PaperDetailExp> subjectiveDetails = new ArrayList<PaperDetailExp>();// 主观题
|
|
|
|
- double objectiveScore = 0;
|
|
|
|
- double subjectiveScore = 0;
|
|
|
|
- paperExp.setTitle(CommonUtils.PAPER_TITLE);
|
|
|
|
- paperExp.setSubTitle(CommonUtils.PAPER_SUB_TITLE);
|
|
|
|
- // 获取大题
|
|
|
|
- List<PaperDetail> paperDetails = paperDetailRepo.findByPaper(paper);
|
|
|
|
- int objectNumber = 1;// 客观题大题序号
|
|
|
|
- int objetcUnitSum = 0;
|
|
|
|
- for (int i = 0; i < paperDetails.size(); i++) {
|
|
|
|
- PaperDetailExp paperDetailExp = BeanCopierUtil.copyProperties(paperDetails.get(i), PaperDetailExp.class);
|
|
|
|
- List<PaperDetailUnit> paperDetailUnits = paperDetailUnitRepo.findByPaperDetail(paperDetails.get(i));
|
|
|
|
- // 把大题分类 :客观题和主观题
|
|
|
|
- List<PaperDetailUnitExp> paperDetailUnitExps = BeanCopierUtil.copyPropertiesOfList(paperDetailUnits,PaperDetailUnitExp.class);
|
|
|
|
- // 选择题,套题下选择题 选项顺序重新排列
|
|
|
|
- paperService.reorderChoicequestionOption(paperDetailUnitExps);
|
|
|
|
- paperDetailExp.setPaperDetailUnits(paperDetailUnitExps);
|
|
|
|
- boolean hasTextAnswer = false;// 判断主观题
|
|
|
|
- if (paperDetailUnits.get(0).getQuestionType() == QuesStructType.NESTED_ANSWER_QUESTION) {
|
|
|
|
- for (Question ques : paperDetailUnits.get(0).getQuestion().getSubQuestions()) {
|
|
|
|
- if (ques.getQuestionType() == QuesStructType.TEXT_ANSWER_QUESTION) {
|
|
|
|
- hasTextAnswer = true;
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- } else if (paperDetailUnits.get(0).getQuestionType() == QuesStructType.TEXT_ANSWER_QUESTION
|
|
|
|
- ||paperDetailUnits.get(0).getQuestionType() == QuesStructType.FILL_BLANK_QUESTION) {
|
|
|
|
- hasTextAnswer = true;
|
|
|
|
- }
|
|
|
|
- if (hasTextAnswer) {
|
|
|
|
- subjectiveDetails.add(paperDetailExp);
|
|
|
|
- subjectiveScore += paperDetailExp.getScore();
|
|
|
|
- } else {
|
|
|
|
- objectiveDetails.add(paperDetailExp);
|
|
|
|
- paperDetailExp.setNumber(objectNumber);
|
|
|
|
- paperDetailExp.setCnNum(CommonUtils.toCHNum(objectNumber));
|
|
|
|
- objectiveScore += paperDetailExp.getScore();
|
|
|
|
- objetcUnitSum += paperDetailExp.getUnitCount();
|
|
|
|
- objectNumber++;
|
|
|
|
- }
|
|
|
|
- setExpTitle(paperDetailExp);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- paperExp.setObjectiveDetails(objectiveDetails);
|
|
|
|
- paperExp.setSubjectiveDetails(subjectiveDetails);
|
|
|
|
- paperExp.setObjectiveScore(objectiveScore);
|
|
|
|
- paperExp.setSubjectiveScore(subjectiveScore);
|
|
|
|
- if (objectiveDetails.size() > 0) {
|
|
|
|
- setUnitExpNumber(objectiveDetails, 0);
|
|
|
|
- setScore(objectiveDetails);
|
|
|
|
- }
|
|
|
|
- if (subjectiveDetails.size() > 0) {
|
|
|
|
- for (PaperDetailExp subDetail : subjectiveDetails) {
|
|
|
|
- subDetail.setNumber(objectNumber);
|
|
|
|
- subDetail.setCnNum(CommonUtils.toCHNum(objectNumber));
|
|
|
|
- objectNumber++;
|
|
|
|
- }
|
|
|
|
- setUnitExpNumber(subjectiveDetails, objetcUnitSum);
|
|
|
|
- setScore(subjectiveDetails);
|
|
|
|
- }
|
|
|
|
- returnMap.put("paper", paperExp);
|
|
|
|
- returnMap.put("fileName", paperExp.getName());
|
|
|
|
-
|
|
|
|
- return returnMap;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- protected void setExpTitle(PaperDetailExp paperDetailExp) {
|
|
|
|
- String title = "";
|
|
|
|
- String totalScore = BigDecimal.valueOf(paperDetailExp.getScore()).stripTrailingZeros().toPlainString();
|
|
|
|
- String unitScore = BigDecimal.valueOf(paperDetailExp.getPaperDetailUnits().get(0).getScore()).stripTrailingZeros().toPlainString();
|
|
|
|
- QuesStructType type = paperDetailExp.getPaperDetailUnits().get(0).getQuestionType();
|
|
|
|
- String scoreString = checkPaperDetailUnitScore(paperDetailExp) ? "每小题"+ unitScore + "分" : "";
|
|
|
|
- if (type == QuesStructType.SINGLE_ANSWER_QUESTION) {
|
|
|
|
- paperDetailExp.setName("单项选择题");
|
|
|
|
- title = "(本大题共" + paperDetailExp.getUnitCount() + "小题,"
|
|
|
|
- + scoreString + "共" + totalScore + "分)。"
|
|
|
|
- + "在每小题列出的四个备选中只有一个符合题目要求的,请将其选出并将“答题卡”的相应代码涂黑,错涂、多涂或未涂均无分";
|
|
|
|
- } else if (type == QuesStructType.BOOL_ANSWER_QUESTION) {
|
|
|
|
- paperDetailExp.setName("判断题");
|
|
|
|
- title = "(本大题共" + paperDetailExp.getUnitCount() + "小题,"+ scoreString + "共" + totalScore+ "分。正确的填涂A、错误填涂B。错涂、多涂或未涂均无分)";
|
|
|
|
- } else if (type == QuesStructType.FILL_BLANK_QUESTION) {
|
|
|
|
- paperDetailExp.setName("填空题");
|
|
|
|
- int blankNum = 0;
|
|
|
|
- for (PaperDetailUnitExp unit:paperDetailExp.getPaperDetailUnits()){
|
|
|
|
- String tempStr = unit.getQuestion().getQuesBody().replaceAll(FILL_BLANK_QUESTION_FLAG, "");
|
|
|
|
- int lenTimes = (unit.getQuestion().getQuesBody().length() - tempStr.length()) / FILL_BLANK_QUESTION_FLAG.length();// 出现的次数
|
|
|
|
- blankNum += lenTimes;
|
|
|
|
- }
|
|
|
|
- title = "(本大题共"+blankNum+"个空格,将每空答在答题卡 “1—" +blankNum+"”相应的序号上。"+"共"+totalScore + "分)";
|
|
|
|
- } else {
|
|
|
|
- title = "(本大题共"+paperDetailExp.getUnitCount()+"小题,"+scoreString+"共"+totalScore+"分)";
|
|
|
|
- }
|
|
|
|
- paperDetailExp.setTitle(title);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 校验大题下的小题分数是不是一样
|
|
|
|
- *
|
|
|
|
- * @param paperDetailExp
|
|
|
|
- * @return
|
|
|
|
- */
|
|
|
|
- protected boolean checkPaperDetailUnitScore(PaperDetailExp paperDetailExp) {
|
|
|
|
- List<PaperDetailUnitExp> paperDetailUnitExps = paperDetailExp.getPaperDetailUnits();
|
|
|
|
- Set<Double> scoreSet = new HashSet<Double>();
|
|
|
|
- for (PaperDetailUnitExp unitExp : paperDetailUnitExps) {
|
|
|
|
- scoreSet.add(unitExp.getScore());
|
|
|
|
- }
|
|
|
|
- return scoreSet.size() == 1;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- protected void setUnitExpNumber(List<PaperDetailExp> paperDetails,int startIndxt) throws Exception {
|
|
|
|
- int subNum = startIndxt;
|
|
|
|
- for (PaperDetailExp paperDetail : paperDetails) {
|
|
|
|
- for (PaperDetailUnitExp paperDetailUnit : paperDetail.getPaperDetailUnits()) {
|
|
|
|
- List<QuesOption> optionList = paperDetailUnit.getQuestion().getQuesOptions();
|
|
|
|
- if (optionList != null && optionList.size() > 0) {
|
|
|
|
- int index = 0;
|
|
|
|
- for (QuesOption quesOption : optionList) {
|
|
|
|
- quesOption.setOptionBodyWord(setOptionNum(quesOption.getOptionBodyWord(),getOptionNum(index)));
|
|
|
|
- index++;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- List<Question> subQuesList = paperDetailUnit.getQuestion().getSubQuestions();
|
|
|
|
- Question question = paperDetailUnit.getQuestion();
|
|
|
|
- // 套题序号
|
|
|
|
- if (subQuesList != null && subQuesList.size() > 0) {
|
|
|
|
- question.setQuesBodyWord(replaceQuesBlank(question.getQuesBodyWord(),subNum + 1));
|
|
|
|
- for (Question subQues : subQuesList) {
|
|
|
|
- int curSubNum = ++subNum;
|
|
|
|
- subQues.setQuesBodyWord(setSubQuesNum(subQues.getQuesBodyWord(),curSubNum));
|
|
|
|
- subQues.setQuesAnswerWord(setSubQuesNum(subQues.getQuesAnswerWord(),curSubNum));
|
|
|
|
- subQues.setQuesBodyWord(replaceQuesBlank(subQues.getQuesBodyWord(),curSubNum));
|
|
|
|
- List<QuesOption> subOptionList = subQues.getQuesOptions();
|
|
|
|
- if (subOptionList != null && subOptionList.size() > 0) {
|
|
|
|
- int sub_index = 0;
|
|
|
|
- for (QuesOption quesOption : subOptionList) {
|
|
|
|
- quesOption.setOptionBodyWord(setOptionNum(quesOption.getOptionBodyWord(),getOptionNum(sub_index)));
|
|
|
|
- sub_index++;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- } else {
|
|
|
|
- int curSubNum = ++subNum;
|
|
|
|
- question.setQuesBodyWord(setSubQuesNum(question.getQuesBodyWord(), curSubNum));
|
|
|
|
- question.setQuesAnswerWord(setSubQuesNum(question.getQuesAnswerWord(),curSubNum));
|
|
|
|
- question.setQuesBodyWord(replaceQuesBlank(question.getQuesBodyWord(),curSubNum));
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 替换填空
|
|
|
|
- * 将###替换为下划线_______
|
|
|
|
- * @param wordMl
|
|
|
|
- * @param num
|
|
|
|
- * @return
|
|
|
|
- * @throws Exception
|
|
|
|
- */
|
|
|
|
- protected String replaceQuesBlank(String wordMl,int num) throws Exception {
|
|
|
|
- String tmpStr = DocxProcessUtil.BODY_HEADER + wordMl + DocxProcessUtil.BODY_TAIL;
|
|
|
|
- Body body = (Body)XmlUtils.unmarshalString(tmpStr,Context.jc,Body.class);
|
|
|
|
- List<Object> pList = body.getContent();
|
|
|
|
- int index = 0;
|
|
|
|
- int cur = 0;
|
|
|
|
- Map<Integer,String> curMap = new HashMap<Integer,String>();
|
|
|
|
- for(Object pObj:pList){
|
|
|
|
- if(pObj.getClass().equals(P.class)){
|
|
|
|
- List<Object> pContent = ((P)pObj).getContent();
|
|
|
|
- for(Object rObj:pContent){
|
|
|
|
- if(rObj.getClass().equals(R.class)){
|
|
|
|
- List<Object> rContent = ((R)rObj).getContent();
|
|
|
|
- for(Object tObj:rContent){
|
|
|
|
- if (tObj instanceof JAXBElement)
|
|
|
|
- tObj = ((JAXBElement<?>) tObj).getValue();
|
|
|
|
- if(tObj.getClass().equals(Text.class)){
|
|
|
|
- Text text = (Text)tObj;
|
|
|
|
- String str = text.getValue().trim();
|
|
|
|
- if(str.equals("###")){
|
|
|
|
- text.setValue("______");
|
|
|
|
- }else if(str.equals("(###)")){
|
|
|
|
- text.setValue("(______)");
|
|
|
|
- }else if(str.equals("(###)")){
|
|
|
|
- text.setValue("(______)");
|
|
|
|
- }else if(str.matches("##\\d{1,}##")){
|
|
|
|
- int curNum = num + index;
|
|
|
|
- text.setValue("___"+(curNum)+"___");
|
|
|
|
- index++;
|
|
|
|
- }else if(str.startsWith("#") || str.equals("___")){
|
|
|
|
- curMap.put(cur,str);
|
|
|
|
- text.setValue("");
|
|
|
|
- }else if(str.matches("^\\d{1,}$")){
|
|
|
|
- String preStr = curMap.get(cur - 1);
|
|
|
|
- if(!StringUtils.isEmpty(preStr) && preStr.startsWith("#")){
|
|
|
|
- int curNum = num + index;
|
|
|
|
- text.setValue("___"+(curNum)+"___");
|
|
|
|
- index++;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- cur++;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- StringBuffer pWordMl = new StringBuffer();
|
|
|
|
- for(Object pObj:pList){
|
|
|
|
- if(pObj instanceof P){
|
|
|
|
- pWordMl.append(DocxProcessUtil.formatPWordMl(XmlUtils.marshaltoString(pObj)));
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return pWordMl.toString();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public String getOptionNum(int number){
|
|
|
|
- char optionNum = (char)(65 + number);
|
|
|
|
- return String.valueOf(optionNum);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 获取当前试卷下所有试题WordPkg
|
|
|
|
- * @param id
|
|
|
|
- * @return
|
|
|
|
- */
|
|
|
|
- public List<WordprocessingMLPackage> getPkgList(String id){
|
|
|
|
- Paper paper = paperRepo.findOne(id);
|
|
|
|
- List<WordprocessingMLPackage> wordMLPackages = paperDetailUnitRepo.findByPaper(paper)
|
|
|
|
- .stream().map(PaperDetailUnit::getQuestion).collect(Collectors.toList())
|
|
|
|
- .stream().map(Question::getPkgObj).collect(Collectors.toList());
|
|
|
|
- return wordMLPackages;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 设置题号
|
|
|
|
- * @param quesBodyWordMl
|
|
|
|
- * @param num
|
|
|
|
- * @return
|
|
|
|
- * @throws Exception
|
|
|
|
- */
|
|
|
|
- public String setSubQuesNum(String quesBodyWordMl,int num) throws Exception {
|
|
|
|
- String tmpStr = DocxProcessUtil.BODY_HEADER + quesBodyWordMl + DocxProcessUtil.BODY_TAIL;
|
|
|
|
- Body body = (Body)XmlUtils.unmarshalString(tmpStr,Context.jc,Body.class);
|
|
|
|
- List<Object> pList = body.getContent();
|
|
|
|
- int index = 0;
|
|
|
|
- for(Object pObj:pList){
|
|
|
|
- if(index > 0){
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- P p = (P) pObj;
|
|
|
|
- List<Object> pContent = p.getContent();
|
|
|
|
- R run = new R();
|
|
|
|
- Text text = new Text();
|
|
|
|
- text.setValue(num+". ");
|
|
|
|
- run.getContent().add(text);
|
|
|
|
- pContent.add(0,run);
|
|
|
|
- index++;
|
|
|
|
- }
|
|
|
|
- StringBuffer pWordMl = new StringBuffer();
|
|
|
|
- for(Object pObj:pList){
|
|
|
|
- if(pObj instanceof P){
|
|
|
|
- pWordMl.append(DocxProcessUtil.formatPWordMl(XmlUtils.marshaltoString(pObj)));
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return pWordMl.toString();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 设置选项号
|
|
|
|
- * @param optionWordMl
|
|
|
|
- * @param num
|
|
|
|
- * @return
|
|
|
|
- * @throws Exception
|
|
|
|
- */
|
|
|
|
- public String setOptionNum(String optionWordMl,String num) throws Exception {
|
|
|
|
- String tmpStr = DocxProcessUtil.BODY_HEADER + optionWordMl + DocxProcessUtil.BODY_TAIL;
|
|
|
|
- Body body = (Body)XmlUtils.unmarshalString(tmpStr,Context.jc,Body.class);
|
|
|
|
- List<Object> pList = body.getContent();
|
|
|
|
- int index = 0;
|
|
|
|
- for(Object pObj:pList){
|
|
|
|
- if(index > 0){
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- P p = (P) pObj;
|
|
|
|
- List<Object> pContent = p.getContent();
|
|
|
|
- R run = new R();
|
|
|
|
- Text text = new Text();
|
|
|
|
- text.setValue(num+". ");
|
|
|
|
- run.getContent().add(text);
|
|
|
|
- pContent.add(0,run);
|
|
|
|
- index++;
|
|
|
|
- }
|
|
|
|
- StringBuffer pWordMl = new StringBuffer();
|
|
|
|
- for(Object pObj:pList){
|
|
|
|
- if(pObj instanceof P){
|
|
|
|
- pWordMl.append(DocxProcessUtil.formatPWordMl(XmlUtils.marshaltoString(pObj)));
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return pWordMl.toString();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 当大题下小题分数不是全部一样时,在小题题干后面加上小题的分数
|
|
|
|
- * @param details
|
|
|
|
- * @throws Exception
|
|
|
|
- */
|
|
|
|
- protected void setScore(List<PaperDetailExp> details) throws Exception{
|
|
|
|
- for(PaperDetailExp paperDetailExp:details){
|
|
|
|
- if(!checkPaperDetailUnitScore(paperDetailExp)){
|
|
|
|
- for(PaperDetailUnitExp paperDetailUnit:paperDetailExp.getPaperDetailUnits()){
|
|
|
|
- Question question = paperDetailUnit.getQuestion();
|
|
|
|
- String questionBodyWord = appendScoreToQuestionBody(question.getQuesBodyWord(),paperDetailUnit.getScore());
|
|
|
|
- question.setQuesBodyWord(questionBodyWord);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 在题干上设置分数
|
|
|
|
- * @throws Exception
|
|
|
|
- */
|
|
|
|
- protected String appendScoreToQuestionBody(String quesBodyWordMl,double score) throws Exception{
|
|
|
|
- String tmpStr = DocxProcessUtil.BODY_HEADER + quesBodyWordMl + DocxProcessUtil.BODY_TAIL;
|
|
|
|
- Body body = (Body)XmlUtils.unmarshalString(tmpStr,Context.jc,Body.class);
|
|
|
|
- List<Object> pList = body.getContent();
|
|
|
|
- int index = 0;
|
|
|
|
- for(Object pObj:pList){
|
|
|
|
- if(index < pList.size()-1){
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- P p = (P) pObj;
|
|
|
|
- List<Object> pContent = p.getContent();
|
|
|
|
- R run = new R();
|
|
|
|
- Text text = new Text();
|
|
|
|
- int scoreInt = (int)score;
|
|
|
|
- text.setValue("("+scoreInt+"分)");
|
|
|
|
- run.getContent().add(text);
|
|
|
|
- pContent.add(run);
|
|
|
|
- index++;
|
|
|
|
- }
|
|
|
|
- StringBuffer pWordMl = new StringBuffer();
|
|
|
|
- for(Object pObj:pList){
|
|
|
|
- if(pObj instanceof P){
|
|
|
|
- pWordMl.append(DocxProcessUtil.formatPWordMl(XmlUtils.marshaltoString(pObj)));
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return pWordMl.toString();
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
|
|
+package com.qmth.cqb.paper.service.export;
|
|
|
|
+
|
|
|
|
+import java.math.BigDecimal;
|
|
|
|
+import java.util.ArrayList;
|
|
|
|
+import java.util.HashMap;
|
|
|
|
+import java.util.HashSet;
|
|
|
|
+import java.util.List;
|
|
|
|
+import java.util.Map;
|
|
|
|
+import java.util.Set;
|
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
+
|
|
|
|
+import javax.servlet.http.HttpServletResponse;
|
|
|
|
+import javax.xml.bind.JAXBElement;
|
|
|
|
+
|
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
|
+import org.docx4j.XmlUtils;
|
|
|
|
+import org.docx4j.jaxb.Context;
|
|
|
|
+import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
|
|
|
|
+import org.docx4j.wml.Body;
|
|
|
|
+import org.docx4j.wml.P;
|
|
|
|
+import org.docx4j.wml.R;
|
|
|
|
+import org.docx4j.wml.Text;
|
|
|
|
+import org.slf4j.Logger;
|
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
+
|
|
|
|
+import cn.com.qmth.examcloud.common.dto.core.enums.CourseLevel;
|
|
|
|
+import cn.com.qmth.examcloud.common.dto.question.enums.QuesStructType;
|
|
|
|
+
|
|
|
|
+import com.qmth.cqb.paper.dao.PaperDetailRepo;
|
|
|
|
+import com.qmth.cqb.paper.dao.PaperDetailUnitRepo;
|
|
|
|
+import com.qmth.cqb.paper.dao.PaperRepo;
|
|
|
|
+import com.qmth.cqb.paper.dto.PaperDetailExp;
|
|
|
|
+import com.qmth.cqb.paper.dto.PaperDetailUnitExp;
|
|
|
|
+import com.qmth.cqb.paper.dto.PaperExp;
|
|
|
|
+import com.qmth.cqb.paper.model.Paper;
|
|
|
|
+import com.qmth.cqb.paper.model.PaperDetail;
|
|
|
|
+import com.qmth.cqb.paper.model.PaperDetailUnit;
|
|
|
|
+import com.qmth.cqb.paper.service.PaperService;
|
|
|
|
+import com.qmth.cqb.question.dao.QuesRepo;
|
|
|
|
+import com.qmth.cqb.question.model.QuesOption;
|
|
|
|
+import com.qmth.cqb.question.model.Question;
|
|
|
|
+import com.qmth.cqb.utils.BeanCopierUtil;
|
|
|
|
+import com.qmth.cqb.utils.CommonUtils;
|
|
|
|
+import com.qmth.cqb.utils.exception.PaperException;
|
|
|
|
+import com.qmth.cqb.utils.word.DocxProcessUtil;
|
|
|
|
+
|
|
|
|
+import freemarker.template.Configuration;
|
|
|
|
+import freemarker.template.Template;
|
|
|
|
+
|
|
|
|
+public abstract class ExportPaperAbstractService {
|
|
|
|
+
|
|
|
|
+ private static final Logger logger = LoggerFactory.getLogger(ExportPaperAbstractService.class);
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ PaperRepo paperRepo;
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ PaperService paperService;
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ PaperDetailRepo paperDetailRepo;
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ PaperDetailUnitRepo paperDetailUnitRepo;
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ QuesRepo quesRepo;
|
|
|
|
+
|
|
|
|
+ private static final String FILL_BLANK_QUESTION_FLAG = "###";
|
|
|
|
+
|
|
|
|
+ public static Configuration CONFIGURATION;
|
|
|
|
+
|
|
|
|
+ public static final String ENCODING = "UTF-8";
|
|
|
|
+
|
|
|
|
+ //陕西师范模板
|
|
|
|
+ protected static Template SXSF_TEMPLATE_PAPER;
|
|
|
|
+ protected static Template SXSF_TEMPLATE_ANSWER;
|
|
|
|
+ //电子科大模板
|
|
|
|
+ protected static Template DZKD_TEMPLATE_PAPER;
|
|
|
|
+ protected static Template DZKD_TEMPLATE_ANSWER;
|
|
|
|
+ //石油大学模板
|
|
|
|
+ //protected static Template SYDX_TEMPLATE_NORMAL;
|
|
|
|
+
|
|
|
|
+ static {
|
|
|
|
+ try {
|
|
|
|
+ CONFIGURATION = new Configuration(Configuration.VERSION_2_3_25);
|
|
|
|
+ // 设置编码
|
|
|
|
+ CONFIGURATION.setDefaultEncoding(ENCODING);
|
|
|
|
+ // 设置ftl模板路径
|
|
|
|
+ CONFIGURATION.setClassForTemplateLoading(DocxProcessUtil.class, "/");
|
|
|
|
+
|
|
|
|
+ SXSF_TEMPLATE_PAPER = CONFIGURATION.getTemplate("sxsf_paper_template.ftl", ENCODING);
|
|
|
|
+ SXSF_TEMPLATE_ANSWER = CONFIGURATION.getTemplate("sxsf_answer_template.ftl", ENCODING);
|
|
|
|
+
|
|
|
|
+ DZKD_TEMPLATE_PAPER = CONFIGURATION.getTemplate("dzkd_paper_template.ftl", ENCODING);
|
|
|
|
+ DZKD_TEMPLATE_ANSWER = CONFIGURATION.getTemplate("dzkd_answer_template.ftl", ENCODING);
|
|
|
|
+
|
|
|
|
+ //SYDX_TEMPLATE_NORMAL = CONFIGURATION.getTemplate("paper_template.ftl", ENCODING);
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 下载试卷
|
|
|
|
+ * @param id
|
|
|
|
+ * @param response
|
|
|
|
+ * @throws Exception
|
|
|
|
+ */
|
|
|
|
+ public abstract void downloadPaper(String paperId, HttpServletResponse response)throws Exception;
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 初始化导出试卷DTO
|
|
|
|
+ *
|
|
|
|
+ * @param id
|
|
|
|
+ * @return
|
|
|
|
+ */
|
|
|
|
+ protected Map<String,Object> initExportPaper(String paperId) throws Exception {
|
|
|
|
+ // 创建返回Map
|
|
|
|
+ Map<String,Object> returnMap = new HashMap<String,Object>();
|
|
|
|
+ // 获取paper
|
|
|
|
+ Paper paper = paperRepo.findOne(paperId);
|
|
|
|
+ paperService.formatPaper(paper, null);
|
|
|
|
+ if (paper == null) {
|
|
|
|
+ throw new PaperException("该试卷不存在");
|
|
|
|
+ }
|
|
|
|
+ // 创建paperDto
|
|
|
|
+ PaperExp paperExp = BeanCopierUtil.copyProperties(paper, PaperExp.class);
|
|
|
|
+ paperExp.setCourseLevel(paper.getLevel()==null?CourseLevel.ALL.name():paper.getLevel().name());
|
|
|
|
+ List<PaperDetailExp> objectiveDetails = new ArrayList<PaperDetailExp>();// 客观题
|
|
|
|
+ List<PaperDetailExp> subjectiveDetails = new ArrayList<PaperDetailExp>();// 主观题
|
|
|
|
+ double objectiveScore = 0;
|
|
|
|
+ double subjectiveScore = 0;
|
|
|
|
+ paperExp.setTitle(CommonUtils.PAPER_TITLE);
|
|
|
|
+ paperExp.setSubTitle(CommonUtils.PAPER_SUB_TITLE);
|
|
|
|
+ // 获取大题
|
|
|
|
+ List<PaperDetail> paperDetails = paperDetailRepo.findByPaper(paper);
|
|
|
|
+ int objectNumber = 1;// 客观题大题序号
|
|
|
|
+ int objetcUnitSum = 0;
|
|
|
|
+ for (int i = 0; i < paperDetails.size(); i++) {
|
|
|
|
+ PaperDetailExp paperDetailExp = BeanCopierUtil.copyProperties(paperDetails.get(i), PaperDetailExp.class);
|
|
|
|
+ List<PaperDetailUnit> paperDetailUnits = paperDetailUnitRepo.findByPaperDetail(paperDetails.get(i));
|
|
|
|
+ // 把大题分类 :客观题和主观题
|
|
|
|
+ List<PaperDetailUnitExp> paperDetailUnitExps = BeanCopierUtil.copyPropertiesOfList(paperDetailUnits,PaperDetailUnitExp.class);
|
|
|
|
+ // 选择题,套题下选择题 选项顺序重新排列
|
|
|
|
+ paperService.reorderChoicequestionOption(paperDetailUnitExps);
|
|
|
|
+ paperDetailExp.setPaperDetailUnits(paperDetailUnitExps);
|
|
|
|
+ boolean hasTextAnswer = false;// 判断主观题
|
|
|
|
+ if (paperDetailUnits.get(0).getQuestionType() == QuesStructType.NESTED_ANSWER_QUESTION) {
|
|
|
|
+ for (Question ques : paperDetailUnits.get(0).getQuestion().getSubQuestions()) {
|
|
|
|
+ if (ques.getQuestionType() == QuesStructType.TEXT_ANSWER_QUESTION) {
|
|
|
|
+ hasTextAnswer = true;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ } else if (paperDetailUnits.get(0).getQuestionType() == QuesStructType.TEXT_ANSWER_QUESTION
|
|
|
|
+ ||paperDetailUnits.get(0).getQuestionType() == QuesStructType.FILL_BLANK_QUESTION) {
|
|
|
|
+ hasTextAnswer = true;
|
|
|
|
+ }
|
|
|
|
+ if (hasTextAnswer) {
|
|
|
|
+ subjectiveDetails.add(paperDetailExp);
|
|
|
|
+ subjectiveScore += paperDetailExp.getScore();
|
|
|
|
+ } else {
|
|
|
|
+ objectiveDetails.add(paperDetailExp);
|
|
|
|
+ paperDetailExp.setNumber(objectNumber);
|
|
|
|
+ paperDetailExp.setCnNum(CommonUtils.toCHNum(objectNumber));
|
|
|
|
+ objectiveScore += paperDetailExp.getScore();
|
|
|
|
+ objetcUnitSum += paperDetailExp.getUnitCount();
|
|
|
|
+ objectNumber++;
|
|
|
|
+ }
|
|
|
|
+ setExpTitle(paperDetailExp);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ paperExp.setObjectiveDetails(objectiveDetails);
|
|
|
|
+ paperExp.setSubjectiveDetails(subjectiveDetails);
|
|
|
|
+ paperExp.setObjectiveScore(objectiveScore);
|
|
|
|
+ paperExp.setSubjectiveScore(subjectiveScore);
|
|
|
|
+ if (objectiveDetails.size() > 0) {
|
|
|
|
+ setUnitExpNumber(objectiveDetails, 0);
|
|
|
|
+ setScore(objectiveDetails);
|
|
|
|
+ }
|
|
|
|
+ if (subjectiveDetails.size() > 0) {
|
|
|
|
+ for (PaperDetailExp subDetail : subjectiveDetails) {
|
|
|
|
+ subDetail.setNumber(objectNumber);
|
|
|
|
+ subDetail.setCnNum(CommonUtils.toCHNum(objectNumber));
|
|
|
|
+ objectNumber++;
|
|
|
|
+ }
|
|
|
|
+ setUnitExpNumber(subjectiveDetails, objetcUnitSum);
|
|
|
|
+ setScore(subjectiveDetails);
|
|
|
|
+ }
|
|
|
|
+ returnMap.put("paper", paperExp);
|
|
|
|
+ returnMap.put("fileName", paperExp.getName());
|
|
|
|
+
|
|
|
|
+ return returnMap;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ protected void setExpTitle(PaperDetailExp paperDetailExp) {
|
|
|
|
+ String title = "";
|
|
|
|
+ String totalScore = BigDecimal.valueOf(paperDetailExp.getScore()).stripTrailingZeros().toPlainString();
|
|
|
|
+ String unitScore = BigDecimal.valueOf(paperDetailExp.getPaperDetailUnits().get(0).getScore()).stripTrailingZeros().toPlainString();
|
|
|
|
+ QuesStructType type = paperDetailExp.getPaperDetailUnits().get(0).getQuestionType();
|
|
|
|
+ String scoreString = checkPaperDetailUnitScore(paperDetailExp) ? "每小题"+ unitScore + "分" : "";
|
|
|
|
+ if (type == QuesStructType.SINGLE_ANSWER_QUESTION) {
|
|
|
|
+ paperDetailExp.setName("单项选择题");
|
|
|
|
+ title = "(本大题共" + paperDetailExp.getUnitCount() + "小题,"
|
|
|
|
+ + scoreString + "共" + totalScore + "分)。"
|
|
|
|
+ + "在每小题列出的四个备选中只有一个符合题目要求的,请将其选出并将“答题卡”的相应代码涂黑,错涂、多涂或未涂均无分";
|
|
|
|
+ } else if (type == QuesStructType.BOOL_ANSWER_QUESTION) {
|
|
|
|
+ paperDetailExp.setName("判断题");
|
|
|
|
+ title = "(本大题共" + paperDetailExp.getUnitCount() + "小题,"+ scoreString + "共" + totalScore+ "分。正确的填涂A、错误填涂B。错涂、多涂或未涂均无分)";
|
|
|
|
+ } else if (type == QuesStructType.FILL_BLANK_QUESTION) {
|
|
|
|
+ paperDetailExp.setName("填空题");
|
|
|
|
+ int blankNum = 0;
|
|
|
|
+ for (PaperDetailUnitExp unit:paperDetailExp.getPaperDetailUnits()){
|
|
|
|
+ String tempStr = unit.getQuestion().getQuesBody().replaceAll(FILL_BLANK_QUESTION_FLAG, "");
|
|
|
|
+ int lenTimes = (unit.getQuestion().getQuesBody().length() - tempStr.length()) / FILL_BLANK_QUESTION_FLAG.length();// 出现的次数
|
|
|
|
+ blankNum += lenTimes;
|
|
|
|
+ }
|
|
|
|
+ title = "(本大题共"+blankNum+"个空格,将每空答在答题卡 “1—" +blankNum+"”相应的序号上。"+"共"+totalScore + "分)";
|
|
|
|
+ } else {
|
|
|
|
+ title = "(本大题共"+paperDetailExp.getUnitCount()+"小题,"+scoreString+"共"+totalScore+"分)";
|
|
|
|
+ }
|
|
|
|
+ paperDetailExp.setTitle(title);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 校验大题下的小题分数是不是一样
|
|
|
|
+ *
|
|
|
|
+ * @param paperDetailExp
|
|
|
|
+ * @return
|
|
|
|
+ */
|
|
|
|
+ protected boolean checkPaperDetailUnitScore(PaperDetailExp paperDetailExp) {
|
|
|
|
+ List<PaperDetailUnitExp> paperDetailUnitExps = paperDetailExp.getPaperDetailUnits();
|
|
|
|
+ Set<Double> scoreSet = new HashSet<Double>();
|
|
|
|
+ for (PaperDetailUnitExp unitExp : paperDetailUnitExps) {
|
|
|
|
+ scoreSet.add(unitExp.getScore());
|
|
|
|
+ }
|
|
|
|
+ return scoreSet.size() == 1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ protected void setUnitExpNumber(List<PaperDetailExp> paperDetails,int startIndxt) throws Exception {
|
|
|
|
+ int subNum = startIndxt;
|
|
|
|
+ for (PaperDetailExp paperDetail : paperDetails) {
|
|
|
|
+ for (PaperDetailUnitExp paperDetailUnit : paperDetail.getPaperDetailUnits()) {
|
|
|
|
+ List<QuesOption> optionList = paperDetailUnit.getQuestion().getQuesOptions();
|
|
|
|
+ if (optionList != null && optionList.size() > 0) {
|
|
|
|
+ int index = 0;
|
|
|
|
+ for (QuesOption quesOption : optionList) {
|
|
|
|
+ quesOption.setOptionBodyWord(setOptionNum(quesOption.getOptionBodyWord(),getOptionNum(index)));
|
|
|
|
+ index++;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ List<Question> subQuesList = paperDetailUnit.getQuestion().getSubQuestions();
|
|
|
|
+ Question question = paperDetailUnit.getQuestion();
|
|
|
|
+ // 套题序号
|
|
|
|
+ if (subQuesList != null && subQuesList.size() > 0) {
|
|
|
|
+ question.setQuesBodyWord(replaceQuesBlank(question.getQuesBodyWord(),subNum + 1));
|
|
|
|
+ for (Question subQues : subQuesList) {
|
|
|
|
+ int curSubNum = ++subNum;
|
|
|
|
+ subQues.setQuesBodyWord(setSubQuesNum(subQues.getQuesBodyWord(),curSubNum));
|
|
|
|
+ subQues.setQuesAnswerWord(setSubQuesNum(subQues.getQuesAnswerWord(),curSubNum));
|
|
|
|
+ subQues.setQuesBodyWord(replaceQuesBlank(subQues.getQuesBodyWord(),curSubNum));
|
|
|
|
+ List<QuesOption> subOptionList = subQues.getQuesOptions();
|
|
|
|
+ if (subOptionList != null && subOptionList.size() > 0) {
|
|
|
|
+ int sub_index = 0;
|
|
|
|
+ for (QuesOption quesOption : subOptionList) {
|
|
|
|
+ quesOption.setOptionBodyWord(setOptionNum(quesOption.getOptionBodyWord(),getOptionNum(sub_index)));
|
|
|
|
+ sub_index++;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ int curSubNum = ++subNum;
|
|
|
|
+ question.setQuesBodyWord(setSubQuesNum(question.getQuesBodyWord(), curSubNum));
|
|
|
|
+ question.setQuesAnswerWord(setSubQuesNum(question.getQuesAnswerWord(),curSubNum));
|
|
|
|
+ question.setQuesBodyWord(replaceQuesBlank(question.getQuesBodyWord(),curSubNum));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 替换填空
|
|
|
|
+ * 将###替换为下划线_______
|
|
|
|
+ * @param wordMl
|
|
|
|
+ * @param num
|
|
|
|
+ * @return
|
|
|
|
+ * @throws Exception
|
|
|
|
+ */
|
|
|
|
+ protected String replaceQuesBlank(String wordMl,int num) throws Exception {
|
|
|
|
+ String tmpStr = DocxProcessUtil.BODY_HEADER + wordMl + DocxProcessUtil.BODY_TAIL;
|
|
|
|
+ Body body = (Body)XmlUtils.unmarshalString(tmpStr,Context.jc,Body.class);
|
|
|
|
+ List<Object> pList = body.getContent();
|
|
|
|
+ int index = 0;
|
|
|
|
+ int cur = 0;
|
|
|
|
+ Map<Integer,String> curMap = new HashMap<Integer,String>();
|
|
|
|
+ for(Object pObj:pList){
|
|
|
|
+ if(pObj.getClass().equals(P.class)){
|
|
|
|
+ List<Object> pContent = ((P)pObj).getContent();
|
|
|
|
+ for(Object rObj:pContent){
|
|
|
|
+ if(rObj.getClass().equals(R.class)){
|
|
|
|
+ List<Object> rContent = ((R)rObj).getContent();
|
|
|
|
+ for(Object tObj:rContent){
|
|
|
|
+ if (tObj instanceof JAXBElement)
|
|
|
|
+ tObj = ((JAXBElement<?>) tObj).getValue();
|
|
|
|
+ if(tObj.getClass().equals(Text.class)){
|
|
|
|
+ Text text = (Text)tObj;
|
|
|
|
+ String str = text.getValue().trim();
|
|
|
|
+ if(str.equals("###")){
|
|
|
|
+ text.setValue("______");
|
|
|
|
+ }else if(str.equals("(###)")){
|
|
|
|
+ text.setValue("(______)");
|
|
|
|
+ }else if(str.equals("(###)")){
|
|
|
|
+ text.setValue("(______)");
|
|
|
|
+ }else if(str.matches("##\\d{1,}##")){
|
|
|
|
+ int curNum = num + index;
|
|
|
|
+ text.setValue("___"+(curNum)+"___");
|
|
|
|
+ index++;
|
|
|
|
+ }else if(str.startsWith("#") || str.equals("___")){
|
|
|
|
+ curMap.put(cur,str);
|
|
|
|
+ text.setValue("");
|
|
|
|
+ }else if(str.matches("^\\d{1,}$")){
|
|
|
|
+ String preStr = curMap.get(cur - 1);
|
|
|
|
+ if(!StringUtils.isEmpty(preStr) && preStr.startsWith("#")){
|
|
|
|
+ int curNum = num + index;
|
|
|
|
+ text.setValue("___"+(curNum)+"___");
|
|
|
|
+ index++;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ cur++;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ StringBuffer pWordMl = new StringBuffer();
|
|
|
|
+ for(Object pObj:pList){
|
|
|
|
+ if(pObj instanceof P){
|
|
|
|
+ pWordMl.append(DocxProcessUtil.formatPWordMl(XmlUtils.marshaltoString(pObj)));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return pWordMl.toString();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public String getOptionNum(int number){
|
|
|
|
+ char optionNum = (char)(65 + number);
|
|
|
|
+ return String.valueOf(optionNum);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 获取当前试卷下所有试题WordPkg
|
|
|
|
+ * @param id
|
|
|
|
+ * @return
|
|
|
|
+ */
|
|
|
|
+ public List<WordprocessingMLPackage> getPkgList(String id){
|
|
|
|
+ Paper paper = paperRepo.findOne(id);
|
|
|
|
+ List<WordprocessingMLPackage> wordMLPackages = paperDetailUnitRepo.findByPaper(paper)
|
|
|
|
+ .stream().map(PaperDetailUnit::getQuestion).collect(Collectors.toList())
|
|
|
|
+ .stream().map(Question::getPkgObj).collect(Collectors.toList());
|
|
|
|
+ return wordMLPackages;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 设置题号
|
|
|
|
+ * @param quesBodyWordMl
|
|
|
|
+ * @param num
|
|
|
|
+ * @return
|
|
|
|
+ * @throws Exception
|
|
|
|
+ */
|
|
|
|
+ public String setSubQuesNum(String quesBodyWordMl,int num) throws Exception {
|
|
|
|
+ String tmpStr = DocxProcessUtil.BODY_HEADER + quesBodyWordMl + DocxProcessUtil.BODY_TAIL;
|
|
|
|
+ Body body = (Body)XmlUtils.unmarshalString(tmpStr,Context.jc,Body.class);
|
|
|
|
+ List<Object> pList = body.getContent();
|
|
|
|
+ int index = 0;
|
|
|
|
+ for(Object pObj:pList){
|
|
|
|
+ if(index > 0){
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ P p = (P) pObj;
|
|
|
|
+ List<Object> pContent = p.getContent();
|
|
|
|
+ R run = new R();
|
|
|
|
+ Text text = new Text();
|
|
|
|
+ text.setValue(num+". ");
|
|
|
|
+ run.getContent().add(text);
|
|
|
|
+ pContent.add(0,run);
|
|
|
|
+ index++;
|
|
|
|
+ }
|
|
|
|
+ StringBuffer pWordMl = new StringBuffer();
|
|
|
|
+ for(Object pObj:pList){
|
|
|
|
+ if(pObj instanceof P){
|
|
|
|
+ pWordMl.append(DocxProcessUtil.formatPWordMl(XmlUtils.marshaltoString(pObj)));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return pWordMl.toString();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 设置选项号
|
|
|
|
+ * @param optionWordMl
|
|
|
|
+ * @param num
|
|
|
|
+ * @return
|
|
|
|
+ * @throws Exception
|
|
|
|
+ */
|
|
|
|
+ public String setOptionNum(String optionWordMl,String num) throws Exception {
|
|
|
|
+ String tmpStr = DocxProcessUtil.BODY_HEADER + optionWordMl + DocxProcessUtil.BODY_TAIL;
|
|
|
|
+ Body body = (Body)XmlUtils.unmarshalString(tmpStr,Context.jc,Body.class);
|
|
|
|
+ List<Object> pList = body.getContent();
|
|
|
|
+ int index = 0;
|
|
|
|
+ for(Object pObj:pList){
|
|
|
|
+ if(index > 0){
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ P p = (P) pObj;
|
|
|
|
+ List<Object> pContent = p.getContent();
|
|
|
|
+ R run = new R();
|
|
|
|
+ Text text = new Text();
|
|
|
|
+ text.setValue(num+". ");
|
|
|
|
+ run.getContent().add(text);
|
|
|
|
+ pContent.add(0,run);
|
|
|
|
+ index++;
|
|
|
|
+ }
|
|
|
|
+ StringBuffer pWordMl = new StringBuffer();
|
|
|
|
+ for(Object pObj:pList){
|
|
|
|
+ if(pObj instanceof P){
|
|
|
|
+ pWordMl.append(DocxProcessUtil.formatPWordMl(XmlUtils.marshaltoString(pObj)));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return pWordMl.toString();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 当大题下小题分数不是全部一样时,在小题题干后面加上小题的分数
|
|
|
|
+ * @param details
|
|
|
|
+ * @throws Exception
|
|
|
|
+ */
|
|
|
|
+ protected void setScore(List<PaperDetailExp> details) throws Exception{
|
|
|
|
+ for(PaperDetailExp paperDetailExp:details){
|
|
|
|
+ if(!checkPaperDetailUnitScore(paperDetailExp)){
|
|
|
|
+ for(PaperDetailUnitExp paperDetailUnit:paperDetailExp.getPaperDetailUnits()){
|
|
|
|
+ Question question = paperDetailUnit.getQuestion();
|
|
|
|
+ String questionBodyWord = appendScoreToQuestionBody(question.getQuesBodyWord(),paperDetailUnit.getScore());
|
|
|
|
+ question.setQuesBodyWord(questionBodyWord);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 在题干上设置分数
|
|
|
|
+ * @throws Exception
|
|
|
|
+ */
|
|
|
|
+ protected String appendScoreToQuestionBody(String quesBodyWordMl,double score) throws Exception{
|
|
|
|
+ String tmpStr = DocxProcessUtil.BODY_HEADER + quesBodyWordMl + DocxProcessUtil.BODY_TAIL;
|
|
|
|
+ Body body = (Body)XmlUtils.unmarshalString(tmpStr,Context.jc,Body.class);
|
|
|
|
+ List<Object> pList = body.getContent();
|
|
|
|
+ int index = 0;
|
|
|
|
+ for(Object pObj:pList){
|
|
|
|
+ if(index < pList.size()-1){
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ P p = (P) pObj;
|
|
|
|
+ List<Object> pContent = p.getContent();
|
|
|
|
+ R run = new R();
|
|
|
|
+ Text text = new Text();
|
|
|
|
+ int scoreInt = (int)score;
|
|
|
|
+ text.setValue("("+scoreInt+"分)");
|
|
|
|
+ run.getContent().add(text);
|
|
|
|
+ pContent.add(run);
|
|
|
|
+ index++;
|
|
|
|
+ }
|
|
|
|
+ StringBuffer pWordMl = new StringBuffer();
|
|
|
|
+ for(Object pObj:pList){
|
|
|
|
+ if(pObj instanceof P){
|
|
|
|
+ pWordMl.append(DocxProcessUtil.formatPWordMl(XmlUtils.marshaltoString(pObj)));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return pWordMl.toString();
|
|
|
|
+ }
|
|
|
|
+}
|