|
@@ -0,0 +1,2882 @@
|
|
|
+package com.qmth.qrzk.repository.pager.service;
|
|
|
+
|
|
|
+import java.io.ByteArrayInputStream;
|
|
|
+import java.io.File;
|
|
|
+import java.io.FileInputStream;
|
|
|
+import java.io.FileOutputStream;
|
|
|
+import java.io.InputStream;
|
|
|
+import java.io.UnsupportedEncodingException;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.Collections;
|
|
|
+import java.util.Comparator;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.Iterator;
|
|
|
+import java.util.LinkedList;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.UUID;
|
|
|
+
|
|
|
+import org.apache.commons.io.IOUtils;
|
|
|
+import org.apache.commons.lang.StringUtils;
|
|
|
+import org.apache.log4j.Logger;
|
|
|
+import org.dom4j.Attribute;
|
|
|
+import org.dom4j.Document;
|
|
|
+import org.dom4j.DocumentException;
|
|
|
+import org.dom4j.DocumentHelper;
|
|
|
+import org.dom4j.Element;
|
|
|
+import org.dom4j.io.SAXReader;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+
|
|
|
+import com.qmth.qrzk.repository.common.base.BaseDao;
|
|
|
+import com.qmth.qrzk.repository.exception.BizException;
|
|
|
+import com.qmth.qrzk.repository.pager.model.PagerConstruct;
|
|
|
+import com.qmth.qrzk.repository.pager.model.PagerConstructDetail;
|
|
|
+import com.qmth.qrzk.repository.pager.model.PagerConstructQtype;
|
|
|
+import com.qmth.qrzk.repository.service.query.PagerQueryParams;
|
|
|
+import com.qmth.qrzk.repository.task.PaperTask;
|
|
|
+import com.qmth.qrzk.repository.user.model.Attachment;
|
|
|
+import com.qmth.qrzk.repository.user.model.OperLog;
|
|
|
+import com.qmth.qrzk.repository.user.model.Question;
|
|
|
+import com.qmth.qrzk.repository.user.model.QuestionOption;
|
|
|
+import com.qmth.qrzk.repository.user.model.User;
|
|
|
+import com.qmth.qrzk.repository.user.service.impl.AttachmentService;
|
|
|
+import com.qmth.qrzk.repository.utils.Consts;
|
|
|
+import com.qmth.qrzk.repository.utils.DateHelper;
|
|
|
+import com.qmth.qrzk.repository.utils.General;
|
|
|
+import com.qmth.qrzk.repository.utils.ParamUtils;
|
|
|
+import com.qmth.qrzk.repository.utils.docx.DocxReader;
|
|
|
+import com.qmth.qrzk.repository.utils.docx.ResourceInfo;
|
|
|
+
|
|
|
+@Service
|
|
|
+public class ZujuanService {
|
|
|
+
|
|
|
+ private final static Logger log = Logger.getLogger(ZujuanService.class);
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private BaseDao dao;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private AttachmentService attachmentService;
|
|
|
+
|
|
|
+ public List<PagerConstruct> queryPagers(PagerQueryParams params) {
|
|
|
+ return dao.getPagerList("queryPagerConstructs", params);
|
|
|
+ }
|
|
|
+
|
|
|
+ public PagerConstruct findById(int paperId) {
|
|
|
+ return dao.getObject("findPagerConstructById", paperId);
|
|
|
+ }
|
|
|
+
|
|
|
+ public void updatePagerConstruct(PagerConstruct pager) {
|
|
|
+ dao.update("updatePagerConstruct", pager);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取完整的试卷信息,包括题型列表,题型下面的试题信息
|
|
|
+ *
|
|
|
+ * @param courseId
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public PagerConstruct getOriginalWholePaperInfo(int paperId) {
|
|
|
+ PagerConstruct paper = findById(paperId);
|
|
|
+ if (paper == null) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ List<PagerConstructQtype> qtypes = dao.getList("findPagerConstructQtypesByPaperId", paperId);
|
|
|
+ paper.setQtypeList(qtypes);
|
|
|
+ return paper;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取完整的试卷信息,包括题型列表,题型下面的试题信息,并把试题里面的Word数据转换成Html数据
|
|
|
+ *
|
|
|
+ * @param courseId
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public PagerConstruct getWholePaperInfoForShow(int paperId) {
|
|
|
+ PagerConstruct paper = findById(paperId);
|
|
|
+ if (paper == null) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ List<PagerConstructQtype> qtypes = dao.getList("findPagerConstructQtypesByPaperId", paperId);
|
|
|
+ for (PagerConstructQtype qt : qtypes) {
|
|
|
+ for (PagerConstructDetail pcd : qt.getConstructDetails()) {
|
|
|
+ Question ques = pcd.getQuestion();
|
|
|
+ if (ques != null) {
|
|
|
+ General.quesWordToHtmlForShow(ques);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ paper.setQtypeList(qtypes);
|
|
|
+ return paper;
|
|
|
+ }
|
|
|
+
|
|
|
+ public List<PagerConstruct> getPaperListByIdArr(int[] idArr) {
|
|
|
+ List<PagerConstruct> list = new ArrayList<PagerConstruct>();
|
|
|
+ for (int id : idArr) {
|
|
|
+ PagerConstruct paper = getWholePaperInfoForShow(id);
|
|
|
+ if (paper != null) {
|
|
|
+ list.add(paper);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return list;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void delUserPagerByUserId(int user_id) {
|
|
|
+ dao.delete("delUserPagerByUserId", user_id);
|
|
|
+ }
|
|
|
+
|
|
|
+ public void sortSj(int paperId, User curUser) {
|
|
|
+ PagerConstruct paper = findById(paperId);
|
|
|
+ if (paper == null) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ List<PagerConstructQtype> qtypes = dao.getList("findPagerConstructQtypesByPaperId", paperId);
|
|
|
+ for (PagerConstructQtype qt : qtypes) {
|
|
|
+ Collections.sort(qt.getConstructDetails(), new Comparator<PagerConstructDetail>() {
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public int compare(PagerConstructDetail o1, PagerConstructDetail o2) {
|
|
|
+ if (o1.getQuestion() == null && o2.getQuestion() == null) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ if (o1.getQuestion() == null) {
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ if (o2.getQuestion() == null) {
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+ String diff1 = General.convertNullToEmpty(o1.getQuestion().getEstimateDifficultyCode());
|
|
|
+ String chapter1 = General.convertNullToEmpty(o1.getQuestion().getChapter());
|
|
|
+
|
|
|
+ String diff2 = General.convertNullToEmpty(o2.getQuestion().getEstimateDifficultyCode());
|
|
|
+ String chapter2 = General.convertNullToEmpty(o2.getQuestion().getChapter());
|
|
|
+ if (diff1.equals(diff2)) {
|
|
|
+ return chapter1.compareTo(chapter2);
|
|
|
+ } else {
|
|
|
+ return diff1.compareTo(diff2);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ for (int i = 0; i < qt.getConstructDetails().size(); i++) {
|
|
|
+ PagerConstructDetail detail = qt.getConstructDetails().get(i);
|
|
|
+ detail.setSortNo(i + 1);
|
|
|
+ detail.setUpdatedBy(curUser.getId());
|
|
|
+ dao.update("updatePagerConstructDetail", detail);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public List<PagerConstruct> findPagersByUserId(int userId) {
|
|
|
+ return dao.getList("findPagerByUserId", userId);
|
|
|
+ }
|
|
|
+
|
|
|
+ public void submitAudit(int paperId, int userId) {
|
|
|
+ PagerConstruct paper = new PagerConstruct();
|
|
|
+ paper.setId(paperId);
|
|
|
+ paper.setStatus(Consts.PaperStatus.TOAPPROVE);
|
|
|
+ paper.setUpdatedBy(userId);
|
|
|
+ dao.update("updatePagerConstruct", paper);
|
|
|
+
|
|
|
+ OperLog ol = new OperLog();
|
|
|
+ ol.setObjId(paperId);
|
|
|
+ ol.setObjType(Consts.OperLogObjType.PagerConstruct);
|
|
|
+ ol.setOperCode("提交审核");
|
|
|
+ ol.setCreatedBy(userId);
|
|
|
+ dao.insert("addOperLog", ol);
|
|
|
+ }
|
|
|
+
|
|
|
+ public void saveAudit(int paperId, int userId, int auditResult, String remark) {
|
|
|
+ PagerConstruct paper = new PagerConstruct();
|
|
|
+ paper.setId(paperId);
|
|
|
+ paper.setStatus(auditResult);
|
|
|
+ paper.setUpdatedBy(userId);
|
|
|
+ dao.update("updatePagerConstruct", paper);
|
|
|
+
|
|
|
+ OperLog ol = new OperLog();
|
|
|
+ ol.setObjId(paperId);
|
|
|
+ ol.setObjType(Consts.OperLogObjType.PagerConstruct);
|
|
|
+ ol.setOperCode((auditResult == Consts.PaperStatus.APPROVED) ? "审核通过" : "审核拒绝");
|
|
|
+ ol.setRemark(remark);
|
|
|
+ ol.setCreatedBy(userId);
|
|
|
+ dao.insert("addOperLog", ol);
|
|
|
+ }
|
|
|
+
|
|
|
+ public List<OperLog> getAuditLogs(int paperId) {
|
|
|
+ Map<String, Object> param = new HashMap<String, Object>();
|
|
|
+ param.put("objId", paperId);
|
|
|
+ param.put("objType", Consts.OperLogObjType.PagerConstruct);
|
|
|
+ List<OperLog> list = dao.getList("queryOperLogsByObjIdAndType", param);
|
|
|
+ return list;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void deletePaper(int paperId) {
|
|
|
+ dao.delete("deletePaperDetailsByPaperId", paperId);
|
|
|
+ dao.delete("deletePaperQtypesByPaperId", paperId);
|
|
|
+ // 还要删除WordHistory及附件
|
|
|
+ dao.delete("deletePaperById", paperId);
|
|
|
+ }
|
|
|
+
|
|
|
+ private static String toQuesNumStr(int quesNum) {
|
|
|
+ String numStr = quesNum + "";
|
|
|
+ if (numStr.length() == 1) {
|
|
|
+ numStr = " " + quesNum;
|
|
|
+ }
|
|
|
+ return numStr;
|
|
|
+ }
|
|
|
+
|
|
|
+ public Attachment generalAnswerFileIntoAtt(int paperId,User curUser) throws BizException{
|
|
|
+ PagerConstruct paper = getOriginalWholePaperInfo(paperId);
|
|
|
+ File answerFile = generalAnswerFile(paper);
|
|
|
+ File newFile = General.newAttFile();
|
|
|
+ answerFile.renameTo(newFile);
|
|
|
+ Attachment att = new Attachment();
|
|
|
+ att.setCreatedBy(curUser.getId());
|
|
|
+ att.setOriginalName(paper.getName() + "N" + ".docx");
|
|
|
+ att.setCurName(newFile.getName());
|
|
|
+ att.setFileLength(newFile.length());
|
|
|
+ att.setStorePath(newFile.getAbsolutePath());
|
|
|
+ att.setStatus(Consts.AttachmentStatus.DRAFT);
|
|
|
+ dao.insert("addAttachment", att);
|
|
|
+ //更新试卷中的word附件
|
|
|
+ int oldAttId = paper.getLastAnswerWord() == null ? 0 : paper.getLastAnswerWord().intValue();
|
|
|
+ Attachment newAtt = attachmentService.getAttachmentByAttr(newFile.getAbsolutePath());
|
|
|
+ int newAttId = newAtt == null ? 0 : newAtt.getId().intValue();
|
|
|
+ if (oldAttId == 0) {
|
|
|
+ paper.setLastAnswerWord(newAttId);
|
|
|
+ } else {
|
|
|
+ Attachment oldAtt = attachmentService.getAttachmentById(oldAttId);
|
|
|
+ if (oldAtt != null) {
|
|
|
+ oldAtt.setStatus("DELETEED");
|
|
|
+ dao.update("updateAttachment", att);
|
|
|
+ }
|
|
|
+ paper.setLastAnswerWord(newAttId);
|
|
|
+ }
|
|
|
+ if (newAttId != 0) {
|
|
|
+ dao.update("updatePagerConstruct", paper);
|
|
|
+ }
|
|
|
+ return att;
|
|
|
+ }
|
|
|
+
|
|
|
+ public File generalAnswerFile(PagerConstruct paper) throws BizException {
|
|
|
+ File newDocx = null;
|
|
|
+ DocxReader templetDocxReader = null;
|
|
|
+ Map<String, ResourceInfo> needToUpdate = new HashMap<String, ResourceInfo>();
|
|
|
+ try {
|
|
|
+ {// 拷贝一份模板文件到临时文件夹里面
|
|
|
+ FileOutputStream fos = null;
|
|
|
+ InputStream is = null;
|
|
|
+ try {
|
|
|
+ newDocx = new File(ParamUtils.TemporaryDirPath, UUID.randomUUID().toString().replace("-", ""));
|
|
|
+ fos = new FileOutputStream(newDocx);
|
|
|
+ is = ZujuanService.class.getResourceAsStream("/paperTmps/answerTmp1.docx");
|
|
|
+ IOUtils.copyLarge(is, fos);
|
|
|
+ fos.flush();
|
|
|
+ } finally {
|
|
|
+ General.close(is);
|
|
|
+ General.close(fos);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ templetDocxReader = new DocxReader(newDocx);
|
|
|
+ templetDocxReader.doRead();
|
|
|
+ {
|
|
|
+ List<ResourceInfo> headersAndFooters = new ArrayList<ResourceInfo>();
|
|
|
+ headersAndFooters.addAll(templetDocxReader.getHeaders());
|
|
|
+ headersAndFooters.addAll(templetDocxReader.getFooters());
|
|
|
+ for (ResourceInfo info : headersAndFooters) {
|
|
|
+ FileOutputStream fos = null;
|
|
|
+ InputStream is = null;
|
|
|
+ try {
|
|
|
+ is = new FileInputStream(info.getFile());
|
|
|
+ String docStr = IOUtils.toString(is, "UTF-8")
|
|
|
+ .replace("##试卷名称##", General.XMLEncode(paper.getName()))
|
|
|
+ .replace("##试卷题头##", General.XMLEncode(paper.getHead()))
|
|
|
+ .replace("##课程名称##", General.XMLEncode(paper.getSkeleton().getCourse().getName()))
|
|
|
+ .replace("##课程代码##", General.XMLEncode(paper.getSkeleton().getCourse().getCode()));
|
|
|
+ fos = new FileOutputStream(info.getFile(), false);
|
|
|
+ IOUtils.write(docStr, fos, "UTF-8");
|
|
|
+ } finally {
|
|
|
+ General.close(is);
|
|
|
+ General.close(fos);
|
|
|
+ }
|
|
|
+ needToUpdate.put(info.getPathInZip(), info);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ {
|
|
|
+ needToUpdate.put(templetDocxReader.getDocumentInfo().getPathInZip(),
|
|
|
+ templetDocxReader.getDocumentInfo());
|
|
|
+ File document = templetDocxReader.getDocumentInfo().getFile();
|
|
|
+ FileOutputStream fos = null;
|
|
|
+ InputStream is = null;
|
|
|
+ try {
|
|
|
+ is = new FileInputStream(document);
|
|
|
+ String docStr = IOUtils.toString(is, "UTF-8")
|
|
|
+ .replace("##试卷名称##", General.XMLEncode(paper.getName()))
|
|
|
+ .replace("##试卷题头##", General.XMLEncode(paper.getHead()))
|
|
|
+ .replace("##课程名称##", General.XMLEncode(paper.getSkeleton().getCourse().getName()))
|
|
|
+ .replace("##课程代码##", General.XMLEncode(paper.getSkeleton().getCourse().getCode()));
|
|
|
+ String xmlns_w15 = "xmlns:w15=\"http://schemas.microsoft.com/office/word/2012/wordml\"";
|
|
|
+ if (!docStr.contains(xmlns_w15)) {
|
|
|
+ docStr = docStr.replace("<w:document ", "<w:document " + xmlns_w15 + " ");
|
|
|
+ }
|
|
|
+ String xmlns_a = "xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"";
|
|
|
+ if (!docStr.contains(xmlns_a)) {
|
|
|
+ docStr = docStr.replace("<w:document ", "<w:document " + xmlns_a + " ");
|
|
|
+ }
|
|
|
+ fos = new FileOutputStream(document, false);
|
|
|
+ IOUtils.write(docStr, fos, "UTF-8");
|
|
|
+ } finally {
|
|
|
+ General.close(is);
|
|
|
+ General.close(fos);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ {
|
|
|
+ File document = templetDocxReader.getDocumentInfo().getFile();
|
|
|
+ FileOutputStream fosNew = null;
|
|
|
+ FileOutputStream fos = null;
|
|
|
+ InputStream is = null;
|
|
|
+ try {
|
|
|
+ is = new FileInputStream(document);
|
|
|
+ String docStr = IOUtils.toString(is, "UTF-8");
|
|
|
+ int index1 = docStr.indexOf("##试题开始##");// "##试题开始##"的位置
|
|
|
+ int index2 = docStr.substring(0, index1).lastIndexOf("<w:p ");// "##试题开始##"对应的<w:p>标签的开始位置
|
|
|
+ int index3 = index1 + docStr.substring(index1).indexOf("</w:p>");// "##试题开始##"对应的<w:p>标签的结束位置
|
|
|
+
|
|
|
+ int index4 = docStr.indexOf("##试题结束##");// "##试题结束##"的位置
|
|
|
+ int index5 = docStr.substring(0, index4).lastIndexOf("<w:p ");// "##试题结束##"对应的<w:p>标签的开始位置
|
|
|
+ int index6 = index4 + docStr.substring(index4).indexOf("</w:p>");// "##试题结束##"对应的<w:p>标签的结束位置
|
|
|
+
|
|
|
+ String head = docStr.substring(0, index2);// ##试题开始##"前面的部分
|
|
|
+ String quTmpStr = docStr.substring(index3 + "</w:p>".length(), index5);// 题目模板
|
|
|
+ String tail = docStr.substring(index6 + "</w:p>".length());// "##试题结束##"后面的部分
|
|
|
+
|
|
|
+ int index7 = quTmpStr.indexOf("##答案项##");
|
|
|
+ int index8 = quTmpStr.substring(0, index7).lastIndexOf("<w:p ");// 答案项对应的<w:p>标签的开始位置
|
|
|
+ int index9 = index7 + quTmpStr.substring(index7).indexOf("</w:p>");// 答案项对应的<w:p>标签的结束位置
|
|
|
+
|
|
|
+ // int index10 = quTmpStr.indexOf("##答题项##");
|
|
|
+ // int index11 =
|
|
|
+ // quTmpStr.substring(0,index10).lastIndexOf("<w:p ");//答题项对应的<w:p>标签的开始位置
|
|
|
+ // int index12 = index10 +
|
|
|
+ // quTmpStr.substring(index10).indexOf("</w:p>");//答题项对应的<w:p>标签的结束位置
|
|
|
+
|
|
|
+ fosNew = new FileOutputStream(document, false);
|
|
|
+ IOUtils.write(head, fosNew, "UTF-8");
|
|
|
+ General.close(fosNew);
|
|
|
+
|
|
|
+ fos = new FileOutputStream(document, true);
|
|
|
+
|
|
|
+ String qtTmpHeadStr = quTmpStr.substring(0, index8);
|
|
|
+ String qtTmpTailStr = quTmpStr.substring(index9 + "</w:p>".length());
|
|
|
+ String xtTmpStr = quTmpStr.substring(index8, index9 + "</w:p>".length());
|
|
|
+
|
|
|
+ // String anTmpStr = quTmpStr.substring(index11,index12 +
|
|
|
+ // "</w:p>".length());
|
|
|
+ int quNo = 0;
|
|
|
+ for (int i = 0; i < paper.getQtypeList().size(); i++) {
|
|
|
+ PagerConstructQtype qtyp = paper.getQtypeList().get(i);
|
|
|
+ String str1= General.toCNLowerNum(i + 1) + "、" + General.XMLEncode(qtyp.getName())
|
|
|
+ + ":本大题共" + qtyp.getQuestionSum() + "小题," + ((qtyp.getQuestionSum() > 1)?"每小题":"")
|
|
|
+ + General.formatScore(qtyp.getScore()) + "分"
|
|
|
+ + ((qtyp.getQuestionSum() > 1) ? ",共" + General.formatScore(qtyp.getQuestionScores()) + "分" : "")
|
|
|
+ + "。";
|
|
|
+ String qtypStr = qtTmpHeadStr
|
|
|
+ .replace("##大题描述##", str1)
|
|
|
+ .replace("##大题序号##", General.toCNLowerNum(i + 1))
|
|
|
+ .replace("##大题名称##", General.XMLEncode(qtyp.getName()))
|
|
|
+ .replace("##小题数##", "" + qtyp.getQuestionSum())
|
|
|
+ .replace("##小题分##", "" + General.formatScore(qtyp.getScore()))
|
|
|
+ .replace("##小题总分##", "" + General.formatScore(qtyp.getQuestionScores()))
|
|
|
+ .replace("##题型说明##",
|
|
|
+ General.isNotEmpty(qtyp.getRemark()) ? ("(" + qtyp.getRemark() + ")") : "");
|
|
|
+ IOUtils.write(qtypStr, fos, "UTF-8");
|
|
|
+ String quesTypeName = qtyp.getName();
|
|
|
+ if(quesTypeName.equals("单项选择题") || quesTypeName.equals("单选题") || quesTypeName.equals("单选")
|
|
|
+ || quesTypeName.equals("多项选择题") || quesTypeName.equals("多选题") || quesTypeName.equals("多选")){
|
|
|
+ int lineSize = (qtyp.getConstructDetails().size() + 4) / 5;
|
|
|
+ List<String> rowList = new LinkedList<String>();
|
|
|
+ for (int lineIndex = 0; lineIndex < lineSize; lineIndex++) {
|
|
|
+ String rowContent = Consts.OPT_TAB_5_TEMP;
|
|
|
+ int columnIndex = 0;
|
|
|
+ for (int quesIndex = lineIndex * 5; quesIndex < ((lineIndex + 1) * 5); quesIndex++,columnIndex++) {
|
|
|
+ int tabSpace = Consts.OPT_TAB_SPACE_ARR[columnIndex];
|
|
|
+ if(quNo >= 9){
|
|
|
+ tabSpace = tabSpace - 105;
|
|
|
+ }
|
|
|
+ char a = 'A';
|
|
|
+ a = (char) (a + columnIndex);
|
|
|
+ rowContent = rowContent.replace(a + "_NUM", "" + tabSpace);
|
|
|
+ if (quesIndex >= qtyp.getConstructDetails().size()) {
|
|
|
+ rowContent = rowContent.replace(a + "#" + a, "");
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ PagerConstructDetail d = qtyp.getConstructDetails().get(quesIndex);
|
|
|
+ quNo++;
|
|
|
+ Question qu = d.getQuestion();
|
|
|
+ if (qu == null) {
|
|
|
+ qu = new Question();
|
|
|
+ }
|
|
|
+ if (qu.getOptions() != null && qu.getOptions().size() > 0) {
|
|
|
+ String answer = "";
|
|
|
+ for (QuestionOption opt : qu.getOptions()) {
|
|
|
+ if (opt.getIsCorrectOption() == 1) {
|
|
|
+ answer = answer + opt.getOptionNoString() + " ";
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (answer.length() > 0) {
|
|
|
+ answer = answer.substring(0, answer.length() - 1);
|
|
|
+ }
|
|
|
+ qu.setAnswer(answer);
|
|
|
+ } else {
|
|
|
+ qu.setAnswer(null);
|
|
|
+ }
|
|
|
+ String answer = qu.getAnswer();
|
|
|
+ if (General.isEmpty(answer)) {
|
|
|
+ answer = "空";
|
|
|
+ }
|
|
|
+ rowContent = rowContent.replace(a + "#" + a, quNo + "." + answer);
|
|
|
+ }
|
|
|
+ rowList.add(rowContent);
|
|
|
+ }
|
|
|
+ System.out.println(StringUtils.join(rowList, ""));
|
|
|
+ IOUtils.write(StringUtils.join(rowList, ""), fos, "UTF-8");
|
|
|
+ IOUtils.write(qtTmpTailStr, fos, "UTF-8");
|
|
|
+ } else {
|
|
|
+ for (int j = 0; j < qtyp.getConstructDetails().size(); j++) {
|
|
|
+ PagerConstructDetail d = qtyp.getConstructDetails().get(j);
|
|
|
+ quNo++;
|
|
|
+ Question qu = d.getQuestion();
|
|
|
+ if (qu == null) {
|
|
|
+ qu = new Question();
|
|
|
+ qu.setAnswer("空");
|
|
|
+ }
|
|
|
+ log.info("正在处理试题:id = " + qu.getId());
|
|
|
+ String answer = null;
|
|
|
+ if ((qu.getAnswerWord() == null || qu.getAnswerWord().length == 0)
|
|
|
+ && General.isEmpty(qu.getAnswer())) {
|
|
|
+ answer = xtTmpStr.replace("##答案项##",
|
|
|
+ toQuesNumStr(quNo) + "." + General.XMLEncode(qu.getAnswerSummary()).trim());
|
|
|
+ } else {
|
|
|
+ try {
|
|
|
+ boolean isBlank = false;
|
|
|
+ byte[] wordBytes = null;
|
|
|
+ if ((qu.getAnswerWord() == null || qu.getAnswerWord().length == 0)
|
|
|
+ && !General.isEmpty(qu.getAnswer())) {
|
|
|
+ if(General.isEmpty(General.extractText(qu.getAnswer()))){
|
|
|
+ answer = xtTmpStr.replace("##答案项##",
|
|
|
+ toQuesNumStr(quNo) + "." + General.toUnicode('<') + "无" + General.toUnicode('>'));
|
|
|
+ isBlank = true;
|
|
|
+ }else{
|
|
|
+ wordBytes = General.htmlToDocx(qu.getAnswer());
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ wordBytes = qu.getAnswerWord();
|
|
|
+ }
|
|
|
+ if(!isBlank){
|
|
|
+ answer = General.dealWord(wordBytes, templetDocxReader, needToUpdate);
|
|
|
+
|
|
|
+ int firstWtBeginIndex = answer.indexOf("<w:t>");
|
|
|
+ int firstWtBeginIndex2 = answer.indexOf("<w:t ");
|
|
|
+ firstWtBeginIndex = (firstWtBeginIndex < 0 || (firstWtBeginIndex2 >= 0 && firstWtBeginIndex > firstWtBeginIndex2))?firstWtBeginIndex2:firstWtBeginIndex;
|
|
|
+
|
|
|
+ int nearestGtIndex = answer.indexOf('>', firstWtBeginIndex + 1);
|
|
|
+
|
|
|
+ String part1 = answer.substring(0, nearestGtIndex + 1).trim();
|
|
|
+ String part2 = answer.substring(nearestGtIndex + 1).trim();
|
|
|
+ answer = part1 + toQuesNumStr(quNo) + "." + part2;
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("获取试题[" + qu.getId() + "]的Word信息失败,原因:" + e.getMessage(), e);
|
|
|
+ answer = Consts.ERR_P_TMP.replace("XX",
|
|
|
+ quNo + "." + String.format(Consts.ERR_ANSWER_MSG, qu.getId() + ""));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //answer = dealFormula(answer);
|
|
|
+ IOUtils.write(addBeforeLines(answer,0,0,(j == qtyp.getConstructDetails().size()-1)?10:0), fos, "UTF-8");
|
|
|
+ IOUtils.write(qtTmpTailStr, fos, "UTF-8");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ IOUtils.write(tail, fos, "UTF-8");
|
|
|
+ } finally {
|
|
|
+ General.close(is);
|
|
|
+ General.close(fosNew);
|
|
|
+ General.close(fos);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ {
|
|
|
+ File document = templetDocxReader.getDocumentInfo().getFile();
|
|
|
+ FileOutputStream fos = null;
|
|
|
+ InputStream is = null;
|
|
|
+ try {
|
|
|
+ is = new FileInputStream(document);
|
|
|
+ String docStr = IOUtils
|
|
|
+ .toString(is, "UTF-8")
|
|
|
+ .replace("<pic:pic>",
|
|
|
+ "<pic:pic xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">")
|
|
|
+ .replace("<w15:collapsed w:val=\"false\"/>", "");
|
|
|
+
|
|
|
+ // String xmlns_a =
|
|
|
+ // "xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"";
|
|
|
+ // if(!docStr.contains(xmlns_a)){
|
|
|
+ // docStr = docStr.replace("<w:document ", "<w:document " +
|
|
|
+ // xmlns_a + " ");
|
|
|
+ // }
|
|
|
+ fos = new FileOutputStream(document, false);
|
|
|
+ IOUtils.write(docStr, fos, "UTF-8");
|
|
|
+ } finally {
|
|
|
+ General.close(is);
|
|
|
+ General.close(fos);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ {
|
|
|
+ DocxReader.updateDocx(newDocx, needToUpdate);
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("生成试卷[" + paper.getId() + "]的Word文档失败,原因:" + e.getMessage(), e);
|
|
|
+ throw new BizException(e.getMessage(), e);
|
|
|
+ } finally {
|
|
|
+ General.release(templetDocxReader);
|
|
|
+ }
|
|
|
+ if(ParamUtils.NeedCheckWordVersion){
|
|
|
+ General.setDocxDefinedAttr(newDocx, Consts.DOCX_VERSION, "QMTH" + System.currentTimeMillis());// 往新生成的Word里面打个版本号:当前时间
|
|
|
+ }
|
|
|
+ return newDocx;
|
|
|
+ }
|
|
|
+
|
|
|
+ //TODO 生成网评卷
|
|
|
+ public Attachment generalWangpingPaperFileIntoAtt(int paperId,User curUser) throws BizException{
|
|
|
+ PagerConstruct paper = getOriginalWholePaperInfo(paperId);
|
|
|
+ File paperFile = generalWangPingPaperFile(paper);
|
|
|
+ File newFile = General.newAttFile();
|
|
|
+ paperFile.renameTo(newFile);
|
|
|
+ Attachment att = new Attachment();
|
|
|
+ att.setCreatedBy(curUser.getId());
|
|
|
+ att.setOriginalName(paper.getName() + "网评卷" + ".docx");
|
|
|
+ att.setCurName(newFile.getName());
|
|
|
+ att.setFileLength(newFile.length());
|
|
|
+ att.setStorePath(newFile.getAbsolutePath());
|
|
|
+ att.setStatus(Consts.AttachmentStatus.DRAFT);
|
|
|
+ dao.insert("addAttachment", att);
|
|
|
+ //更新试卷中的word附件
|
|
|
+ int oldAttId = paper.getLastWangpingWord() == null ? 0 : paper.getLastWangpingWord().intValue();
|
|
|
+ Attachment newAtt = attachmentService.getAttachmentByAttr(newFile.getAbsolutePath());
|
|
|
+ int newAttId = newAtt == null ? 0 : newAtt.getId().intValue();
|
|
|
+ if (oldAttId == 0) {
|
|
|
+ paper.setLastWangpingWord(newAttId);
|
|
|
+ } else {
|
|
|
+ Attachment oldAtt = attachmentService.getAttachmentById(oldAttId);
|
|
|
+ if (oldAtt != null) {
|
|
|
+ oldAtt.setStatus("DELETEED");
|
|
|
+ dao.update("updateAttachment", att);
|
|
|
+ }
|
|
|
+ paper.setLastWangpingWord(newAttId);
|
|
|
+ }
|
|
|
+ if (newAttId != 0) {
|
|
|
+ dao.update("updatePagerConstruct", paper);
|
|
|
+ }
|
|
|
+ return att;
|
|
|
+ }
|
|
|
+
|
|
|
+ //生成题卡
|
|
|
+ public Attachment generalTikaFileIntoAtt(int paperId,User curUser) throws BizException{
|
|
|
+ PagerConstruct paper = getOriginalWholePaperInfo(paperId);
|
|
|
+ int oldAttId = paper.getLastTikaWord() == null ? 0 : paper.getLastTikaWord().intValue();
|
|
|
+ PaperTask task = dao.get("getPaperTaskById", paper.getTaskId());
|
|
|
+ if(task.getStatus().equals(Consts.PaperTaskStatus.ARCHIVED) && oldAttId != 0){
|
|
|
+ return attachmentService.getAttachmentById(oldAttId);
|
|
|
+ }
|
|
|
+ File paperFile = generalTikaFile(paper);
|
|
|
+ File newFile = General.newAttFile();
|
|
|
+ paperFile.renameTo(newFile);
|
|
|
+ Attachment att = new Attachment();
|
|
|
+ att.setCreatedBy(curUser.getId());
|
|
|
+ att.setOriginalName(paper.getName() + "题卡" + ".docx");
|
|
|
+ att.setCurName(newFile.getName());
|
|
|
+ att.setFileLength(newFile.length());
|
|
|
+ att.setStorePath(newFile.getAbsolutePath());
|
|
|
+ att.setStatus(Consts.AttachmentStatus.USING);
|
|
|
+ dao.insert("addAttachment", att);
|
|
|
+ //更新试卷中的word附件
|
|
|
+// Attachment newAtt = attachmentService.getAttachmentByAttr(newFile.getAbsolutePath());
|
|
|
+// int newAttId = newAtt == null ? 0 : newAtt.getId().intValue();
|
|
|
+ if (oldAttId != 0) {
|
|
|
+ Attachment oldAtt = attachmentService.getAttachmentById(oldAttId);
|
|
|
+ if (oldAtt != null) {
|
|
|
+ oldAtt.setStatus("DELETEED");
|
|
|
+ dao.update("updateAttachment", att);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ PagerConstruct paperTmp = new PagerConstruct();
|
|
|
+ paperTmp.setId(paperId);
|
|
|
+ paperTmp.setLastTikaWord(att.getId());
|
|
|
+ dao.update("updatePagerConstruct", paperTmp);
|
|
|
+ return att;
|
|
|
+ }
|
|
|
+
|
|
|
+ private String getAbilityText(Question qu){
|
|
|
+ if(qu.getAbilityCode() != null){
|
|
|
+ return qu.getAbilityCode();
|
|
|
+ }else{
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private String getEstimateDifficultyText(Question qu){
|
|
|
+ if("10".equals(qu.getEstimateDifficultyCode())){
|
|
|
+ return "A";
|
|
|
+ }
|
|
|
+ if("20".equals(qu.getEstimateDifficultyCode())){
|
|
|
+ return "B";
|
|
|
+ }
|
|
|
+ if("30".equals(qu.getEstimateDifficultyCode())){
|
|
|
+ return "C";
|
|
|
+ }
|
|
|
+ if("40".equals(qu.getEstimateDifficultyCode())){
|
|
|
+ return "D";
|
|
|
+ }
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+
|
|
|
+ private String getAssessmentDemandText(Question qu){
|
|
|
+ if("A".equals(qu.getEstimateDifficultyCode())){
|
|
|
+ return "1";
|
|
|
+ }
|
|
|
+ if("B".equals(qu.getEstimateDifficultyCode())){
|
|
|
+ return "2";
|
|
|
+ }
|
|
|
+ if("C".equals(qu.getEstimateDifficultyCode())){
|
|
|
+ return "3";
|
|
|
+ }
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+
|
|
|
+ public File generalTikaFile(PagerConstruct paper) throws BizException {
|
|
|
+ String paperType = paper.getName().charAt(paper.getName().length() - 1) + "";
|
|
|
+ File newDocx = null;
|
|
|
+ DocxReader templetDocxReader = null;
|
|
|
+ Map<String, ResourceInfo> needToUpdate = new HashMap<String, ResourceInfo>();
|
|
|
+ try {
|
|
|
+ {// 拷贝一份模板文件到临时文件夹里面
|
|
|
+ FileOutputStream fos = null;
|
|
|
+ InputStream is = null;
|
|
|
+ try {
|
|
|
+ newDocx = new File(ParamUtils.TemporaryDirPath, UUID.randomUUID().toString().replace("-", ""));
|
|
|
+ fos = new FileOutputStream(newDocx);
|
|
|
+ is = ZujuanService.class.getResourceAsStream("/paperTmps/tikaTmp1.docx");
|
|
|
+ IOUtils.copyLarge(is, fos);
|
|
|
+ fos.flush();
|
|
|
+ } finally {
|
|
|
+ General.close(is);
|
|
|
+ General.close(fos);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ templetDocxReader = new DocxReader(newDocx);
|
|
|
+ templetDocxReader.doRead();
|
|
|
+ {
|
|
|
+ List<ResourceInfo> headersAndFooters = new ArrayList<ResourceInfo>();
|
|
|
+ headersAndFooters.addAll(templetDocxReader.getHeaders());
|
|
|
+ headersAndFooters.addAll(templetDocxReader.getFooters());
|
|
|
+ for (ResourceInfo info : headersAndFooters) {
|
|
|
+ FileOutputStream fos = null;
|
|
|
+ InputStream is = null;
|
|
|
+ try {
|
|
|
+ is = new FileInputStream(info.getFile());
|
|
|
+ String docStr = IOUtils.toString(is, "UTF-8")
|
|
|
+ .replace("##试卷名称##", General.XMLEncode(paper.getName()))
|
|
|
+ .replace("##试卷题头##", General.XMLEncode(paper.getHead()))
|
|
|
+ .replace("##课程名称##", General.XMLEncode(paper.getSkeleton().getCourse().getName()))
|
|
|
+ .replace("##课程代码##", General.XMLEncode(paper.getSkeleton().getCourse().getCode()))
|
|
|
+ .replace("##满分##", "100");
|
|
|
+ fos = new FileOutputStream(info.getFile(), false);
|
|
|
+ IOUtils.write(docStr, fos, "UTF-8");
|
|
|
+ } finally {
|
|
|
+ General.close(is);
|
|
|
+ General.close(fos);
|
|
|
+ }
|
|
|
+ needToUpdate.put(info.getPathInZip(), info);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ {
|
|
|
+ needToUpdate.put(templetDocxReader.getDocumentInfo().getPathInZip(),
|
|
|
+ templetDocxReader.getDocumentInfo());
|
|
|
+ File document = templetDocxReader.getDocumentInfo().getFile();
|
|
|
+ FileOutputStream fos = null;
|
|
|
+ InputStream is = null;
|
|
|
+ try {
|
|
|
+ is = new FileInputStream(document);
|
|
|
+ String docStr = IOUtils.toString(is, "UTF-8")
|
|
|
+ .replace("##试卷名称##", General.XMLEncode(paper.getName()))
|
|
|
+ .replace("##试卷题头##", General.XMLEncode(paper.getHead()))
|
|
|
+ .replace("##课程名称##", General.XMLEncode(paper.getSkeleton().getCourse().getName()))
|
|
|
+ .replace("##课程代码##", General.XMLEncode(paper.getSkeleton().getCourse().getCode()))
|
|
|
+ .replace("##满分##", "100");
|
|
|
+ String xmlns_w15 = "xmlns:w15=\"http://schemas.microsoft.com/office/word/2012/wordml\"";
|
|
|
+ if (!docStr.contains(xmlns_w15)) {
|
|
|
+ docStr = docStr.replace("<w:document ", "<w:document " + xmlns_w15 + " ");
|
|
|
+ }
|
|
|
+ String xmlns_a = "xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"";
|
|
|
+ if (!docStr.contains(xmlns_a)) {
|
|
|
+ docStr = docStr.replace("<w:document ", "<w:document " + xmlns_a + " ");
|
|
|
+ }
|
|
|
+ fos = new FileOutputStream(document, false);
|
|
|
+ IOUtils.write(docStr, fos, "UTF-8");
|
|
|
+ } finally {
|
|
|
+ General.close(is);
|
|
|
+ General.close(fos);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ {
|
|
|
+ File document = templetDocxReader.getDocumentInfo().getFile();
|
|
|
+ FileOutputStream fosNew = null;
|
|
|
+ FileOutputStream fos = null;
|
|
|
+ InputStream is = null;
|
|
|
+ try {
|
|
|
+ is = new FileInputStream(document);
|
|
|
+ String docStr = IOUtils.toString(is, "UTF-8");
|
|
|
+ int index1 = docStr.indexOf("##试题开始##");// "##试题开始##"的位置
|
|
|
+ int index2 = docStr.substring(0, index1).lastIndexOf("<w:p ");// "##试题开始##"对应的<w:p>标签的开始位置
|
|
|
+ int index3 = index1 + docStr.substring(index1).indexOf("</w:p>");// "##试题开始##"对应的<w:p>标签的结束位置
|
|
|
+
|
|
|
+ int index4 = docStr.indexOf("##试题结束##");// "##试题结束##"的位置
|
|
|
+ int index5 = docStr.substring(0, index4).lastIndexOf("<w:p ");// "##试题结束##"对应的<w:p>标签的开始位置
|
|
|
+ int index6 = index4 + docStr.substring(index4).indexOf("</w:p>");// "##试题结束##"对应的<w:p>标签的结束位置
|
|
|
+
|
|
|
+ String head = docStr.substring(0, index2);// ##试题开始##"前面的部分
|
|
|
+ String quTmpStr = docStr.substring(index3 + "</w:p>".length(), index5);// 题目模板
|
|
|
+ String tail = docStr.substring(index6 + "</w:p>".length());// "##试题结束##"后面的部分
|
|
|
+
|
|
|
+ fosNew = new FileOutputStream(document, false);
|
|
|
+ IOUtils.write(head, fosNew, "UTF-8");
|
|
|
+ General.close(fosNew);
|
|
|
+
|
|
|
+ fos = new FileOutputStream(document, true);
|
|
|
+
|
|
|
+ int quNo = 0;
|
|
|
+ for (int i = 0; i < paper.getQtypeList().size(); i++) {
|
|
|
+ PagerConstructQtype qtyp = paper.getQtypeList().get(i);
|
|
|
+ String quesTypeName = qtyp.getName();
|
|
|
+ for (int j = 0; j < qtyp.getConstructDetails().size(); j++) {
|
|
|
+ PagerConstructDetail d = qtyp.getConstructDetails().get(j);
|
|
|
+ quNo++;
|
|
|
+ Question qu = d.getQuestion();
|
|
|
+ if (qu == null) {
|
|
|
+ qu = new Question();
|
|
|
+ qu.setBodySummary("空题");
|
|
|
+ }
|
|
|
+ String optAnswer = "";
|
|
|
+ if (qu.getOptions() != null && qu.getOptions().size() > 0) {
|
|
|
+ for (QuestionOption opt : qu.getOptions()) {
|
|
|
+ if (opt.getIsCorrectOption() == 1) {
|
|
|
+ optAnswer = optAnswer + opt.getOptionNoString() + " ";
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (optAnswer.length() > 0) {
|
|
|
+ optAnswer = optAnswer.substring(0, optAnswer.length() - 1);
|
|
|
+ }
|
|
|
+ if(optAnswer.length() == 0){
|
|
|
+ optAnswer = "无";
|
|
|
+ }
|
|
|
+ }
|
|
|
+ String setTimeStr = "";
|
|
|
+ if(qu.getSetTime() != null){
|
|
|
+ setTimeStr = DateHelper.formatDate(qu.getSetTime(), "yyyy 年 M 月 d 日");
|
|
|
+ }
|
|
|
+ log.info("正在处理试题:id = " + qu.getId());
|
|
|
+ String xtXml = quTmpStr
|
|
|
+ .replace("##课程代码##", General.XMLEncode(paper.getSkeleton().getCourse().getCode()))
|
|
|
+ .replace("##课程名称##", General.XMLEncode(paper.getSkeleton().getCourse().getName()))
|
|
|
+ .replace("##AB卷##", General.XMLEncode(paperType))
|
|
|
+ .replace("##序列##", General.XMLEncode(toQuesNumStr(quNo)))
|
|
|
+ .replace("##试题编号##", General.null2String(qu.getQuestionNo(), ""))
|
|
|
+ .replace("##大题名称##", General.XMLEncode(quesTypeName))
|
|
|
+ .replace("##章##", General.XMLEncode(General.null2String(qu.getChapter(), "")))
|
|
|
+ .replace("##节##", General.XMLEncode(General.null2String(qu.getSection(), "")))
|
|
|
+ .replace("##目##", General.XMLEncode(General.null2String(qu.getItem(), "")))
|
|
|
+ .replace("##能力要求##", getAbilityText(qu))
|
|
|
+ .replace("##考核要求##", getAssessmentDemandText(qu))
|
|
|
+ .replace("##预计难度##", getEstimateDifficultyText(qu))
|
|
|
+ .replace("##小题分##", General.formatScore(qtyp.getScore()))
|
|
|
+ .replace("##选项答案##", optAnswer)
|
|
|
+ .replace("##命题教师##", General.XMLEncode(General.null2String(qu.getSetTeacherName(), "")))
|
|
|
+ .replace("##命题时间##", General.XMLEncode(setTimeStr));
|
|
|
+ String contentXml = "";
|
|
|
+ if ((qu.getBodyWord() == null || qu.getBodyWord().length == 0)
|
|
|
+ && General.isEmpty(qu.getBody())) {
|
|
|
+ contentXml = Consts.NORMAL_P_TMP.replace("XX", General.XMLEncode(qu.getBodySummary()).trim());
|
|
|
+ } else {
|
|
|
+ try {
|
|
|
+ byte[] wordBytes = null;
|
|
|
+ if ((qu.getBodyWord() == null || qu.getBodyWord().length == 0)
|
|
|
+ && !General.isEmpty(qu.getBody())) {
|
|
|
+ wordBytes = General.htmlToDocx(qu.getBody());
|
|
|
+ } else {
|
|
|
+ wordBytes = qu.getBodyWord();
|
|
|
+ }
|
|
|
+ contentXml = General.dealWord(wordBytes, templetDocxReader, needToUpdate);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("获取试题[" + qu.getId() + "]的Word信息失败,原因:" + e.getMessage(), e);
|
|
|
+ contentXml = Consts.ERR_P_TMP.replace("XX",
|
|
|
+ quNo + "." + String.format(Consts.ERR_QUS_MSG, qu.getId() + ""));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ contentXml = addBeforeLines(contentXml, 200, 0, 0);
|
|
|
+ int optSize = (qu.getOptions() != null) ? qu.getOptions().size() : 0;
|
|
|
+ if (optSize > 0) {
|
|
|
+ int optTxtMaxLen = 0;
|
|
|
+ for (QuestionOption opt : qu.getOptions()) {
|
|
|
+ String optTxt = General.convertNullToEmpty(opt.getSummary()).trim();
|
|
|
+ if (optTxt.length() > optTxtMaxLen) {
|
|
|
+ optTxtMaxLen = optTxt.length();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (optTxtMaxLen == 0) {
|
|
|
+ optTxtMaxLen = 10;
|
|
|
+ }
|
|
|
+ String anTblTmp = null;
|
|
|
+ if (optSize == 4) {
|
|
|
+ if (optTxtMaxLen <= 8) {
|
|
|
+ anTblTmp = Consts.OPT_TABLE_TMP_1;
|
|
|
+ } else if (optTxtMaxLen <= 16) {
|
|
|
+ anTblTmp = Consts.OPT_TABLE_TMP_2;
|
|
|
+ } else {
|
|
|
+ anTblTmp = Consts.OPT_TABLE_TMP_4X1;
|
|
|
+ }
|
|
|
+ } else if (optSize == 5) {
|
|
|
+ if (optTxtMaxLen <= 11) {
|
|
|
+ anTblTmp = Consts.OPT_TABLE_TMP_3;
|
|
|
+ }else{
|
|
|
+ anTblTmp = Consts.OPT_TABLE_TMP_5X1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ String optsStr = null;
|
|
|
+ /**暂时屏蔽表格方式显示选项
|
|
|
+ if ((optSize == 4 || optSize == 5) && anTblTmp != null) {
|
|
|
+ optsStr = anTblTmp;
|
|
|
+ } else {
|
|
|
+ optsStr = "";
|
|
|
+ }
|
|
|
+ **/
|
|
|
+ optsStr = "";
|
|
|
+ for (int m = 0; m < optSize; m++) {
|
|
|
+ QuestionOption opt = qu.getOptions().get(m);
|
|
|
+ String seqNum = String.valueOf(((char) ('A' + m)));
|
|
|
+ String prefixStr = " " + seqNum + ".";
|
|
|
+ String anStr = null;
|
|
|
+ log.info("正在处理答题项:id = " + opt.getId());
|
|
|
+ if ((opt.getContentWord() == null || opt.getContentWord().length == 0)
|
|
|
+ && General.isEmpty(opt.getContent())) {
|
|
|
+ String optTxt = General.XMLEncode(opt.getSummary()).trim();
|
|
|
+ anStr = Consts.NORMAL_P_TMP.replace("XX", prefixStr + optTxt);
|
|
|
+ } else {
|
|
|
+ try {
|
|
|
+ byte[] wordBytes = null;
|
|
|
+ if ((opt.getContentWord() == null || opt.getContentWord().length == 0)
|
|
|
+ && !General.isEmpty(opt.getContent())) {
|
|
|
+ wordBytes = General.htmlToDocx(opt.getContent());
|
|
|
+ } else {
|
|
|
+ wordBytes = opt.getContentWord();
|
|
|
+ }
|
|
|
+ anStr = General.dealWord(wordBytes, templetDocxReader, needToUpdate);
|
|
|
+ // int firstWtBeginIndex =
|
|
|
+ // anStr.indexOf("<w:t>");
|
|
|
+ int firstWtBeginIndex = -1;
|
|
|
+ if (firstWtBeginIndex < 0) {
|
|
|
+ int firstWpBeginIndex = anStr.indexOf(">");// 默认第一个节点是<w:p
|
|
|
+ // ...>,不支持答题项第一个元素是表格
|
|
|
+ String part1 = anStr.substring(0, firstWpBeginIndex + ">".length()).trim();
|
|
|
+ String part2 = anStr.substring(firstWpBeginIndex + ">".length())
|
|
|
+ .replace("\"center\"", "\"left\"")
|
|
|
+ .replace("\"right\"", "\"left\"").trim();
|
|
|
+ anStr = part1 + "<w:r><w:t>" + prefixStr + "</w:t></w:r>" + part2;
|
|
|
+ /*****
|
|
|
+ * 往anStr里面添加<w:jc
|
|
|
+ * w:val="left"/>
|
|
|
+ *****/
|
|
|
+ {
|
|
|
+ if (!anStr.contains("<w:jc w:val=\"left\"/>")) {
|
|
|
+ int pPrIndex = anStr.indexOf("<w:pPr>");
|
|
|
+ if (pPrIndex < 0) {
|
|
|
+ anStr = "<w:pPr><w:jc w:val=\"left\"/></w:pPr>" + anStr;
|
|
|
+ } else {
|
|
|
+ anStr = anStr.substring(0, pPrIndex + "<w:pPr>".length())
|
|
|
+ + "<w:jc w:val=\"left\"/>"
|
|
|
+ + anStr.substring(pPrIndex + "<w:pPr>".length());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // String part1 =
|
|
|
+ // anStr.substring(0,
|
|
|
+ // firstWtBeginIndex +
|
|
|
+ // "<w:t>".length());
|
|
|
+ // String part2 =
|
|
|
+ // anStr.substring(firstWtBeginIndex
|
|
|
+ // + "<w:t>".length());
|
|
|
+ // anStr = part1 + ((char)('A' +
|
|
|
+ // m)) + "." + part2;
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("获取试题选项[" + opt.getId() + "]的Word信息失败,原因:" + e.getMessage(), e);
|
|
|
+ anStr = Consts.ERR_P_TMP.replace("XX",
|
|
|
+ prefixStr + String.format(Consts.ERR_QUS_OPT_MSG, qu.getId() + ""));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /**暂时屏蔽表格方式显示选项
|
|
|
+ if ((optSize == 4 || optSize == 5) && anTblTmp != null) {
|
|
|
+ optsStr = optsStr.replace(seqNum + "_" + seqNum + ".", anStr);
|
|
|
+ } else {
|
|
|
+ optsStr = optsStr + anStr;
|
|
|
+ }
|
|
|
+ **/
|
|
|
+ optsStr = optsStr + addBeforeLines(anStr,200,0,0);
|
|
|
+ }
|
|
|
+ contentXml = contentXml + optsStr;
|
|
|
+ }
|
|
|
+ xtXml = xtXml.replace("##试题内容##", contentXml);
|
|
|
+
|
|
|
+ String answer = null;
|
|
|
+ if ((qu.getAnswerWord() == null || qu.getAnswerWord().length == 0)
|
|
|
+ && General.isEmpty(qu.getAnswer())) {
|
|
|
+ answer = Consts.NORMAL_P_TMP.replace("XX", General.XMLEncode(qu.getAnswerSummary()).trim());
|
|
|
+ } else {
|
|
|
+ try {
|
|
|
+ boolean isBlank = false;
|
|
|
+ byte[] wordBytes = null;
|
|
|
+ if ((qu.getAnswerWord() == null || qu.getAnswerWord().length == 0)
|
|
|
+ && !General.isEmpty(qu.getAnswer())) {
|
|
|
+ if(General.isEmpty(General.extractText(qu.getAnswer()))){
|
|
|
+ answer = Consts.NORMAL_P_TMP.replace("XX", General.toUnicode('<') + "无" + General.toUnicode('>'));
|
|
|
+ isBlank = true;
|
|
|
+ }else{
|
|
|
+ wordBytes = General.htmlToDocx(qu.getAnswer());
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ wordBytes = qu.getAnswerWord();
|
|
|
+ }
|
|
|
+ if(!isBlank){
|
|
|
+ answer = General.dealWord(wordBytes, templetDocxReader, needToUpdate);
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("获取试题[" + qu.getId() + "]的Word信息失败,原因:" + e.getMessage(), e);
|
|
|
+ answer = Consts.ERR_P_TMP.replace("XX",
|
|
|
+ quNo + "." + String.format(Consts.ERR_ANSWER_MSG, qu.getId() + ""));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ answer = addBeforeLines(answer, 200, 0, 0);
|
|
|
+ xtXml = Consts.BLANK_BR_TMP + xtXml.replace("##答案##", answer);
|
|
|
+ if(i < paper.getQtypeList().size()-1 || j < qtyp.getConstructDetails().size()-1){
|
|
|
+ xtXml = xtXml + Consts.PAGE_BR_TMP;
|
|
|
+ }
|
|
|
+ IOUtils.write(xtXml, fos, "UTF-8");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ IOUtils.write(tail, fos, "UTF-8");
|
|
|
+ } finally {
|
|
|
+ General.close(is);
|
|
|
+ General.close(fosNew);
|
|
|
+ General.close(fos);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ {
|
|
|
+ File document = templetDocxReader.getDocumentInfo().getFile();
|
|
|
+ FileOutputStream fos = null;
|
|
|
+ InputStream is = null;
|
|
|
+ try {
|
|
|
+ is = new FileInputStream(document);
|
|
|
+ String docStr = IOUtils
|
|
|
+ .toString(is, "UTF-8")
|
|
|
+ .replace("<pic:pic>",
|
|
|
+ "<pic:pic xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">")
|
|
|
+ .replace("<w15:collapsed w:val=\"false\"/>", "");
|
|
|
+
|
|
|
+ // String xmlns_a =
|
|
|
+ // "xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"";
|
|
|
+ // if(!docStr.contains(xmlns_a)){
|
|
|
+ // docStr = docStr.replace("<w:document ", "<w:document " +
|
|
|
+ // xmlns_a + " ");
|
|
|
+ // }
|
|
|
+ fos = new FileOutputStream(document, false);
|
|
|
+ IOUtils.write(docStr, fos, "UTF-8");
|
|
|
+ } finally {
|
|
|
+ General.close(is);
|
|
|
+ General.close(fos);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ {
|
|
|
+ DocxReader.updateDocx(newDocx, needToUpdate);
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("生成试卷[" + paper.getId() + "]的Word文档失败,原因:" + e.getMessage(), e);
|
|
|
+ throw new BizException(e.getMessage(), e);
|
|
|
+ } finally {
|
|
|
+ General.release(templetDocxReader);
|
|
|
+ }
|
|
|
+ if(ParamUtils.NeedCheckWordVersion){
|
|
|
+ General.setDocxDefinedAttr(newDocx, Consts.DOCX_VERSION, "QMTH" + System.currentTimeMillis());// 往新生成的Word里面打个版本号:当前时间
|
|
|
+ }
|
|
|
+ return newDocx;
|
|
|
+ }
|
|
|
+
|
|
|
+ public Attachment generalPaperFileIntoAtt(int paperId,User curUser) throws BizException{
|
|
|
+ PagerConstruct paper = getOriginalWholePaperInfo(paperId);
|
|
|
+ File paperFile = generalPaperFile(paper);
|
|
|
+ File newFile = General.newAttFile();
|
|
|
+ paperFile.renameTo(newFile);
|
|
|
+ Attachment att = new Attachment();
|
|
|
+ att.setCreatedBy(curUser.getId());
|
|
|
+ att.setOriginalName(paper.getName() + ".docx");
|
|
|
+ att.setCurName(newFile.getName());
|
|
|
+ att.setFileLength(newFile.length());
|
|
|
+ att.setStorePath(newFile.getAbsolutePath());
|
|
|
+ att.setStatus(Consts.AttachmentStatus.DRAFT);
|
|
|
+ dao.insert("addAttachment", att);
|
|
|
+ //更新试卷中的word附件
|
|
|
+ int oldAttId = paper.getLastPaperWord() == null ? 0 : paper.getLastPaperWord().intValue();
|
|
|
+ Attachment newAtt = attachmentService.getAttachmentByAttr(newFile.getAbsolutePath());
|
|
|
+ int newAttId = newAtt == null ? 0 : newAtt.getId().intValue();
|
|
|
+ if(oldAttId == 0){
|
|
|
+ paper.setLastPaperWord(newAttId);
|
|
|
+ }else{
|
|
|
+ Attachment oldAtt = attachmentService.getAttachmentById(oldAttId);
|
|
|
+ if(oldAtt != null){
|
|
|
+ oldAtt.setStatus("DELETEED");
|
|
|
+ dao.update("updateAttachment", att);
|
|
|
+ }
|
|
|
+ paper.setLastPaperWord(newAttId);
|
|
|
+ }
|
|
|
+ if(newAttId != 0){
|
|
|
+ dao.update("updatePagerConstruct", paper);
|
|
|
+ }
|
|
|
+ return att;
|
|
|
+ }
|
|
|
+
|
|
|
+ public File generalPaperFile(PagerConstruct paper) throws BizException {
|
|
|
+ File newDocx = null;
|
|
|
+ DocxReader templetDocxReader = null;
|
|
|
+ Map<String, ResourceInfo> needToUpdate = new HashMap<String, ResourceInfo>();
|
|
|
+ try {
|
|
|
+ {// 拷贝一份模板文件到临时文件夹里面
|
|
|
+ FileOutputStream fos = null;
|
|
|
+ InputStream is = null;
|
|
|
+ try {
|
|
|
+ newDocx = new File(ParamUtils.TemporaryDirPath, UUID.randomUUID().toString().replace("-", ""));
|
|
|
+ fos = new FileOutputStream(newDocx);
|
|
|
+ is = ZujuanService.class.getResourceAsStream("/paperTmps/pagerTmp1.docx");
|
|
|
+ IOUtils.copyLarge(is, fos);
|
|
|
+ fos.flush();
|
|
|
+ } finally {
|
|
|
+ General.close(is);
|
|
|
+ General.close(fos);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ templetDocxReader = new DocxReader(newDocx);
|
|
|
+ templetDocxReader.doRead();
|
|
|
+ {
|
|
|
+ List<ResourceInfo> headersAndFooters = new ArrayList<ResourceInfo>();
|
|
|
+ headersAndFooters.addAll(templetDocxReader.getHeaders());
|
|
|
+ headersAndFooters.addAll(templetDocxReader.getFooters());
|
|
|
+ for (ResourceInfo info : headersAndFooters) {
|
|
|
+ FileOutputStream fos = null;
|
|
|
+ InputStream is = null;
|
|
|
+ try {
|
|
|
+ is = new FileInputStream(info.getFile());
|
|
|
+ String docStr = IOUtils.toString(is, "UTF-8")
|
|
|
+ .replace("##试卷名称##", General.XMLEncode(paper.getName()))
|
|
|
+ .replace("##试卷题头##", General.XMLEncode(paper.getHead()))
|
|
|
+ .replace("##课程名称##", General.XMLEncode(paper.getSkeleton().getCourse().getName()))
|
|
|
+ .replace("##课程代码##", General.XMLEncode(paper.getSkeleton().getCourse().getCode()))
|
|
|
+ .replace("##满分##", "100");
|
|
|
+ fos = new FileOutputStream(info.getFile(), false);
|
|
|
+ IOUtils.write(docStr, fos, "UTF-8");
|
|
|
+ } finally {
|
|
|
+ General.close(is);
|
|
|
+ General.close(fos);
|
|
|
+ }
|
|
|
+ needToUpdate.put(info.getPathInZip(), info);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ {
|
|
|
+ needToUpdate.put(templetDocxReader.getDocumentInfo().getPathInZip(),
|
|
|
+ templetDocxReader.getDocumentInfo());
|
|
|
+ File document = templetDocxReader.getDocumentInfo().getFile();
|
|
|
+ FileOutputStream fos = null;
|
|
|
+ InputStream is = null;
|
|
|
+ try {
|
|
|
+ is = new FileInputStream(document);
|
|
|
+ String docStr = IOUtils.toString(is, "UTF-8")
|
|
|
+ .replace("##试卷名称##", General.XMLEncode(paper.getName()))
|
|
|
+ .replace("##试卷题头##", General.XMLEncode(paper.getHead()))
|
|
|
+ .replace("##课程名称##", General.XMLEncode(paper.getSkeleton().getCourse().getName()))
|
|
|
+ .replace("##课程代码##", General.XMLEncode(paper.getSkeleton().getCourse().getCode()))
|
|
|
+ .replace("##满分##", "100");
|
|
|
+ String xmlns_w15 = "xmlns:w15=\"http://schemas.microsoft.com/office/word/2012/wordml\"";
|
|
|
+ if (!docStr.contains(xmlns_w15)) {
|
|
|
+ docStr = docStr.replace("<w:document ", "<w:document " + xmlns_w15 + " ");
|
|
|
+ }
|
|
|
+ String xmlns_a = "xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"";
|
|
|
+ if (!docStr.contains(xmlns_a)) {
|
|
|
+ docStr = docStr.replace("<w:document ", "<w:document " + xmlns_a + " ");
|
|
|
+ }
|
|
|
+ fos = new FileOutputStream(document, false);
|
|
|
+ IOUtils.write(docStr, fos, "UTF-8");
|
|
|
+ } finally {
|
|
|
+ General.close(is);
|
|
|
+ General.close(fos);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ {
|
|
|
+ File document = templetDocxReader.getDocumentInfo().getFile();
|
|
|
+ FileOutputStream fosNew = null;
|
|
|
+ FileOutputStream fos = null;
|
|
|
+ InputStream is = null;
|
|
|
+ try {
|
|
|
+ is = new FileInputStream(document);
|
|
|
+ String docStr = IOUtils.toString(is, "UTF-8");
|
|
|
+ int index1 = docStr.indexOf("##试题开始##");// "##试题开始##"的位置
|
|
|
+ int index2 = docStr.substring(0, index1).lastIndexOf("<w:p ");// "##试题开始##"对应的<w:p>标签的开始位置
|
|
|
+ int index3 = index1 + docStr.substring(index1).indexOf("</w:p>");// "##试题开始##"对应的<w:p>标签的结束位置
|
|
|
+
|
|
|
+ int index4 = docStr.indexOf("##试题结束##");// "##试题结束##"的位置
|
|
|
+ int index5 = docStr.substring(0, index4).lastIndexOf("<w:p ");// "##试题结束##"对应的<w:p>标签的开始位置
|
|
|
+ int index6 = index4 + docStr.substring(index4).indexOf("</w:p>");// "##试题结束##"对应的<w:p>标签的结束位置
|
|
|
+
|
|
|
+ String head = docStr.substring(0, index2);// ##试题开始##"前面的部分
|
|
|
+ String quTmpStr = docStr.substring(index3 + "</w:p>".length(), index5);// 题目模板
|
|
|
+ String tail = docStr.substring(index6 + "</w:p>".length());// "##试题结束##"后面的部分
|
|
|
+
|
|
|
+ int index7 = quTmpStr.indexOf("##小题序号##");
|
|
|
+ int index8 = quTmpStr.substring(0, index7).lastIndexOf("<w:p ");// 小题对应的<w:p>标签的开始位置
|
|
|
+ int index9 = index7 + quTmpStr.substring(index7).indexOf("</w:p>");// 小题对应的<w:p>标签的结束位置
|
|
|
+
|
|
|
+ int index10 = quTmpStr.indexOf("##答题项##");
|
|
|
+ // int index11 =
|
|
|
+ // quTmpStr.substring(0,index10).lastIndexOf("<w:p ");//答题项对应的<w:p>标签的开始位置
|
|
|
+ int index12 = index10 + quTmpStr.substring(index10).indexOf("</w:p>");// 答题项对应的<w:p>标签的结束位置
|
|
|
+
|
|
|
+ fosNew = new FileOutputStream(document, false);
|
|
|
+ IOUtils.write(head, fosNew, "UTF-8");
|
|
|
+ General.close(fosNew);
|
|
|
+
|
|
|
+ fos = new FileOutputStream(document, true);
|
|
|
+
|
|
|
+ String qtTmpHeadStr = quTmpStr.substring(0, index8);
|
|
|
+ String qtTmpTailStr = quTmpStr.substring(index12 + "</w:p>".length());
|
|
|
+ String xtTmpStr = quTmpStr.substring(index8, index9 + "</w:p>".length());
|
|
|
+
|
|
|
+ // String anTmpStr = quTmpStr.substring(index11,index12 +
|
|
|
+ // "</w:p>".length());
|
|
|
+ int quNo = 0;
|
|
|
+ for (int i = 0; i < paper.getQtypeList().size(); i++) {
|
|
|
+ PagerConstructQtype qtyp = paper.getQtypeList().get(i);
|
|
|
+ String str1= General.toCNLowerNum(i + 1) + "、" + General.XMLEncode(qtyp.getName())
|
|
|
+ + ":本大题共" + qtyp.getQuestionSum() + "小题," + ((qtyp.getQuestionSum() > 1)?"每小题":"")
|
|
|
+ + General.formatScore(qtyp.getScore()) + "分"
|
|
|
+ + ((qtyp.getQuestionSum() > 1) ? ",共" + General.formatScore(qtyp.getQuestionScores()) + "分" : "")
|
|
|
+ + "。";
|
|
|
+ String qtypStr = qtTmpHeadStr
|
|
|
+ .replace("##大题描述##", str1)
|
|
|
+ .replace("##大题序号##", General.toCNLowerNum(i + 1))
|
|
|
+ .replace("##大题名称##", General.XMLEncode(qtyp.getName()))
|
|
|
+ .replace("##小题数##", "" + qtyp.getQuestionSum())
|
|
|
+ .replace("##小题分##", "" + General.formatScore(qtyp.getScore()))
|
|
|
+ .replace("##小题总分##", "" + General.formatScore(qtyp.getQuestionScores()))
|
|
|
+ .replace("##题型说明##",General.convertNullToEmpty(qtyp.getQuestionType().getRemark()));
|
|
|
+ IOUtils.write(qtypStr, fos, "UTF-8");
|
|
|
+ for (int j = 0; j < qtyp.getConstructDetails().size(); j++) {
|
|
|
+ PagerConstructDetail d = qtyp.getConstructDetails().get(j);
|
|
|
+ quNo++;
|
|
|
+ Question qu = d.getQuestion();
|
|
|
+ if (qu == null) {
|
|
|
+ qu = new Question();
|
|
|
+ qu.setBodySummary("空题");
|
|
|
+ }
|
|
|
+ log.info("正在处理试题:id = " + qu.getId());
|
|
|
+ String xtStr = null;
|
|
|
+ if ((qu.getBodyWord() == null || qu.getBodyWord().length == 0)
|
|
|
+ && General.isEmpty(qu.getBody())) {
|
|
|
+ xtStr = xtTmpStr.replace("##小题序号##", "" + toQuesNumStr(quNo)).replace("##题干##",
|
|
|
+ General.XMLEncode(qu.getBodySummary()).trim());
|
|
|
+ } else {
|
|
|
+ try {
|
|
|
+ byte[] wordBytes = null;
|
|
|
+ if ((qu.getBodyWord() == null || qu.getBodyWord().length == 0)
|
|
|
+ && !General.isEmpty(qu.getBody())) {
|
|
|
+ wordBytes = General.htmlToDocx(qu.getBody());
|
|
|
+ } else {
|
|
|
+ wordBytes = qu.getBodyWord();
|
|
|
+ }
|
|
|
+ xtStr = General.dealWord(wordBytes, templetDocxReader, needToUpdate);
|
|
|
+
|
|
|
+ int firstWtBeginIndex = xtStr.indexOf("<w:t>");
|
|
|
+ int firstWtBeginIndex2 = xtStr.indexOf("<w:t ");
|
|
|
+ firstWtBeginIndex = (firstWtBeginIndex < 0 || (firstWtBeginIndex2 >= 0 && firstWtBeginIndex > firstWtBeginIndex2))?firstWtBeginIndex2:firstWtBeginIndex;
|
|
|
+
|
|
|
+ int nearestGtIndex = xtStr.indexOf('>', firstWtBeginIndex + 1);
|
|
|
+
|
|
|
+ String part1 = xtStr.substring(0, nearestGtIndex + 1).trim();
|
|
|
+ String part2 = xtStr.substring(nearestGtIndex + 1).trim();
|
|
|
+ xtStr = part1 + toQuesNumStr(quNo) + "." + part2;
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("获取试题[" + qu.getId() + "]的Word信息失败,原因:" + e.getMessage(), e);
|
|
|
+ xtStr = Consts.ERR_P_TMP.replace("XX",
|
|
|
+ quNo + "." + String.format(Consts.ERR_QUS_MSG, qu.getId() + ""));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //xtStr = dealFormula(xtStr);
|
|
|
+ int firstWtBeginIndex1 = xtStr.indexOf("<w:t>");
|
|
|
+ int firstWtBeginIndex2 = xtStr.indexOf("<w:t ");
|
|
|
+ int firstWtEndIndex1 = xtStr.indexOf("</w:t>");
|
|
|
+ firstWtBeginIndex1 = (firstWtBeginIndex1 < 0 || (firstWtBeginIndex2 >= 0 && firstWtBeginIndex1 > firstWtBeginIndex2))?firstWtBeginIndex2:firstWtBeginIndex1;
|
|
|
+ int nearestGtIndex = xtStr.indexOf('>', firstWtBeginIndex1 + 1);
|
|
|
+ //int wtLen = xtStr.substring(nearestGtIndex, firstWtEndIndex1).length();
|
|
|
+ //int wt_real_len = getQuestionBodyLength(xtStr.substring(nearestGtIndex, firstWtEndIndex1));
|
|
|
+ int optSize = (qu.getOptions() != null) ? qu.getOptions().size() : 0;
|
|
|
+ if (optSize > 0) {
|
|
|
+ String option_temp = null;
|
|
|
+ if (optSize <= 4) {
|
|
|
+ xtStr = xtStr.replaceAll("<w:pPr>", "<w:pPr><w:tabs><w:tab w:val=\"left\" w:pos=\"7329\"/></w:tabs>");
|
|
|
+ option_temp = "<w:r><w:tab/></w:r><w:r><w:t>【 】</w:t></w:r></w:p>";
|
|
|
+ String before_str = StringUtils.substringBeforeLast(xtStr, "</w:p>");
|
|
|
+ String after_str = StringUtils.substringAfterLast(xtStr, "</w:p>");
|
|
|
+ xtStr = before_str + option_temp + after_str;
|
|
|
+ } else {
|
|
|
+ xtStr = xtStr.replaceAll("<w:pPr>", "<w:pPr><w:tabs><w:tab w:val=\"left\" w:pos=\"7119\"/></w:tabs>");
|
|
|
+ option_temp = "<w:r><w:tab/></w:r><w:r><w:t>【 】</w:t></w:r></w:p>";
|
|
|
+ String before_str = StringUtils.substringBeforeLast(xtStr, "</w:p>");
|
|
|
+ String after_str = StringUtils.substringAfterLast(xtStr, "</w:p>");
|
|
|
+ xtStr = before_str + option_temp + after_str;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ IOUtils.write(addBeforeLines(xtStr,0,0,0), fos, "UTF-8");
|
|
|
+ if (optSize > 0) {
|
|
|
+ int optTxtMaxLen = 0;
|
|
|
+ for (QuestionOption opt : qu.getOptions()) {
|
|
|
+ String optTxt = General.convertNullToEmpty(opt.getSummary()).trim();
|
|
|
+ if (optTxt.length() > optTxtMaxLen) {
|
|
|
+ optTxtMaxLen = optTxt.length();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (optTxtMaxLen == 0) {
|
|
|
+ optTxtMaxLen = 10;
|
|
|
+ }
|
|
|
+ String anTblTmp = null;
|
|
|
+ if (optSize == 4) {
|
|
|
+ if (optTxtMaxLen <= 8) {
|
|
|
+ anTblTmp = Consts.OPT_TABLE_TMP_1;
|
|
|
+ } else if (optTxtMaxLen <= 16) {
|
|
|
+ anTblTmp = Consts.OPT_TABLE_TMP_2;
|
|
|
+ } else {
|
|
|
+ anTblTmp = Consts.OPT_TABLE_TMP_4X1;
|
|
|
+ }
|
|
|
+ } else if (optSize == 5) {
|
|
|
+ if (optTxtMaxLen <= 11) {
|
|
|
+ anTblTmp = Consts.OPT_TABLE_TMP_3;
|
|
|
+ }else{
|
|
|
+ anTblTmp = Consts.OPT_TABLE_TMP_5X1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ String optsStr = null;
|
|
|
+ /**暂时屏蔽表格方式显示选项
|
|
|
+ if ((optSize == 4 || optSize == 5) && anTblTmp != null) {
|
|
|
+ optsStr = anTblTmp;
|
|
|
+ } else {
|
|
|
+ optsStr = "";
|
|
|
+ }
|
|
|
+ **/
|
|
|
+ optsStr = "";
|
|
|
+ for (int m = 0; m < optSize; m++) {
|
|
|
+ QuestionOption opt = qu.getOptions().get(m);
|
|
|
+ String seqNum = String.valueOf(((char) ('A' + m)));
|
|
|
+ String prefixStr = " " + seqNum + ".";
|
|
|
+ String anStr = null;
|
|
|
+ log.info("正在处理答题项:id = " + opt.getId());
|
|
|
+ if ((opt.getContentWord() == null || opt.getContentWord().length == 0)
|
|
|
+ && General.isEmpty(opt.getContent())) {
|
|
|
+ String optTxt = General.XMLEncode(opt.getSummary()).trim();
|
|
|
+ anStr = Consts.NORMAL_P_TMP.replace("XX", prefixStr + optTxt);
|
|
|
+ } else {
|
|
|
+ try {
|
|
|
+ byte[] wordBytes = null;
|
|
|
+ if ((opt.getContentWord() == null || opt.getContentWord().length == 0)
|
|
|
+ &&!General.isEmpty(opt.getContent())) {
|
|
|
+ wordBytes = General.htmlToDocx(opt.getContent());
|
|
|
+ } else {
|
|
|
+ wordBytes = opt.getContentWord();
|
|
|
+ }
|
|
|
+ anStr = General.dealWord(wordBytes, templetDocxReader, needToUpdate);
|
|
|
+ // int firstWtBeginIndex =
|
|
|
+ // anStr.indexOf("<w:t>");
|
|
|
+ int firstWtBeginIndex = -1;
|
|
|
+ if (firstWtBeginIndex < 0) {
|
|
|
+ int firstWpBeginIndex = anStr.indexOf(">");// 默认第一个节点是<w:p
|
|
|
+ // ...>,不支持答题项第一个元素是表格
|
|
|
+ String part1 = anStr.substring(0, firstWpBeginIndex + ">".length()).trim();
|
|
|
+ String part2 = anStr.substring(firstWpBeginIndex + ">".length())
|
|
|
+ .replace("\"center\"", "\"left\"")
|
|
|
+ .replace("\"right\"", "\"left\"").trim();
|
|
|
+ anStr = part1 + part2;
|
|
|
+ /*****
|
|
|
+ * 往anStr里面添加<w:jc
|
|
|
+ * w:val="left"/>
|
|
|
+ *****/
|
|
|
+ {
|
|
|
+ if (!anStr.contains("<w:jc w:val=\"left\"/>")) {
|
|
|
+ int pPrIndex = anStr.indexOf("<w:pPr>");
|
|
|
+ if (pPrIndex < 0) {
|
|
|
+ anStr = part1 + "<w:pPr><w:jc w:val=\"left\"/></w:pPr>" + part2;
|
|
|
+ } else {
|
|
|
+ anStr = anStr.substring(0, pPrIndex + "<w:pPr>".length())
|
|
|
+ + "<w:jc w:val=\"left\"/>"
|
|
|
+ + anStr.substring(pPrIndex + "<w:pPr>".length());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ anStr = anStr.replaceAll("</w:pPr>", "</w:pPr><w:r><w:t>" + prefixStr + "</w:t></w:r>");
|
|
|
+ } else {
|
|
|
+ // String part1 =
|
|
|
+ // anStr.substring(0,
|
|
|
+ // firstWtBeginIndex +
|
|
|
+ // "<w:t>".length());
|
|
|
+ // String part2 =
|
|
|
+ // anStr.substring(firstWtBeginIndex
|
|
|
+ // + "<w:t>".length());
|
|
|
+ // anStr = part1 + ((char)('A' +
|
|
|
+ // m)) + "." + part2;
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("获取试题选项[" + opt.getId() + "]的Word信息失败,原因:" + e.getMessage(), e);
|
|
|
+ anStr = Consts.ERR_P_TMP.replace("XX",
|
|
|
+ prefixStr + String.format(Consts.ERR_QUS_OPT_MSG, qu.getId() + ""));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /**暂时屏蔽表格方式显示选项
|
|
|
+ if ((optSize == 4 || optSize == 5) && anTblTmp != null) {
|
|
|
+ optsStr = optsStr.replace(seqNum + "_" + seqNum + ".", anStr);
|
|
|
+ } else {
|
|
|
+ optsStr = optsStr + anStr;
|
|
|
+ }
|
|
|
+ **/
|
|
|
+ //anStr = dealFormula(anStr);
|
|
|
+ optsStr = optsStr + addBeforeLines(anStr,0,0,0);
|
|
|
+ }
|
|
|
+ optsStr = compressOption(optsStr, optSize);
|
|
|
+ IOUtils.write(optsStr, fos, "UTF-8");
|
|
|
+ }
|
|
|
+ IOUtils.write(qtTmpTailStr, fos, "UTF-8");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ IOUtils.write(tail, fos, "UTF-8");
|
|
|
+ } finally {
|
|
|
+ General.close(is);
|
|
|
+ General.close(fosNew);
|
|
|
+ General.close(fos);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ {
|
|
|
+ File document = templetDocxReader.getDocumentInfo().getFile();
|
|
|
+ FileOutputStream fos = null;
|
|
|
+ InputStream is = null;
|
|
|
+ try {
|
|
|
+ is = new FileInputStream(document);
|
|
|
+ String docStr = IOUtils
|
|
|
+ .toString(is, "UTF-8")
|
|
|
+ .replace("<pic:pic>",
|
|
|
+ "<pic:pic xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">")
|
|
|
+ .replace("<w15:collapsed w:val=\"false\"/>", "");
|
|
|
+
|
|
|
+ // String xmlns_a =
|
|
|
+ // "xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"";
|
|
|
+ // if(!docStr.contains(xmlns_a)){
|
|
|
+ // docStr = docStr.replace("<w:document ", "<w:document " +
|
|
|
+ // xmlns_a + " ");
|
|
|
+ // }
|
|
|
+ fos = new FileOutputStream(document, false);
|
|
|
+ IOUtils.write(docStr, fos, "UTF-8");
|
|
|
+ } finally {
|
|
|
+ General.close(is);
|
|
|
+ General.close(fos);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ {
|
|
|
+ DocxReader.updateDocx(newDocx, needToUpdate);
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("生成试卷[" + paper.getId() + "]的Word文档失败,原因:" + e.getMessage(), e);
|
|
|
+ throw new BizException(e.getMessage(), e);
|
|
|
+ } finally {
|
|
|
+ General.release(templetDocxReader);
|
|
|
+ }
|
|
|
+ if(ParamUtils.NeedCheckWordVersion){
|
|
|
+ General.setDocxDefinedAttr(newDocx, Consts.DOCX_VERSION, "QMTH" + System.currentTimeMillis());// 往新生成的Word里面打个版本号:当前时间
|
|
|
+ }
|
|
|
+ return newDocx;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * <p>旧版本的网评卷导出,已作废</p>
|
|
|
+ * <p>新模板</p>
|
|
|
+ * @author songyue
|
|
|
+ * @date 2016-06-24
|
|
|
+ */
|
|
|
+ @Deprecated
|
|
|
+ public File generalWangPingPaperFile_disabled(PagerConstruct paper) throws BizException {
|
|
|
+ File newDocx = null;
|
|
|
+ DocxReader templetDocxReader = null;
|
|
|
+ Map<String, ResourceInfo> needToUpdate = new HashMap<String, ResourceInfo>();
|
|
|
+ try {
|
|
|
+ {// 拷贝一份模板文件到临时文件夹里面
|
|
|
+ FileOutputStream fos = null;
|
|
|
+ InputStream is = null;
|
|
|
+ try {
|
|
|
+ newDocx = new File(ParamUtils.TemporaryDirPath, UUID.randomUUID().toString().replace("-", ""));
|
|
|
+ fos = new FileOutputStream(newDocx);
|
|
|
+ is = ZujuanService.class.getResourceAsStream("/paperTmps/wangpingPagerTmp1.docx");
|
|
|
+ IOUtils.copyLarge(is, fos);
|
|
|
+ fos.flush();
|
|
|
+ } finally {
|
|
|
+ General.close(is);
|
|
|
+ General.close(fos);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ templetDocxReader = new DocxReader(newDocx);
|
|
|
+ templetDocxReader.doRead();
|
|
|
+ {
|
|
|
+ List<ResourceInfo> headersAndFooters = new ArrayList<ResourceInfo>();
|
|
|
+ headersAndFooters.addAll(templetDocxReader.getHeaders());
|
|
|
+ headersAndFooters.addAll(templetDocxReader.getFooters());
|
|
|
+ for (ResourceInfo info : headersAndFooters) {
|
|
|
+ FileOutputStream fos = null;
|
|
|
+ InputStream is = null;
|
|
|
+ try {
|
|
|
+ is = new FileInputStream(info.getFile());
|
|
|
+ String docStr = IOUtils.toString(is, "UTF-8").replace("课程名称",
|
|
|
+ General.XMLEncode(paper.getSkeleton().getCourse().getName()));
|
|
|
+ fos = new FileOutputStream(info.getFile(), false);
|
|
|
+ IOUtils.write(docStr, fos, "UTF-8");
|
|
|
+ } finally {
|
|
|
+ General.close(is);
|
|
|
+ General.close(fos);
|
|
|
+ }
|
|
|
+ needToUpdate.put(info.getPathInZip(), info);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ {
|
|
|
+ needToUpdate.put(templetDocxReader.getDocumentInfo().getPathInZip(),
|
|
|
+ templetDocxReader.getDocumentInfo());
|
|
|
+ File document = templetDocxReader.getDocumentInfo().getFile();
|
|
|
+ FileOutputStream fos = null;
|
|
|
+ InputStream is = null;
|
|
|
+ try {
|
|
|
+ is = new FileInputStream(document);
|
|
|
+ String docStr = IOUtils.toString(is, "UTF-8")
|
|
|
+ .replace("课程名称", General.XMLEncode(paper.getSkeleton().getCourse().getName()))
|
|
|
+ .replace("课程代码一", General.XMLEncode(paper.getSkeleton().getCourse().getCode()))
|
|
|
+ .replace("非选择题总分", General.formatScore(getQuestionScore(paper, "nonchoice")))
|
|
|
+ .replace("选择题总分", General.formatScore(getQuestionScore(paper, "choice")));
|
|
|
+
|
|
|
+ String xmlns_w15 = "xmlns:w15=\"http://schemas.microsoft.com/office/word/2012/wordml\"";
|
|
|
+ if (!docStr.contains(xmlns_w15)) {
|
|
|
+ docStr = docStr.replace("<w:document ", "<w:document " + xmlns_w15 + " ");
|
|
|
+ }
|
|
|
+ String xmlns_a = "xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"";
|
|
|
+ if (!docStr.contains(xmlns_a)) {
|
|
|
+ docStr = docStr.replace("<w:document ", "<w:document " + xmlns_a + " ");
|
|
|
+ }
|
|
|
+ fos = new FileOutputStream(document, false);
|
|
|
+ IOUtils.write(docStr, fos, "UTF-8");
|
|
|
+ } finally {
|
|
|
+ General.close(is);
|
|
|
+ General.close(fos);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ {
|
|
|
+ File document = templetDocxReader.getDocumentInfo().getFile();
|
|
|
+ FileOutputStream fosNew = null;
|
|
|
+ FileOutputStream fos = null;
|
|
|
+ InputStream is = null;
|
|
|
+ try {
|
|
|
+ is = new FileInputStream(document);
|
|
|
+ String docStr = IOUtils.toString(is, "UTF-8");
|
|
|
+ int index1 = docStr.indexOf("选择题开始");// "选择题开始"的位置
|
|
|
+ int index2 = docStr.substring(0, index1).lastIndexOf("<w:p ");// "选择题开始"对应的<w:p>标签的开始位置
|
|
|
+
|
|
|
+ int index4 = docStr.indexOf("非选择题结束");// "非选择题结束"的位置
|
|
|
+ int index6 = index4 + docStr.substring(index4).indexOf("</w:p>");// "非选择题结束"对应的<w:p>标签的结束位置
|
|
|
+
|
|
|
+ String head = docStr.substring(0, index2);// 选择题开始"前面的部分
|
|
|
+ String tail = docStr.substring(index6 + "</w:p>".length());// "非选择题结束"后面的部分
|
|
|
+
|
|
|
+ fosNew = new FileOutputStream(document, false);
|
|
|
+ IOUtils.write(head, fosNew, "UTF-8");
|
|
|
+ General.close(fosNew);
|
|
|
+
|
|
|
+ fos = new FileOutputStream(document, true);
|
|
|
+
|
|
|
+ int quNo = 0;
|
|
|
+ int choice_index1 = docStr.indexOf("选择题开始");// "选择题开始"的位置
|
|
|
+ int choice_index3 = choice_index1 + docStr.substring(choice_index1).indexOf("</w:p>");// "选择题开始"对应的<w:p>标签的结束位置
|
|
|
+ int choice_index4 = docStr.indexOf("选择题结束");// "选择题结束"的位置
|
|
|
+ int choice_index5 = docStr.substring(0, choice_index4).lastIndexOf("<w:p ");// "选择题结束"对应的<w:p>标签的开始位置
|
|
|
+ int choice_index6 = choice_index4 + docStr.substring(choice_index4).indexOf("</w:p>")
|
|
|
+ + "</w:p>".length();// "选择题结束"的</w:p>位置
|
|
|
+ String choice_quTmpStr = docStr.substring(choice_index3 + "</w:p>".length(), choice_index5);// 选择题目模板
|
|
|
+ int choice_index7 = choice_quTmpStr.indexOf("小题序号");
|
|
|
+ int choice_index8 = choice_quTmpStr.substring(0, choice_index7).lastIndexOf("<w:p ");// 小题对应的<w:p>标签的开始位置
|
|
|
+ int choice_index9 = choice_index7 + choice_quTmpStr.substring(choice_index7).indexOf("</w:p>");// 小题对应的<w:p>标签的结束位置
|
|
|
+
|
|
|
+ int choice_index10 = choice_quTmpStr.indexOf("答题项");
|
|
|
+ int choice_index12 = choice_index10 + choice_quTmpStr.substring(choice_index10).indexOf("</w:p>");// 答题项对应的<w:p>标签的结束位置
|
|
|
+ String choice_qtTmpHeadStr = choice_quTmpStr.substring(0, choice_index8);
|
|
|
+ String choice_qtTmpTailStr = choice_quTmpStr.substring(choice_index12 + "</w:p>".length());
|
|
|
+ String choice_xtTmpStr = choice_quTmpStr.substring(choice_index8,
|
|
|
+ choice_index9 + "</w:p>".length());
|
|
|
+ // 选择题
|
|
|
+ for (int i = 0; i < paper.getQtypeList().size(); i++) {
|
|
|
+ PagerConstructQtype qtyp = paper.getQtypeList().get(i);
|
|
|
+
|
|
|
+ if (qtyp.getName().contains("选择题")) {
|
|
|
+ String choice_str1 = General.toCNLowerNum(i + 1) + "、" + General.XMLEncode(qtyp.getName())
|
|
|
+ + ":本大题共" + qtyp.getQuestionSum() + "小题,"
|
|
|
+ + ((qtyp.getQuestionSum() > 1) ? "每小题" : "") + General.formatScore(qtyp.getScore())
|
|
|
+ + "分" + ((qtyp.getQuestionSum() > 1)
|
|
|
+ ? ",共" + General.formatScore(qtyp.getQuestionScores()) + "分" : "")
|
|
|
+ + "。";
|
|
|
+ String choice_qtypStr = choice_qtTmpHeadStr.replace("大题描述", choice_str1)
|
|
|
+ .replace("大题序号", General.toCNLowerNum(i + 1))
|
|
|
+ .replace("大题名称", General.XMLEncode(qtyp.getName()))
|
|
|
+ .replace("小题数", "" + qtyp.getQuestionSum())
|
|
|
+ .replace("小题分", "" + General.formatScore(qtyp.getScore()))
|
|
|
+ .replace("小题总分", "" + General.formatScore(qtyp.getQuestionScores()))
|
|
|
+ .replace("题型说明", General.convertNullToEmpty(qtyp.getQuestionType().getRemark()));
|
|
|
+ IOUtils.write(choice_qtypStr, fos, "UTF-8");
|
|
|
+ for (int j = 0; j < qtyp.getConstructDetails().size(); j++) {
|
|
|
+ PagerConstructDetail d = qtyp.getConstructDetails().get(j);
|
|
|
+ quNo++;
|
|
|
+ Question qu = d.getQuestion();
|
|
|
+ if (qu == null) {
|
|
|
+ qu = new Question();
|
|
|
+ qu.setBodySummary("空题");
|
|
|
+ }
|
|
|
+ log.info("正在处理试题:id = " + qu.getId());
|
|
|
+ String xtStr = null;
|
|
|
+ if ((qu.getBodyWord() == null || qu.getBodyWord().length == 0)
|
|
|
+ && General.isEmpty(qu.getBody())) {
|
|
|
+ xtStr = choice_xtTmpStr.replace("小题序号", "" + toQuesNumStr(quNo)).replace("题干",
|
|
|
+ General.XMLEncode(qu.getBodySummary()).trim());
|
|
|
+ } else {
|
|
|
+ try {
|
|
|
+ byte[] wordBytes = null;
|
|
|
+ if ((qu.getBodyWord() == null || qu.getBodyWord().length == 0)
|
|
|
+ && !General.isEmpty(qu.getBody())) {
|
|
|
+ wordBytes = General.htmlToDocx(qu.getBody());
|
|
|
+ } else {
|
|
|
+ wordBytes = qu.getBodyWord();
|
|
|
+ }
|
|
|
+ xtStr = General.dealWord(wordBytes, templetDocxReader, needToUpdate);
|
|
|
+
|
|
|
+ int firstWtBeginIndex = xtStr.indexOf("<w:t>");
|
|
|
+ int firstWtBeginIndex2 = xtStr.indexOf("<w:t ");
|
|
|
+ firstWtBeginIndex = (firstWtBeginIndex < 0
|
|
|
+ || (firstWtBeginIndex2 >= 0 && firstWtBeginIndex > firstWtBeginIndex2))
|
|
|
+ ? firstWtBeginIndex2 : firstWtBeginIndex;
|
|
|
+
|
|
|
+ int nearestGtIndex = xtStr.indexOf('>', firstWtBeginIndex + 1);
|
|
|
+
|
|
|
+ String part1 = xtStr.substring(0, nearestGtIndex + 1).trim();
|
|
|
+ String part2 = xtStr.substring(nearestGtIndex + 1).trim();
|
|
|
+ xtStr = part1 + toQuesNumStr(quNo) + "." + part2;
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("获取试题[" + qu.getId() + "]的Word信息失败,原因:" + e.getMessage(), e);
|
|
|
+ xtStr = Consts.ERR_P_TMP.replace("XX",
|
|
|
+ quNo + "." + String.format(Consts.ERR_QUS_MSG, qu.getId() + ""));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ int firstWtBeginIndex1 = xtStr.indexOf("<w:t>");
|
|
|
+ int firstWtBeginIndex2 = xtStr.indexOf("<w:t ");
|
|
|
+ int firstWtEndIndex1 = xtStr.indexOf("</w:t>");
|
|
|
+ firstWtBeginIndex1 = (firstWtBeginIndex1 < 0
|
|
|
+ || (firstWtBeginIndex2 >= 0 && firstWtBeginIndex1 > firstWtBeginIndex2))
|
|
|
+ ? firstWtBeginIndex2 : firstWtBeginIndex1;
|
|
|
+ int nearestGtIndex = xtStr.indexOf('>', firstWtBeginIndex1 + 1);
|
|
|
+ //int wtLen = xtStr.substring(nearestGtIndex, firstWtEndIndex1).length();
|
|
|
+ //int wt_real_len = getQuestionBodyLength(xtStr.substring(nearestGtIndex, firstWtEndIndex1));
|
|
|
+ int optSize = (qu.getOptions() != null) ? qu.getOptions().size() : 0;
|
|
|
+ if (optSize > 0) {
|
|
|
+ String option_temp = null;
|
|
|
+ if (optSize <= 4) {
|
|
|
+ xtStr = xtStr.replaceAll("<w:pPr>", "<w:pPr><w:tabs><w:tab w:val=\"left\" w:pos=\"7329\"/></w:tabs>");
|
|
|
+ option_temp = "<w:r><w:tab/></w:r><w:r><w:t>【 】</w:t></w:r></w:p>";
|
|
|
+ String before_str = StringUtils.substringBeforeLast(xtStr, "</w:p>");
|
|
|
+ String after_str = StringUtils.substringAfterLast(xtStr, "</w:p>");
|
|
|
+ xtStr = before_str + option_temp + after_str;
|
|
|
+ } else {
|
|
|
+ xtStr = xtStr.replaceAll("<w:pPr>", "<w:pPr><w:tabs><w:tab w:val=\"left\" w:pos=\"7119\"/></w:tabs>");
|
|
|
+ option_temp = "<w:r><w:tab/></w:r><w:r><w:t>【 】</w:t></w:r></w:p>";
|
|
|
+ String before_str = StringUtils.substringBeforeLast(xtStr, "</w:p>");
|
|
|
+ String after_str = StringUtils.substringAfterLast(xtStr, "</w:p>");
|
|
|
+ xtStr = before_str + option_temp + after_str;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //xtStr = dealFormula(xtStr);
|
|
|
+ IOUtils.write(addBeforeLines(xtStr, 0, 0, 0), fos, "UTF-8");
|
|
|
+ if (optSize > 0) {
|
|
|
+ String optsStr = "";
|
|
|
+ for (int m = 0; m < optSize; m++) {
|
|
|
+ QuestionOption opt = qu.getOptions().get(m);
|
|
|
+ String seqNum = String.valueOf(((char) ('A' + m)));
|
|
|
+ String prefixStr = " " + seqNum + ".";
|
|
|
+ String anStr = null;
|
|
|
+ log.info("正在处理答题项:id = " + opt.getId());
|
|
|
+ if ((opt.getContentWord() == null || opt.getContentWord().length == 0)
|
|
|
+ && General.isEmpty(opt.getContent())) {
|
|
|
+ String optTxt = General.XMLEncode(opt.getSummary()).trim();
|
|
|
+ anStr = Consts.NORMAL_P_TMP.replace("XX", prefixStr + optTxt);
|
|
|
+ } else {
|
|
|
+ try {
|
|
|
+ byte[] wordBytes = null;
|
|
|
+ if ((opt.getContentWord() == null || opt.getContentWord().length == 0)
|
|
|
+ && !General.isEmpty(opt.getContent())) {
|
|
|
+ wordBytes = General.htmlToDocx(opt.getContent());
|
|
|
+ } else {
|
|
|
+ wordBytes = opt.getContentWord();
|
|
|
+ }
|
|
|
+ anStr = General.dealWord(wordBytes, templetDocxReader, needToUpdate);
|
|
|
+ int firstWtBeginIndex = -1;
|
|
|
+ if (firstWtBeginIndex < 0) {
|
|
|
+ int firstWpBeginIndex = anStr.indexOf(">");// 默认第一个节点是<w:p
|
|
|
+ // ...>,不支持答题项第一个元素是表格
|
|
|
+ String part1 = anStr.substring(0, firstWpBeginIndex + ">".length())
|
|
|
+ .trim();
|
|
|
+ String part2 = anStr.substring(firstWpBeginIndex + ">".length())
|
|
|
+ .replace("\"center\"", "\"left\"")
|
|
|
+ .replace("\"right\"", "\"left\"").trim();
|
|
|
+ anStr = part1 + part2;
|
|
|
+ /*****
|
|
|
+ * 往anStr里面添加
|
|
|
+ * <w:jc w:val="left"/>
|
|
|
+ *****/
|
|
|
+ {
|
|
|
+ if (!anStr.contains("<w:jc w:val=\"left\"/>")) {
|
|
|
+ int pPrIndex = anStr.indexOf("<w:pPr>");
|
|
|
+ if (pPrIndex < 0) {
|
|
|
+ anStr = part1 + "<w:pPr><w:jc w:val=\"left\"/></w:pPr>" + part2;
|
|
|
+ } else {
|
|
|
+ anStr = anStr.substring(0,
|
|
|
+ pPrIndex + "<w:pPr>".length())
|
|
|
+ + "<w:jc w:val=\"left\"/>" + anStr.substring(
|
|
|
+ pPrIndex + "<w:pPr>".length());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ anStr = anStr.replaceAll("</w:pPr>", "</w:pPr><w:r><w:t>" + prefixStr + "</w:t></w:r>");
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("获取试题选项[" + opt.getId() + "]的Word信息失败,原因:" + e.getMessage(),
|
|
|
+ e);
|
|
|
+ anStr = Consts.ERR_P_TMP.replace("XX", prefixStr
|
|
|
+ + String.format(Consts.ERR_QUS_OPT_MSG, qu.getId() + ""));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //anStr = dealFormula(anStr);
|
|
|
+ optsStr = optsStr + addBeforeLines(anStr, 0, 0, 0);
|
|
|
+ }
|
|
|
+ optsStr = compressOption(optsStr, optSize);
|
|
|
+ IOUtils.write(optsStr, fos, "UTF-8");
|
|
|
+ }
|
|
|
+ IOUtils.write(choice_qtTmpTailStr, fos, "UTF-8");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 非选择题
|
|
|
+ int non_choice_index1 = docStr.indexOf("非选择题开始");// "非选择题开始"的位置
|
|
|
+ int non_choice_index2 = docStr.substring(0, non_choice_index1).lastIndexOf("<w:p ");// "非选择题开始"<w:p>的位置
|
|
|
+ String non_choice_head = docStr.substring(choice_index6, non_choice_index2);// 第二部分
|
|
|
+ IOUtils.write(non_choice_head, fos, "UTF-8");
|
|
|
+ for (int i = 0; i < paper.getQtypeList().size(); i++) {
|
|
|
+ PagerConstructQtype qtyp = paper.getQtypeList().get(i);
|
|
|
+ if (!qtyp.getName().contains("选择题")) {
|
|
|
+
|
|
|
+ int non_choice_index3 = non_choice_index1
|
|
|
+ + docStr.substring(non_choice_index1).indexOf("</w:p>");// "非选择题开始"对应的<w:p>标签的结束位置
|
|
|
+
|
|
|
+ int non_choice_index4 = docStr.indexOf("非选择题结束");// "非选择题结束"的位置
|
|
|
+ int non_choice_index5 = docStr.substring(0, non_choice_index4).lastIndexOf("<w:p ");// "非选择题结束"对应的<w:p>标签的开始位置
|
|
|
+
|
|
|
+ String non_choice_quTmpStr = docStr.substring(non_choice_index3 + "</w:p>".length(),
|
|
|
+ non_choice_index5);// 非选择题目模板
|
|
|
+
|
|
|
+ int non_choice_index7 = non_choice_quTmpStr.indexOf("小题序号");
|
|
|
+ int non_choice_index8 = non_choice_quTmpStr.substring(0, non_choice_index7)
|
|
|
+ .lastIndexOf("<w:p ");// 小题对应的<w:p>标签的开始位置
|
|
|
+ int non_choice_index9 = non_choice_index7
|
|
|
+ + non_choice_quTmpStr.substring(non_choice_index7).indexOf("</w:p>");// 小题对应的<w:p>标签的结束位置
|
|
|
+
|
|
|
+ int non_choice_index10 = non_choice_quTmpStr.indexOf("答题项");
|
|
|
+ int non_choice_index12 = non_choice_index10
|
|
|
+ + non_choice_quTmpStr.substring(non_choice_index10).indexOf("</w:p>");// 答题项对应的<w:p>标签的结束位置
|
|
|
+ String non_choice_qtTmpHeadStr = non_choice_quTmpStr.substring(0, non_choice_index8);
|
|
|
+ String non_choice_qtTmpTailStr = non_choice_quTmpStr
|
|
|
+ .substring(non_choice_index12 + "</w:p>".length());
|
|
|
+ String non_choice_xtTmpStr = non_choice_quTmpStr.substring(non_choice_index8,
|
|
|
+ non_choice_index9 + "</w:p>".length());
|
|
|
+ String non_choice_str1 = General.toCNLowerNum(i + 1) + "、"
|
|
|
+ + General.XMLEncode(qtyp.getName()) + ":本大题共" + qtyp.getQuestionSum() + "小题,"
|
|
|
+ + ((qtyp.getQuestionSum() > 1) ? "每小题" : "") + General.formatScore(qtyp.getScore())
|
|
|
+ + "分" + ((qtyp.getQuestionSum() > 1)
|
|
|
+ ? ",共" + General.formatScore(qtyp.getQuestionScores()) + "分" : "")
|
|
|
+ + "。";
|
|
|
+ String non_choice_qtypStr = non_choice_qtTmpHeadStr.replace("大题描述", non_choice_str1)
|
|
|
+ .replace("大题序号", General.toCNLowerNum(i + 1))
|
|
|
+ .replace("大题名称", General.XMLEncode(qtyp.getName()))
|
|
|
+ .replace("小题数", "" + qtyp.getQuestionSum())
|
|
|
+ .replace("小题分", "" + General.formatScore(qtyp.getScore()))
|
|
|
+ .replace("小题总分", "" + General.formatScore(qtyp.getQuestionScores()))
|
|
|
+ .replace("题型说明", General.convertNullToEmpty(qtyp.getQuestionType().getRemark()));
|
|
|
+ IOUtils.write(non_choice_qtypStr, fos, "UTF-8");
|
|
|
+ for (int j = 0; j < qtyp.getConstructDetails().size(); j++) {
|
|
|
+ PagerConstructDetail d = qtyp.getConstructDetails().get(j);
|
|
|
+ quNo++;
|
|
|
+ Question qu = d.getQuestion();
|
|
|
+ if (qu == null) {
|
|
|
+ qu = new Question();
|
|
|
+ qu.setBodySummary("空题");
|
|
|
+ }
|
|
|
+ log.info("正在处理试题:id = " + qu.getId());
|
|
|
+ String xtStr = null;
|
|
|
+ if ((qu.getBodyWord() == null || qu.getBodyWord().length == 0)
|
|
|
+ && General.isEmpty(qu.getBody())) {
|
|
|
+ xtStr = non_choice_xtTmpStr.replace("小题序号", "" + toQuesNumStr(quNo)).replace("题干",
|
|
|
+ General.XMLEncode(qu.getBodySummary()).trim());
|
|
|
+ } else {
|
|
|
+ try {
|
|
|
+ byte[] wordBytes = null;
|
|
|
+ if ((qu.getBodyWord() == null || qu.getBodyWord().length == 0)
|
|
|
+ && !General.isEmpty(qu.getBody())) {
|
|
|
+ wordBytes = General.htmlToDocx(qu.getBody());
|
|
|
+ } else {
|
|
|
+ wordBytes = qu.getBodyWord();
|
|
|
+ }
|
|
|
+ xtStr = General.dealWord(wordBytes, templetDocxReader, needToUpdate);
|
|
|
+
|
|
|
+ int firstWtBeginIndex = xtStr.indexOf("<w:t>");
|
|
|
+ int firstWtBeginIndex2 = xtStr.indexOf("<w:t ");
|
|
|
+ firstWtBeginIndex = (firstWtBeginIndex < 0
|
|
|
+ || (firstWtBeginIndex2 >= 0 && firstWtBeginIndex > firstWtBeginIndex2))
|
|
|
+ ? firstWtBeginIndex2 : firstWtBeginIndex;
|
|
|
+
|
|
|
+ int nearestGtIndex = xtStr.indexOf('>', firstWtBeginIndex + 1);
|
|
|
+
|
|
|
+ String part1 = xtStr.substring(0, nearestGtIndex + 1).trim();
|
|
|
+ String part2 = xtStr.substring(nearestGtIndex + 1).trim();
|
|
|
+ xtStr = part1 + toQuesNumStr(quNo) + "." + part2;
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("获取试题[" + qu.getId() + "]的Word信息失败,原因:" + e.getMessage(), e);
|
|
|
+ xtStr = Consts.ERR_P_TMP.replace("XX",
|
|
|
+ quNo + "." + String.format(Consts.ERR_QUS_MSG, qu.getId() + ""));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ IOUtils.write(addBeforeLines(xtStr, 0, 0, 0), fos, "UTF-8");
|
|
|
+ IOUtils.write(non_choice_qtTmpTailStr, fos, "UTF-8");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ IOUtils.write(tail, fos, "UTF-8");
|
|
|
+ } finally {
|
|
|
+ General.close(is);
|
|
|
+ General.close(fosNew);
|
|
|
+ General.close(fos);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ {
|
|
|
+ File document = templetDocxReader.getDocumentInfo().getFile();
|
|
|
+ FileOutputStream fos = null;
|
|
|
+ InputStream is = null;
|
|
|
+ try {
|
|
|
+ is = new FileInputStream(document);
|
|
|
+ String docStr = IOUtils.toString(is, "UTF-8")
|
|
|
+ .replace("<pic:pic>",
|
|
|
+ "<pic:pic xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">")
|
|
|
+ .replace("<w15:collapsed w:val=\"false\"/>", "");
|
|
|
+ fos = new FileOutputStream(document, false);
|
|
|
+ IOUtils.write(docStr, fos, "UTF-8");
|
|
|
+ } finally {
|
|
|
+ General.close(is);
|
|
|
+ General.close(fos);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ {
|
|
|
+ DocxReader.updateDocx(newDocx, needToUpdate);
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("生成试卷[" + paper.getId() + "]的Word文档失败,原因:" + e.getMessage(), e);
|
|
|
+ throw new BizException(e.getMessage(), e);
|
|
|
+ } finally {
|
|
|
+ General.release(templetDocxReader);
|
|
|
+ }
|
|
|
+ if (ParamUtils.NeedCheckWordVersion) {
|
|
|
+ General.setDocxDefinedAttr(newDocx, Consts.DOCX_VERSION, "QMTH" + System.currentTimeMillis());// 往新生成的Word里面打个版本号:当前时间
|
|
|
+ }
|
|
|
+ return newDocx;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * <p>网评卷导出</p>
|
|
|
+ * <p>新模板</p>
|
|
|
+ * @author songyue
|
|
|
+ * @date 2016-06-24
|
|
|
+ */
|
|
|
+ public File generalWangPingPaperFile(PagerConstruct paper) throws BizException {
|
|
|
+ File newDocx = null;
|
|
|
+ DocxReader templetDocxReader = null;
|
|
|
+ Map<String, ResourceInfo> needToUpdate = new HashMap<String, ResourceInfo>();
|
|
|
+ try {
|
|
|
+ {// 拷贝一份模板文件到临时文件夹里面
|
|
|
+ FileOutputStream fos = null;
|
|
|
+ InputStream is = null;
|
|
|
+ try {
|
|
|
+ newDocx = new File(ParamUtils.TemporaryDirPath, UUID.randomUUID().toString().replace("-", ""));
|
|
|
+ fos = new FileOutputStream(newDocx);
|
|
|
+ is = ZujuanService.class.getResourceAsStream("/paperTmps/wangpingPagerTmp2.docx");
|
|
|
+ IOUtils.copyLarge(is, fos);
|
|
|
+ fos.flush();
|
|
|
+ } finally {
|
|
|
+ General.close(is);
|
|
|
+ General.close(fos);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ templetDocxReader = new DocxReader(newDocx);
|
|
|
+ templetDocxReader.doRead();
|
|
|
+ {
|
|
|
+ List<ResourceInfo> headersAndFooters = new ArrayList<ResourceInfo>();
|
|
|
+ headersAndFooters.addAll(templetDocxReader.getHeaders());
|
|
|
+ headersAndFooters.addAll(templetDocxReader.getFooters());
|
|
|
+ for (ResourceInfo info : headersAndFooters) {
|
|
|
+ FileOutputStream fos = null;
|
|
|
+ InputStream is = null;
|
|
|
+ try {
|
|
|
+ is = new FileInputStream(info.getFile());
|
|
|
+ String docStr = IOUtils.toString(is, "UTF-8").replace("课程名称",
|
|
|
+ General.XMLEncode(paper.getSkeleton().getCourse().getName()));
|
|
|
+ fos = new FileOutputStream(info.getFile(), false);
|
|
|
+ IOUtils.write(docStr, fos, "UTF-8");
|
|
|
+ } finally {
|
|
|
+ General.close(is);
|
|
|
+ General.close(fos);
|
|
|
+ }
|
|
|
+ needToUpdate.put(info.getPathInZip(), info);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ {
|
|
|
+ needToUpdate.put(templetDocxReader.getDocumentInfo().getPathInZip(),
|
|
|
+ templetDocxReader.getDocumentInfo());
|
|
|
+ File document = templetDocxReader.getDocumentInfo().getFile();
|
|
|
+ FileOutputStream fos = null;
|
|
|
+ InputStream is = null;
|
|
|
+ try {
|
|
|
+ is = new FileInputStream(document);
|
|
|
+ String docStr = IOUtils.toString(is, "UTF-8")
|
|
|
+ .replace("课程名称", General.XMLEncode(paper.getSkeleton().getCourse().getName()))
|
|
|
+ .replace("课程代码一", General.XMLEncode(paper.getSkeleton().getCourse().getCode()))
|
|
|
+ .replace("非选择题总分", General.formatScore(getQuestionScore(paper, "nonchoice")))
|
|
|
+ .replace("选择题总分", General.formatScore(getQuestionScore(paper, "choice")));
|
|
|
+
|
|
|
+ String xmlns_w15 = "xmlns:w15=\"http://schemas.microsoft.com/office/word/2012/wordml\"";
|
|
|
+ if (!docStr.contains(xmlns_w15)) {
|
|
|
+ docStr = docStr.replace("<w:document ", "<w:document " + xmlns_w15 + " ");
|
|
|
+ }
|
|
|
+ String xmlns_w14 = "xmlns:w14=\"http://schemas.microsoft.com/office/word/2010/wordml\"";
|
|
|
+ if (!docStr.contains(xmlns_w14)) {
|
|
|
+ docStr = docStr.replace("<w:document ", "<w:document " + xmlns_w14 + " ");
|
|
|
+ }
|
|
|
+ String xmlns_a = "xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"";
|
|
|
+ if (!docStr.contains(xmlns_a)) {
|
|
|
+ docStr = docStr.replace("<w:document ", "<w:document " + xmlns_a + " ");
|
|
|
+ }
|
|
|
+ fos = new FileOutputStream(document, false);
|
|
|
+ IOUtils.write(docStr, fos, "UTF-8");
|
|
|
+ } finally {
|
|
|
+ General.close(is);
|
|
|
+ General.close(fos);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ {
|
|
|
+ File document = templetDocxReader.getDocumentInfo().getFile();
|
|
|
+ FileOutputStream fosNew = null;
|
|
|
+ FileOutputStream fos = null;
|
|
|
+ InputStream is = null;
|
|
|
+ try {
|
|
|
+ is = new FileInputStream(document);
|
|
|
+ String docStr = IOUtils.toString(is, "UTF-8");
|
|
|
+ int index1 = docStr.indexOf("选择题开始");// "选择题开始"的位置
|
|
|
+ int index2 = docStr.substring(0, index1).lastIndexOf("<w:p ");// "选择题开始"对应的<w:p>标签的开始位置
|
|
|
+
|
|
|
+ int index4 = docStr.indexOf("非选择题结束");// "非选择题结束"的位置
|
|
|
+ int index6 = index4 + docStr.substring(index4).indexOf("</w:p>");// "非选择题结束"对应的<w:p>标签的结束位置
|
|
|
+
|
|
|
+ String head = docStr.substring(0, index2);// 选择题开始"前面的部分
|
|
|
+ String tail = docStr.substring(index6 + "</w:p>".length());// "非选择题结束"后面的部分
|
|
|
+
|
|
|
+ fosNew = new FileOutputStream(document, false);
|
|
|
+ IOUtils.write(head, fosNew, "UTF-8");
|
|
|
+ General.close(fosNew);
|
|
|
+
|
|
|
+ fos = new FileOutputStream(document, true);
|
|
|
+
|
|
|
+ int quNo = 0;
|
|
|
+ int choice_index1 = docStr.indexOf("选择题开始");// "选择题开始"的位置
|
|
|
+ int choice_index3 = choice_index1 + docStr.substring(choice_index1).indexOf("</w:p>");// "选择题开始"对应的<w:p>标签的结束位置
|
|
|
+ int choice_index4 = docStr.indexOf("选择题结束");// "选择题结束"的位置
|
|
|
+ int choice_index5 = docStr.substring(0, choice_index4).lastIndexOf("<w:p ");// "选择题结束"对应的<w:p>标签的开始位置
|
|
|
+ int choice_index6 = choice_index4 + docStr.substring(choice_index4).indexOf("</w:p>")
|
|
|
+ + "</w:p>".length();// "选择题结束"的</w:p>位置
|
|
|
+ String choice_quTmpStr = docStr.substring(choice_index3 + "</w:p>".length(), choice_index5);// 选择题目模板
|
|
|
+ int choice_index7 = choice_quTmpStr.indexOf("小题序号");
|
|
|
+ int choice_index8 = choice_quTmpStr.substring(0, choice_index7).lastIndexOf("<w:p ");// 小题对应的<w:p>标签的开始位置
|
|
|
+ int choice_index9 = choice_index7 + choice_quTmpStr.substring(choice_index7).indexOf("</w:p>");// 小题对应的<w:p>标签的结束位置
|
|
|
+
|
|
|
+ int choice_index10 = choice_quTmpStr.indexOf("答题项");
|
|
|
+ int choice_index12 = choice_index10 + choice_quTmpStr.substring(choice_index10).indexOf("</w:p>");// 答题项对应的<w:p>标签的结束位置
|
|
|
+ String choice_qtTmpHeadStr = choice_quTmpStr.substring(0, choice_index8);
|
|
|
+ String choice_qtTmpTailStr = choice_quTmpStr.substring(choice_index12 + "</w:p>".length());
|
|
|
+ String choice_xtTmpStr = choice_quTmpStr.substring(choice_index8,
|
|
|
+ choice_index9 + "</w:p>".length());
|
|
|
+ // 选择题
|
|
|
+ int qtypIndex = 0;
|
|
|
+ for (int index = 0; index < paper.getQtypeList().size(); index++) {
|
|
|
+ PagerConstructQtype qtyp = paper.getQtypeList().get(index);
|
|
|
+
|
|
|
+ if (qtyp.getName().contains("选择题")) {
|
|
|
+ String choice_str1 = General.toCNLowerNum(qtypIndex + 1) + "、" + General.XMLEncode(qtyp.getName())
|
|
|
+ + ":本大题共" + qtyp.getQuestionSum() + "小题,"
|
|
|
+ + ((qtyp.getQuestionSum() > 1) ? "每小题" : "") + General.formatScore(qtyp.getScore())
|
|
|
+ + "分" + ((qtyp.getQuestionSum() > 1)
|
|
|
+ ? ",共" + General.formatScore(qtyp.getQuestionScores()) + "分" : "")
|
|
|
+ + "。";
|
|
|
+ if(qtyp.getName().equals("单项选择题")){
|
|
|
+ choice_str1 = choice_str1 + "在每小题列出的备选项中只有一项是最符合题目要求的,请将其选出。";
|
|
|
+ }else if(qtyp.getName().equals("多项选择题")){
|
|
|
+ choice_str1 = choice_str1 + "在每小题列出的备选项中至少有两项是符合题目要求的,请将其选出,错选、多选或少选均无分。";
|
|
|
+ }
|
|
|
+ String choice_qtypStr = choice_qtTmpHeadStr.replace("大题描述", choice_str1);
|
|
|
+ IOUtils.write(choice_qtypStr, fos, "UTF-8");
|
|
|
+ for (int j = 0; j < qtyp.getConstructDetails().size(); j++) {
|
|
|
+ PagerConstructDetail d = qtyp.getConstructDetails().get(j);
|
|
|
+ quNo++;
|
|
|
+ Question qu = d.getQuestion();
|
|
|
+ if (qu == null) {
|
|
|
+ qu = new Question();
|
|
|
+ qu.setBodySummary("空题");
|
|
|
+ }
|
|
|
+ log.info("正在处理试题:id = " + qu.getId());
|
|
|
+ String xtStr = null;
|
|
|
+ if ((qu.getBodyWord() == null || qu.getBodyWord().length == 0)
|
|
|
+ && General.isEmpty(qu.getBody())) {
|
|
|
+ xtStr = choice_xtTmpStr.replace("小题序号", "" + toQuesNumStr(quNo)).replace("题干",
|
|
|
+ General.XMLEncode(qu.getBodySummary()).trim());
|
|
|
+ } else {
|
|
|
+ try {
|
|
|
+ byte[] wordBytes = null;
|
|
|
+ if ((qu.getBodyWord() == null || qu.getBodyWord().length == 0)
|
|
|
+ && !General.isEmpty(qu.getBody())) {
|
|
|
+ wordBytes = General.htmlToDocx(qu.getBody());
|
|
|
+ } else {
|
|
|
+ wordBytes = qu.getBodyWord();
|
|
|
+ }
|
|
|
+ xtStr = General.dealWord(wordBytes, templetDocxReader, needToUpdate);
|
|
|
+
|
|
|
+ int firstWtBeginIndex = xtStr.indexOf("<w:t>");
|
|
|
+ int firstWtBeginIndex2 = xtStr.indexOf("<w:t ");
|
|
|
+ firstWtBeginIndex = (firstWtBeginIndex < 0
|
|
|
+ || (firstWtBeginIndex2 >= 0 && firstWtBeginIndex > firstWtBeginIndex2))
|
|
|
+ ? firstWtBeginIndex2 : firstWtBeginIndex;
|
|
|
+
|
|
|
+ int nearestGtIndex = xtStr.indexOf('>', firstWtBeginIndex + 1);
|
|
|
+
|
|
|
+ String part1 = xtStr.substring(0, nearestGtIndex + 1).trim();
|
|
|
+ String part2 = xtStr.substring(nearestGtIndex + 1).trim();
|
|
|
+ xtStr = part1 + toQuesNumStr(quNo) + "." + part2;
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("获取试题[" + qu.getId() + "]的Word信息失败,原因:" + e.getMessage(), e);
|
|
|
+ xtStr = Consts.ERR_P_TMP.replace("XX",
|
|
|
+ quNo + "." + String.format(Consts.ERR_QUS_MSG, qu.getId() + ""));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ int firstWtBeginIndex1 = xtStr.indexOf("<w:t>");
|
|
|
+ int firstWtBeginIndex2 = xtStr.indexOf("<w:t ");
|
|
|
+// int firstWtEndIndex1 = xtStr.indexOf("</w:t>");
|
|
|
+ firstWtBeginIndex1 = (firstWtBeginIndex1 < 0
|
|
|
+ || (firstWtBeginIndex2 >= 0 && firstWtBeginIndex1 > firstWtBeginIndex2))
|
|
|
+ ? firstWtBeginIndex2 : firstWtBeginIndex1;
|
|
|
+// int nearestGtIndex = xtStr.indexOf('>', firstWtBeginIndex1 + 1);
|
|
|
+ //int wtLen = xtStr.substring(nearestGtIndex, firstWtEndIndex1).length();
|
|
|
+ //int wt_real_len = getQuestionBodyLength(xtStr.substring(nearestGtIndex, firstWtEndIndex1));
|
|
|
+ int optSize = (qu.getOptions() != null) ? qu.getOptions().size() : 0;
|
|
|
+ if (optSize > 0) {
|
|
|
+ String option_temp = null;
|
|
|
+ if (optSize <= 4) {
|
|
|
+ xtStr = xtStr.replaceAll("<w:pPr>", "<w:pPr>");
|
|
|
+ option_temp = "</w:p>";
|
|
|
+ String before_str = StringUtils.substringBeforeLast(xtStr, "</w:p>");
|
|
|
+ String after_str = StringUtils.substringAfterLast(xtStr, "</w:p>");
|
|
|
+ xtStr = before_str + option_temp + after_str;
|
|
|
+ } else {
|
|
|
+ xtStr = xtStr.replaceAll("<w:pPr>", "<w:pPr>");
|
|
|
+// option_temp = "<w:r><w:tab/></w:r><w:r><w:t>【 】</w:t></w:r></w:p>";
|
|
|
+ option_temp = "</w:p>";
|
|
|
+ String before_str = StringUtils.substringBeforeLast(xtStr, "</w:p>");
|
|
|
+ String after_str = StringUtils.substringAfterLast(xtStr, "</w:p>");
|
|
|
+ xtStr = before_str + option_temp + after_str;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //xtStr = dealFormula(xtStr);
|
|
|
+ IOUtils.write(addBeforeLines(xtStr, 0, 0, 0), fos, "UTF-8");
|
|
|
+ if (optSize > 0) {
|
|
|
+ String optsStr = "";
|
|
|
+ for (int m = 0; m < optSize; m++) {
|
|
|
+ QuestionOption opt = qu.getOptions().get(m);
|
|
|
+ String seqNum = String.valueOf(((char) ('A' + m)));
|
|
|
+ String prefixStr = " " + seqNum + ".";
|
|
|
+ String anStr = null;
|
|
|
+ log.info("正在处理答题项:id = " + opt.getId());
|
|
|
+ if ((opt.getContentWord() == null || opt.getContentWord().length == 0)
|
|
|
+ && General.isEmpty(opt.getContent())) {
|
|
|
+ String optTxt = General.XMLEncode(opt.getSummary()).trim();
|
|
|
+ anStr = Consts.NORMAL_P_TMP.replace("XX", prefixStr + optTxt);
|
|
|
+ } else {
|
|
|
+ try {
|
|
|
+ byte[] wordBytes = null;
|
|
|
+ if ((opt.getContentWord() == null || opt.getContentWord().length == 0)
|
|
|
+ && !General.isEmpty(opt.getContent())) {
|
|
|
+ wordBytes = General.htmlToDocx(opt.getContent());
|
|
|
+ } else {
|
|
|
+ wordBytes = opt.getContentWord();
|
|
|
+ }
|
|
|
+ anStr = General.dealWord(wordBytes, templetDocxReader, needToUpdate);
|
|
|
+ int firstWtBeginIndex = -1;
|
|
|
+ if (firstWtBeginIndex < 0) {
|
|
|
+ int firstWpBeginIndex = anStr.indexOf(">");// 默认第一个节点是<w:p
|
|
|
+ // ...>,不支持答题项第一个元素是表格
|
|
|
+ String part1 = anStr.substring(0, firstWpBeginIndex + ">".length())
|
|
|
+ .trim();
|
|
|
+ String part2 = anStr.substring(firstWpBeginIndex + ">".length())
|
|
|
+ .replace("\"center\"", "\"left\"")
|
|
|
+ .replace("\"right\"", "\"left\"").trim();
|
|
|
+ anStr = part1 + part2;
|
|
|
+ /*****
|
|
|
+ * 往anStr里面添加
|
|
|
+ * <w:jc w:val="left"/>
|
|
|
+ *****/
|
|
|
+ {
|
|
|
+ if (!anStr.contains("<w:jc w:val=\"left\"/>")) {
|
|
|
+ int pPrIndex = anStr.indexOf("<w:pPr>");
|
|
|
+ if (pPrIndex < 0) {
|
|
|
+ anStr = part1 + "<w:pPr><w:jc w:val=\"left\"/></w:pPr>" + part2;
|
|
|
+ } else {
|
|
|
+ anStr = anStr.substring(0,
|
|
|
+ pPrIndex + "<w:pPr>".length())
|
|
|
+ + "<w:jc w:val=\"left\"/>" + anStr.substring(
|
|
|
+ pPrIndex + "<w:pPr>".length());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ anStr = anStr.replaceAll("</w:pPr>", "</w:pPr><w:r><w:t>" + prefixStr + "</w:t></w:r>");
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("获取试题选项[" + opt.getId() + "]的Word信息失败,原因:" + e.getMessage(),
|
|
|
+ e);
|
|
|
+ anStr = Consts.ERR_P_TMP.replace("XX", prefixStr
|
|
|
+ + String.format(Consts.ERR_QUS_OPT_MSG, qu.getId() + ""));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //anStr = dealFormula(anStr);
|
|
|
+ optsStr = optsStr + addBeforeLines(anStr, 0, 0, 0);
|
|
|
+ }
|
|
|
+ optsStr = compressOption(optsStr, optSize);
|
|
|
+ IOUtils.write(optsStr, fos, "UTF-8");
|
|
|
+ }
|
|
|
+ IOUtils.write(choice_qtTmpTailStr, fos, "UTF-8");
|
|
|
+ }
|
|
|
+ qtypIndex++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 非选择题
|
|
|
+ int non_choice_index1 = docStr.indexOf("非选择题开始");// "非选择题开始"的位置
|
|
|
+ int non_choice_index2 = docStr.substring(0, non_choice_index1).lastIndexOf("<w:p ");// "非选择题开始"<w:p>的位置
|
|
|
+ String non_choice_head = docStr.substring(choice_index6, non_choice_index2);// 第二部分
|
|
|
+ IOUtils.write(non_choice_head, fos, "UTF-8");
|
|
|
+ for (int index = 0; index < paper.getQtypeList().size(); index++) {
|
|
|
+ PagerConstructQtype qtyp = paper.getQtypeList().get(index);
|
|
|
+ if (!qtyp.getName().contains("选择题")) {
|
|
|
+
|
|
|
+ int non_choice_index3 = non_choice_index1
|
|
|
+ + docStr.substring(non_choice_index1).indexOf("</w:p>");// "非选择题开始"对应的<w:p>标签的结束位置
|
|
|
+
|
|
|
+ int non_choice_index4 = docStr.indexOf("非选择题结束");// "非选择题结束"的位置
|
|
|
+ int non_choice_index5 = docStr.substring(0, non_choice_index4).lastIndexOf("<w:p ");// "非选择题结束"对应的<w:p>标签的开始位置
|
|
|
+
|
|
|
+ String non_choice_quTmpStr = docStr.substring(non_choice_index3 + "</w:p>".length(),
|
|
|
+ non_choice_index5);// 非选择题目模板
|
|
|
+
|
|
|
+ int non_choice_index7 = non_choice_quTmpStr.indexOf("小题序号");
|
|
|
+ int non_choice_index8 = non_choice_quTmpStr.substring(0, non_choice_index7)
|
|
|
+ .lastIndexOf("<w:p ");// 小题对应的<w:p>标签的开始位置
|
|
|
+ int non_choice_index9 = non_choice_index7
|
|
|
+ + non_choice_quTmpStr.substring(non_choice_index7).indexOf("</w:p>");// 小题对应的<w:p>标签的结束位置
|
|
|
+
|
|
|
+ int non_choice_index10 = non_choice_quTmpStr.indexOf("答题项");
|
|
|
+ int non_choice_index12 = non_choice_index10
|
|
|
+ + non_choice_quTmpStr.substring(non_choice_index10).indexOf("</w:p>");// 答题项对应的<w:p>标签的结束位置
|
|
|
+ String non_choice_qtTmpHeadStr = non_choice_quTmpStr.substring(0, non_choice_index8);
|
|
|
+ String non_choice_qtTmpTailStr = non_choice_quTmpStr
|
|
|
+ .substring(non_choice_index12 + "</w:p>".length());
|
|
|
+ String non_choice_xtTmpStr = non_choice_quTmpStr.substring(non_choice_index8,
|
|
|
+ non_choice_index9 + "</w:p>".length());
|
|
|
+ String non_choice_str1 = General.toCNLowerNum(qtypIndex + 1) + "、"
|
|
|
+ + General.XMLEncode(qtyp.getName()) + ":本大题共" + qtyp.getQuestionSum() + "小题,"
|
|
|
+ + ((qtyp.getQuestionSum() > 1) ? "每小题" : "") + General.formatScore(qtyp.getScore())
|
|
|
+ + "分" + ((qtyp.getQuestionSum() > 1)
|
|
|
+ ? ",共" + General.formatScore(qtyp.getQuestionScores()) + "分" : "")
|
|
|
+ + "。";
|
|
|
+ if(qtyp.getQuestionType().getRemark()!=null){
|
|
|
+ non_choice_str1+=" "+qtyp.getQuestionType().getRemark();
|
|
|
+ }
|
|
|
+ String non_choice_qtypStr = non_choice_qtTmpHeadStr.replace("大题描述", non_choice_str1);
|
|
|
+// if(qtyp.getQuestionType().getRemark()!=null){
|
|
|
+// non_choice_qtypStr+= "<w:p w:rsidR=\"00EA7945\" w:rsidRPr=\"008F10F9\" w:rsidRDefault=\"00EA7945\" w:rsidP=\"003217C2\"><w:pPr><w:adjustRightInd w:val=\"0\"/><w:snapToGrid w:val=\"0\"/><w:spacing w:line=\"260\" w:lineRule=\"exact\"/><w:ind w:left=\"420\" w:hangingChars=\"200\" w:hanging=\"420\"/><w:rPr><w:rFonts w:eastAsia=\"黑体\"/><w:color w:val=\"000000\"/><w:szCs w:val=\"21\"/></w:rPr></w:pPr><w:r w:rsidRPr=\"007253D9\"><w:rPr><w:rFonts w:eastAsia=\"黑体\" w:hint=\"eastAsia\"/><w:color w:val=\"000000\"/><w:szCs w:val=\"21\"/></w:rPr><w:t>"+qtyp.getQuestionType().getRemark()+"</w:t></w:r></w:p>";
|
|
|
+// }
|
|
|
+ IOUtils.write(non_choice_qtypStr, fos, "UTF-8");
|
|
|
+ for (int j = 0; j < qtyp.getConstructDetails().size(); j++) {
|
|
|
+ PagerConstructDetail d = qtyp.getConstructDetails().get(j);
|
|
|
+ quNo++;
|
|
|
+ Question qu = d.getQuestion();
|
|
|
+ if (qu == null) {
|
|
|
+ qu = new Question();
|
|
|
+ qu.setBodySummary("空题");
|
|
|
+ }
|
|
|
+ log.info("正在处理试题:id = " + qu.getId());
|
|
|
+ String xtStr = null;
|
|
|
+ if ((qu.getBodyWord() == null || qu.getBodyWord().length == 0)
|
|
|
+ && General.isEmpty(qu.getBody())) {
|
|
|
+ xtStr = non_choice_xtTmpStr.replace("小题序号", "" + toQuesNumStr(quNo)).replace("题干",
|
|
|
+ General.XMLEncode(qu.getBodySummary()).trim());
|
|
|
+ } else {
|
|
|
+ try {
|
|
|
+ byte[] wordBytes = null;
|
|
|
+ if ((qu.getBodyWord() == null || qu.getBodyWord().length == 0)
|
|
|
+ && !General.isEmpty(qu.getBody())) {
|
|
|
+ wordBytes = General.htmlToDocx(qu.getBody());
|
|
|
+ } else {
|
|
|
+ wordBytes = qu.getBodyWord();
|
|
|
+ }
|
|
|
+ xtStr = General.dealWord(wordBytes, templetDocxReader, needToUpdate);
|
|
|
+
|
|
|
+ int firstWtBeginIndex = xtStr.indexOf("<w:t>");
|
|
|
+ int firstWtBeginIndex2 = xtStr.indexOf("<w:t ");
|
|
|
+ firstWtBeginIndex = (firstWtBeginIndex < 0
|
|
|
+ || (firstWtBeginIndex2 >= 0 && firstWtBeginIndex > firstWtBeginIndex2))
|
|
|
+ ? firstWtBeginIndex2 : firstWtBeginIndex;
|
|
|
+
|
|
|
+ int nearestGtIndex = xtStr.indexOf('>', firstWtBeginIndex + 1);
|
|
|
+
|
|
|
+ String part1 = xtStr.substring(0, nearestGtIndex + 1).trim();
|
|
|
+ String part2 = xtStr.substring(nearestGtIndex + 1).trim();
|
|
|
+ xtStr = part1 + toQuesNumStr(quNo) + "." + part2;
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("获取试题[" + qu.getId() + "]的Word信息失败,原因:" + e.getMessage(), e);
|
|
|
+ xtStr = Consts.ERR_P_TMP.replace("XX",
|
|
|
+ quNo + "." + String.format(Consts.ERR_QUS_MSG, qu.getId() + ""));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ IOUtils.write(addBeforeLines(xtStr, 0, 0, 0), fos, "UTF-8");
|
|
|
+ IOUtils.write(non_choice_qtTmpTailStr, fos, "UTF-8");
|
|
|
+ }
|
|
|
+ qtypIndex++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ IOUtils.write(tail, fos, "UTF-8");
|
|
|
+ } finally {
|
|
|
+ General.close(is);
|
|
|
+ General.close(fosNew);
|
|
|
+ General.close(fos);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ {
|
|
|
+ File document = templetDocxReader.getDocumentInfo().getFile();
|
|
|
+ FileOutputStream fos = null;
|
|
|
+ InputStream is = null;
|
|
|
+ try {
|
|
|
+ is = new FileInputStream(document);
|
|
|
+ String docStr = IOUtils.toString(is, "UTF-8")
|
|
|
+ .replace("<pic:pic>",
|
|
|
+ "<pic:pic xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">")
|
|
|
+ .replace("<w15:collapsed w:val=\"false\"/>", "");
|
|
|
+ is.close();
|
|
|
+ fos = new FileOutputStream(document, false);
|
|
|
+ IOUtils.write(docStr, fos, "UTF-8");
|
|
|
+ fos.flush();
|
|
|
+ fos.close();
|
|
|
+
|
|
|
+ {
|
|
|
+ SAXReader sax = new SAXReader();
|
|
|
+ is = new FileInputStream(document);
|
|
|
+ Document documentNode = sax.read(is);
|
|
|
+ Element root = documentNode.getRootElement();
|
|
|
+ List allParaIdNodes = (List) root.selectNodes("//@w14:paraId | //@w14:textId");//删掉无用的属性
|
|
|
+ for(Object pObj:allParaIdNodes){
|
|
|
+ if(pObj instanceof Attribute){
|
|
|
+ Attribute paraId = (Attribute)pObj;
|
|
|
+ paraId.getParent().remove(paraId);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ String xtStr = documentNode.asXML();
|
|
|
+ is.close();
|
|
|
+ fos = new FileOutputStream(document, false);
|
|
|
+ IOUtils.write(xtStr, fos, "UTF-8");
|
|
|
+ fos.flush();
|
|
|
+ fos.close();
|
|
|
+ }
|
|
|
+ } finally {
|
|
|
+ General.close(is);
|
|
|
+ General.close(fos);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ {
|
|
|
+ DocxReader.updateDocx(newDocx, needToUpdate);
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("生成试卷[" + paper.getId() + "]的Word文档失败,原因:" + e.getMessage(), e);
|
|
|
+ throw new BizException(e.getMessage(), e);
|
|
|
+ } finally {
|
|
|
+ General.release(templetDocxReader);
|
|
|
+ }
|
|
|
+ if (ParamUtils.NeedCheckWordVersion) {
|
|
|
+ General.setDocxDefinedAttr(newDocx, Consts.DOCX_VERSION, "QMTH" + System.currentTimeMillis());// 往新生成的Word里面打个版本号:当前时间
|
|
|
+ }
|
|
|
+ return newDocx;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 给某段文字添加左侧多少个字符,前、后多少行距。
|
|
|
+ * @param xtStr
|
|
|
+ * @param leftChars leftChars/100=左侧字符数
|
|
|
+ * @param beforeLinesInt beforeLinesInt/100=段前行数
|
|
|
+ * @param afterLinesInt afterLinesInt/100=段后行数
|
|
|
+ * @return
|
|
|
+ * @throws UnsupportedEncodingException
|
|
|
+ * @throws DocumentException
|
|
|
+ */
|
|
|
+ @SuppressWarnings("rawtypes")
|
|
|
+ private static String addBeforeLines(String xtStr,int leftChars,int beforeLinesInt,int afterLinesInt) throws UnsupportedEncodingException, DocumentException {
|
|
|
+ xtStr = Consts.PAPERTMPBODY_START + xtStr + Consts.PAPERTMPBODY_END;
|
|
|
+ SAXReader sax = new SAXReader();
|
|
|
+ ByteArrayInputStream is = new ByteArrayInputStream(xtStr.getBytes("UTF-8"));
|
|
|
+ Document document = sax.read(is);
|
|
|
+ Element root = document.getRootElement();
|
|
|
+ {// 设置段前,0.5行
|
|
|
+ Element firstP = root.element("p");
|
|
|
+ Element pPr = firstP.element("pPr");
|
|
|
+ if (pPr == null) {
|
|
|
+ List children = firstP.elements();
|
|
|
+ pPr = DocumentHelper.createElement("w:pPr");
|
|
|
+ children.add(0, pPr);
|
|
|
+ firstP.setContent(children);
|
|
|
+ }
|
|
|
+ {//处理spacing
|
|
|
+ Element spacing = pPr.element("spacing");
|
|
|
+ if (spacing == null) {
|
|
|
+ spacing = pPr.addElement("w:spacing");
|
|
|
+ }
|
|
|
+ Attribute before = spacing.attribute("before");
|
|
|
+ if (before == null) {
|
|
|
+ spacing.addAttribute("w:before", "0");
|
|
|
+ } else {
|
|
|
+ before.setValue("0");
|
|
|
+ }
|
|
|
+ Attribute beforeLines = spacing.attribute("beforeLines");
|
|
|
+ if (beforeLines == null) {
|
|
|
+ spacing.addAttribute("w:beforeLines", "" + beforeLinesInt);
|
|
|
+ } else {
|
|
|
+ beforeLines.setValue("" + beforeLinesInt);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ {//一定居左对齐
|
|
|
+ Element jc = pPr.element("jc");
|
|
|
+ if(jc != null){
|
|
|
+ pPr.remove(jc);
|
|
|
+ }
|
|
|
+ jc = pPr.addElement("w:jc");
|
|
|
+ jc.addAttribute("w:val", "left");
|
|
|
+ }
|
|
|
+ {//处理左边距
|
|
|
+ Element ind = pPr.element("ind");
|
|
|
+ if(ind != null){
|
|
|
+ pPr.remove(ind);
|
|
|
+ }
|
|
|
+ ind = pPr.addElement("w:ind");
|
|
|
+ ind.addAttribute("w:leftChars", leftChars + "");
|
|
|
+ }
|
|
|
+ {
|
|
|
+ Element firstWt = (Element) firstP.selectSingleNode("*/w:t");
|
|
|
+ if(firstWt != null){
|
|
|
+ Attribute spaceAttr = firstWt.attribute("space");
|
|
|
+ if(spaceAttr == null){
|
|
|
+ firstWt.addAttribute("xml:space", "preserve");
|
|
|
+ }else{
|
|
|
+ spaceAttr.setValue("preserve");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ {// 设置段后,0.1行
|
|
|
+ List pList = root.elements("p");
|
|
|
+ Element lastP = (Element) pList.get(pList.size() - 1);
|
|
|
+ Element pPr = lastP.element("pPr");
|
|
|
+ if (pPr == null) {
|
|
|
+ List children = lastP.elements();
|
|
|
+ pPr = DocumentHelper.createElement("w:pPr");
|
|
|
+ children.add(0, pPr);
|
|
|
+ lastP.setContent(children);
|
|
|
+ }
|
|
|
+ Element adjustRightInd = pPr.element("adjustRightInd");
|
|
|
+ if (adjustRightInd == null) {
|
|
|
+ adjustRightInd = pPr.addElement("w:adjustRightInd");
|
|
|
+ }
|
|
|
+ {
|
|
|
+ Attribute val = adjustRightInd.attribute("val");
|
|
|
+ if (val == null) {
|
|
|
+ adjustRightInd.addAttribute("w:val", "0");
|
|
|
+ } else {
|
|
|
+ val.setValue("0");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ Element snapToGrid = pPr.element("snapToGrid");
|
|
|
+ if (snapToGrid == null) {
|
|
|
+ snapToGrid = pPr.addElement("w:snapToGrid");
|
|
|
+ }
|
|
|
+ {
|
|
|
+ Attribute val = snapToGrid.attribute("val");
|
|
|
+ if (val == null) {
|
|
|
+ snapToGrid.addAttribute("w:val", "0");
|
|
|
+ } else {
|
|
|
+ val.setValue("0");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ Element spacing = pPr.element("spacing");
|
|
|
+ if (spacing == null) {
|
|
|
+ spacing = pPr.addElement("w:spacing");
|
|
|
+ }
|
|
|
+ Attribute before = spacing.attribute("after");
|
|
|
+ if (before == null) {
|
|
|
+ spacing.addAttribute("w:after", "0");
|
|
|
+ } else {
|
|
|
+ before.setValue("0");
|
|
|
+ }
|
|
|
+ Attribute afterLines = spacing.attribute("afterLines");
|
|
|
+ if (afterLines == null) {
|
|
|
+ spacing.addAttribute("w:afterLines", "" + afterLinesInt);
|
|
|
+ } else {
|
|
|
+ afterLines.setValue("" + afterLinesInt);
|
|
|
+ }
|
|
|
+ Attribute line = spacing.attribute("line");
|
|
|
+ if (line == null) {
|
|
|
+ spacing.addAttribute("w:line", "280");
|
|
|
+ } else {
|
|
|
+ line.setValue("280");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ {
|
|
|
+ List allWrNodes = (List) root.selectNodes("*/w:r");
|
|
|
+ for(Object wrObj:allWrNodes){
|
|
|
+ if(wrObj instanceof Element){
|
|
|
+ Element wr = (Element)wrObj;
|
|
|
+ Element rPr = wr.element("rPr");
|
|
|
+ if (rPr == null) {
|
|
|
+ List children = wr.elements();
|
|
|
+ rPr = DocumentHelper.createElement("w:rPr");
|
|
|
+ children.add(0, rPr);
|
|
|
+ wr.setContent(children);
|
|
|
+ }
|
|
|
+ {
|
|
|
+ Element szCs = rPr.element("szCs");
|
|
|
+ if(szCs == null){
|
|
|
+ List children = rPr.elements();
|
|
|
+ szCs = DocumentHelper.createElement("w:szCs");
|
|
|
+ children.add(szCs);
|
|
|
+ rPr.setContent(children);
|
|
|
+ }
|
|
|
+ Attribute val = szCs.attribute("val");
|
|
|
+ if (val == null) {
|
|
|
+ szCs.addAttribute("w:val", "21");
|
|
|
+ } else {
|
|
|
+ val.setValue("21");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ {
|
|
|
+ Element szCs = rPr.element("sz");
|
|
|
+ if(szCs == null){
|
|
|
+ List children = rPr.elements();
|
|
|
+ szCs = DocumentHelper.createElement("w:sz");
|
|
|
+ children.add(szCs);
|
|
|
+ rPr.setContent(children);
|
|
|
+ }
|
|
|
+ Attribute val = szCs.attribute("val");
|
|
|
+ if (val == null) {
|
|
|
+ szCs.addAttribute("w:val", "21");
|
|
|
+ } else {
|
|
|
+ val.setValue("21");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ xtStr = document.asXML();
|
|
|
+ xtStr = xtStr.substring(xtStr.indexOf(Consts.PAPERTMPBODY_START) + Consts.PAPERTMPBODY_START.length(),
|
|
|
+ xtStr.length() - Consts.PAPERTMPBODY_END.length());
|
|
|
+ return xtStr;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 压缩试题选项
|
|
|
+ * @param xtStr 选项内容
|
|
|
+ * @param optSize 选项个数
|
|
|
+ * @author songyue
|
|
|
+ **/
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
+ private static String compressOption(String xtStr,int optSize) throws UnsupportedEncodingException, DocumentException {
|
|
|
+ String xtStr_temp = xtStr;
|
|
|
+ xtStr = Consts.PAPERTMPBODY_START + xtStr + Consts.PAPERTMPBODY_END;
|
|
|
+ SAXReader sax = new SAXReader();
|
|
|
+ ByteArrayInputStream is = new ByteArrayInputStream(xtStr.getBytes("UTF-8"));
|
|
|
+ Document document = sax.read(is);
|
|
|
+ Element root = document.getRootElement();
|
|
|
+ List pList = root.elements("p");
|
|
|
+ //获取所有选项元素
|
|
|
+
|
|
|
+ Element pA = (Element)pList.get(0);
|
|
|
+ Element pPrA = pA.element("pPr");
|
|
|
+ List pArList = pA.elements("r");
|
|
|
+ Element pAr = null;
|
|
|
+ if(pArList.size() > 1){
|
|
|
+ pAr = (Element)pArList.get(1);
|
|
|
+ }else{
|
|
|
+ return xtStr_temp;
|
|
|
+ }
|
|
|
+ if(pAr.element("t")==null){
|
|
|
+ return xtStr_temp;
|
|
|
+ }
|
|
|
+ int pA_len = pAr.element("t").getTextTrim().length();
|
|
|
+ int pA_real_len = getQuestionBodyLength(pAr.element("t").getTextTrim());
|
|
|
+ List pA_children = pA.elements();
|
|
|
+
|
|
|
+ Element pB = (Element)pList.get(1);
|
|
|
+ Element pPrB = pA.element("pPr");
|
|
|
+ List pBrList = pB.elements("r");
|
|
|
+ Element pBr = null;
|
|
|
+ if(pBrList.size() > 1){
|
|
|
+ pBr = (Element)pBrList.get(1);
|
|
|
+ }else{
|
|
|
+ return xtStr_temp;
|
|
|
+ }
|
|
|
+ if(pBr.element("t")==null){
|
|
|
+ return xtStr_temp;
|
|
|
+ }
|
|
|
+ int pB_len = pBr.element("t").getTextTrim().length();
|
|
|
+ int pB_real_len = getQuestionBodyLength(pBr.element("t").getTextTrim());
|
|
|
+ List pB_children = pB.elements();
|
|
|
+
|
|
|
+ Element pC = (Element)pList.get(2);
|
|
|
+ Element pPrC = pA.element("pPr");
|
|
|
+ List pCrList = pC.elements("r");
|
|
|
+ Element pCr = null;
|
|
|
+ if(pCrList.size() > 1){
|
|
|
+ pCr = (Element)pCrList.get(1);
|
|
|
+ }else{
|
|
|
+ return xtStr_temp;
|
|
|
+ }
|
|
|
+ if(pCr.element("t")==null){
|
|
|
+ return xtStr_temp;
|
|
|
+ }
|
|
|
+ int pC_len = pCr.element("t").getTextTrim().length();
|
|
|
+ int pC_real_len = getQuestionBodyLength(pCr.element("t").getTextTrim());
|
|
|
+ List pC_children = pC.elements();
|
|
|
+
|
|
|
+ Element pD = (Element)pList.get(3);
|
|
|
+ Element pPrD = pA.element("pPr");
|
|
|
+ List pDrList = pD.elements("r");
|
|
|
+ Element pDr = null;
|
|
|
+ if(pDrList.size() > 1){
|
|
|
+ pDr = (Element)pDrList.get(1);
|
|
|
+ }else{
|
|
|
+ return xtStr_temp;
|
|
|
+ }
|
|
|
+ if(pDr.element("t")==null){
|
|
|
+ return xtStr_temp;
|
|
|
+ }
|
|
|
+ int pD_len = pDr.element("t").getTextTrim().length();
|
|
|
+ int pD_real_len = getQuestionBodyLength(pDr.element("t").getTextTrim());
|
|
|
+ List pD_children = pD.elements();
|
|
|
+
|
|
|
+ int pE_real_len = 0;
|
|
|
+ int pE_len = 0;
|
|
|
+
|
|
|
+ Element rtab = DocumentHelper.createElement("w:r");
|
|
|
+ Element rPr = DocumentHelper.createElement("w:rPr");
|
|
|
+ Element szCs = DocumentHelper.createElement("w:szCs");
|
|
|
+ Element sz = DocumentHelper.createElement("w:sz");
|
|
|
+ {
|
|
|
+ Attribute val = szCs.attribute("val");
|
|
|
+ if (val == null) {
|
|
|
+ szCs.addAttribute("w:val", "21");
|
|
|
+ } else {
|
|
|
+ val.setValue("21");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ {
|
|
|
+ Attribute val = sz.attribute("val");
|
|
|
+ if (val == null) {
|
|
|
+ sz.addAttribute("w:val", "21");
|
|
|
+ } else {
|
|
|
+ val.setValue("21");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ rPr.add(szCs);
|
|
|
+ rPr.add(sz);
|
|
|
+ rtab.add(rPr);
|
|
|
+ rtab.addElement("w:tab","http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
|
|
+
|
|
|
+ //处理单选题
|
|
|
+ if(optSize == 4){
|
|
|
+ //一行4项
|
|
|
+// if((pA_real_len + pB_real_len + pC_real_len + pD_real_len) <= 25 && pA_real_len <= 6 && pB_real_len <= 6 && pC_real_len <= 6 && pD_real_len <= 6){
|
|
|
+// //pA_children.add(1,(Element)rtab.clone());
|
|
|
+// pB_children.add(1,(Element)rtab.clone());
|
|
|
+// pC_children.add(1,(Element)rtab.clone());
|
|
|
+// pD_children.add(1,(Element)rtab.clone());
|
|
|
+// detachPr(pB_children);
|
|
|
+// detachPr(pC_children);
|
|
|
+// detachPr(pD_children);
|
|
|
+// detachAll(pA_children);
|
|
|
+// detachAll(pB_children);
|
|
|
+// detachAll(pC_children);
|
|
|
+// detachAll(pD_children);
|
|
|
+// pA_children.addAll(pB_children);
|
|
|
+// pA_children.addAll(pC_children);
|
|
|
+// pA_children.addAll(pD_children);
|
|
|
+// pA.setContent(pA_children);
|
|
|
+// pB.detach();
|
|
|
+// pC.detach();
|
|
|
+// pD.detach();
|
|
|
+// }
|
|
|
+ //一行2项
|
|
|
+ if((pA_real_len + pB_real_len) <= 30 && (pC_real_len + pD_real_len) <= 30 && pA_real_len <= 15 && pB_real_len <= 15 && pC_real_len <= 15 && pD_real_len <= 15){
|
|
|
+ //pA_children.add(1,(Element)rtab.clone());
|
|
|
+ pB_children.add(1,(Element)rtab.clone());
|
|
|
+ //pC_children.add(1,(Element)rtab.clone());
|
|
|
+ pD_children.add(1,(Element)rtab.clone());
|
|
|
+ detachPr(pB_children);
|
|
|
+ detachPr(pD_children);
|
|
|
+ detachAll(pA_children);
|
|
|
+ detachAll(pB_children);
|
|
|
+ detachAll(pC_children);
|
|
|
+ detachAll(pD_children);
|
|
|
+ pA_children.addAll(pB_children);
|
|
|
+ pC_children.addAll(pD_children);
|
|
|
+ pA.setContent(pA_children);
|
|
|
+ pC.setContent(pC_children);
|
|
|
+ pB.detach();
|
|
|
+ pD.detach();
|
|
|
+ }
|
|
|
+ //处理多选题
|
|
|
+ }else if(optSize == 5){
|
|
|
+ Element pE = (Element)pList.get(4);
|
|
|
+ Element pPrE = pE.element("pPr");
|
|
|
+ List pErList = pE.elements("r");
|
|
|
+ Element pEr = null;
|
|
|
+ if(pErList.size() > 1){
|
|
|
+ pEr = (Element)pErList.get(1);
|
|
|
+ }else{
|
|
|
+ return xtStr_temp;
|
|
|
+ }
|
|
|
+ if(pEr.element("t") == null){
|
|
|
+ return xtStr_temp;
|
|
|
+ }
|
|
|
+ pE_len = pEr.element("t").getTextTrim().length();
|
|
|
+ pE_real_len = getQuestionBodyLength(pEr.element("t").getTextTrim());
|
|
|
+ List pE_children = pE.elements();
|
|
|
+ //一行5项
|
|
|
+// if((pA_real_len + pB_real_len + pC_real_len + pD_real_len + pE_real_len) <= 10){
|
|
|
+// detachAll(pA_children);
|
|
|
+// detachAll(pB_children);
|
|
|
+// detachAll(pC_children);
|
|
|
+// detachAll(pD_children);
|
|
|
+// detachAll(pE_children);
|
|
|
+// pA_children.addAll(pB_children);
|
|
|
+// pA_children.addAll(pC_children);
|
|
|
+// pA_children.addAll(pD_children);
|
|
|
+// pA_children.addAll(pE_children);
|
|
|
+// pA.setContent(pA_children);
|
|
|
+// pB.detach();
|
|
|
+// pC.detach();
|
|
|
+// pD.detach();
|
|
|
+// pE.detach();
|
|
|
+// }
|
|
|
+ //一行2项
|
|
|
+ if((pA_real_len + pB_real_len ) <= 30 && (pC_real_len + pD_real_len) <= 30 && pA_real_len <= 15 && pB_real_len <= 15 && pC_real_len <= 15 && pD_real_len <= 15 && pE_real_len <= 15){
|
|
|
+ //pA_children.add(1,(Element)rtab.clone());
|
|
|
+ pB_children.add(1,(Element)rtab.clone());
|
|
|
+ //pC_children.add(1,(Element)rtab.clone());
|
|
|
+ pD_children.add(1,(Element)rtab.clone());
|
|
|
+ //pE_children.add(1,(Element)rtab.clone());
|
|
|
+ detachPr(pB_children);
|
|
|
+ detachPr(pD_children);
|
|
|
+ detachAll(pA_children);
|
|
|
+ detachAll(pB_children);
|
|
|
+ detachAll(pC_children);
|
|
|
+ detachAll(pD_children);
|
|
|
+ //detachAll(pE_children);
|
|
|
+ pA_children.addAll(pB_children);
|
|
|
+ pC_children.addAll(pD_children);
|
|
|
+ pA.setContent(pA_children);
|
|
|
+ pC.setContent(pC_children);
|
|
|
+ pB.detach();
|
|
|
+ pD.detach();
|
|
|
+ }
|
|
|
+// //一行2项
|
|
|
+// else if((pA_real_len + pB_real_len) <= 20 && (pC_real_len + pD_real_len) <= 20){
|
|
|
+// detachAll(pA_children);
|
|
|
+// detachAll(pB_children);
|
|
|
+// detachAll(pC_children);
|
|
|
+// detachAll(pD_children);
|
|
|
+// addTab(pA_children, pC_children, pA_len, pC_len, tab);
|
|
|
+// pA_children.addAll(pB_children);
|
|
|
+// pC_children.addAll(pD_children);
|
|
|
+// pA.setContent(pA_children);
|
|
|
+// pC.setContent(pC_children);
|
|
|
+// pB.detach();
|
|
|
+// pD.detach();
|
|
|
+// }
|
|
|
+ }
|
|
|
+
|
|
|
+ xtStr = document.asXML();
|
|
|
+ xtStr = xtStr.substring(xtStr.indexOf(Consts.PAPERTMPBODY_START) + Consts.PAPERTMPBODY_START.length(),
|
|
|
+ xtStr.length() - Consts.PAPERTMPBODY_END.length());
|
|
|
+ //增加tabs定义
|
|
|
+ if(optSize == 4){
|
|
|
+ //一行4项
|
|
|
+// if((pA_real_len + pB_real_len + pC_real_len + pD_real_len) <= 25 && pA_real_len <= 6 && pB_real_len <= 6 && pC_real_len <= 6 && pD_real_len <= 6){
|
|
|
+// xtStr = xtStr.replaceAll("<w:pPr>", "<w:pPr><w:tabs>"+ "<w:tab w:val=\"left\" w:pos=\"420\"/>"
|
|
|
+// + "<w:tab w:val=\"left\" w:pos=\"2210\"/>"
|
|
|
+// //+ "<w:tab w:val=\"left\" w:pos=\"4410\"/>"+ "<w:tab w:val=\"left\" w:pos=\"6510\"/>"
|
|
|
+// +"</w:tabs>");
|
|
|
+// }
|
|
|
+ //一行2项
|
|
|
+ if((pA_real_len + pB_real_len) <= 30 && (pC_real_len + pD_real_len) <= 30 && pA_real_len <= 15 && pB_real_len <= 15 && pC_real_len <= 15 && pD_real_len <= 15){
|
|
|
+ xtStr = xtStr.replaceAll("<w:pPr>", "<w:pPr><w:tabs>" + "<w:tab w:val=\"left\" w:pos=\"420\"/>"
|
|
|
+ +"<w:tab w:val=\"left\" w:pos=\"4410\"/></w:tabs>");
|
|
|
+ }
|
|
|
+ }else if(optSize == 5){
|
|
|
+ //一行2项
|
|
|
+ if((pA_real_len + pB_real_len) <= 30 && (pC_real_len + pD_real_len) <= 30 && pA_real_len <= 15 && pB_real_len <= 15 && pC_real_len <= 15 && pD_real_len <= 15 && pE_real_len <= 15){
|
|
|
+ xtStr = xtStr.replaceAll("<w:pPr>", "<w:pPr><w:tabs>"+ "<w:tab w:val=\"left\" w:pos=\"420\"/>"+"<w:tab w:val=\"left\" w:pos=\"4410\"/>" + "</w:tabs>");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return xtStr;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void detachAll(List<Element> eList){
|
|
|
+ for(Element e:eList){
|
|
|
+ e.detach();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void detachPr(List<Element> eList){
|
|
|
+ Iterator<Element> iterator = eList.iterator();
|
|
|
+ while(iterator.hasNext()){
|
|
|
+ Element e = iterator.next();
|
|
|
+ if(e.getName().equals("pPr")){
|
|
|
+ iterator.remove();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * <p>
|
|
|
+ * 增加tab缩进,上下对齐选项
|
|
|
+ * </p>
|
|
|
+ * @param upList
|
|
|
+ * 上选项
|
|
|
+ * @param downList
|
|
|
+ * 下选项
|
|
|
+ * @param tab
|
|
|
+ * 缩进字符元素
|
|
|
+ * @param differ_len
|
|
|
+ * 相差tab数
|
|
|
+ * @author songyue
|
|
|
+ * @date 2016-07-11
|
|
|
+ */
|
|
|
+ public static void addTab(List<Element> upList, List<Element> downList, int uplen, int downlen, Element tab) {
|
|
|
+ int differ_len = (uplen - downlen) >= 0 ? Math.round(((float) uplen - (float) downlen) / 4)
|
|
|
+ : (-1) * Math.round(((float) downlen - (float) uplen) / 4);
|
|
|
+ if (differ_len > 0) {
|
|
|
+ for (int i = 0; i < differ_len; i++) {
|
|
|
+ downList.add((Element) tab.clone());
|
|
|
+ }
|
|
|
+ } else if (differ_len < 0) {
|
|
|
+ for (int i = 0; i < Math.abs(differ_len); i++) {
|
|
|
+ upList.add((Element) tab.clone());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * <p>获取试卷中题目的分值(选择题、非选择题)</p>
|
|
|
+ * @author songyue
|
|
|
+ * @date 2016-06-28
|
|
|
+ */
|
|
|
+ public double getQuestionScore(PagerConstruct paper,String qtype){
|
|
|
+ double score = 0;
|
|
|
+ if(qtype.equals("choice")){
|
|
|
+ for (int i = 0; i < paper.getQtypeList().size(); i++) {
|
|
|
+ PagerConstructQtype qtyp = paper.getQtypeList().get(i);
|
|
|
+ if(qtyp.getName().contains("选择题")){
|
|
|
+ score += qtyp.getQuestionScores().doubleValue();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }else if(qtype.equals("nonchoice")){
|
|
|
+ for (int i = 0; i < paper.getQtypeList().size(); i++) {
|
|
|
+ PagerConstructQtype qtyp = paper.getQtypeList().get(i);
|
|
|
+ if(!qtyp.getName().contains("选择题")){
|
|
|
+ score += qtyp.getQuestionScores().doubleValue();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return score;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * <p>获取题干实际长度</p>
|
|
|
+ * @author songyue
|
|
|
+ * @throws UnsupportedEncodingException
|
|
|
+ * @date 2016-07-11
|
|
|
+ */
|
|
|
+ public static int getQuestionBodyLength(String str) throws UnsupportedEncodingException{
|
|
|
+ double real_len = 0;
|
|
|
+ String []str_split = str.split("");
|
|
|
+ for(String s:str_split){
|
|
|
+ double len = s.getBytes("UTF-8").length;
|
|
|
+ if(len == 1){
|
|
|
+ real_len += len / 2;
|
|
|
+ }else if(len >= 2){
|
|
|
+ real_len += 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return (int)Math.ceil(real_len);
|
|
|
+ }
|
|
|
+
|
|
|
+// /**
|
|
|
+// * <p>将word中的latex公式替换为omml</p>
|
|
|
+// * @author songyue
|
|
|
+// * @date
|
|
|
+// */
|
|
|
+// @SuppressWarnings({ "rawtypes"})
|
|
|
+// private static String dealFormula(String xtStr) throws UnsupportedEncodingException, DocumentException {
|
|
|
+// String xtStr_temp = xtStr;
|
|
|
+// xtStr = Consts.PAPERTMPBODY_START + xtStr + Consts.PAPERTMPBODY_END;
|
|
|
+// SAXReader sax = new SAXReader();
|
|
|
+// ByteArrayInputStream is = new ByteArrayInputStream(xtStr.getBytes("UTF-8"));
|
|
|
+// Document document = sax.read(is);
|
|
|
+// General.close(is);
|
|
|
+// Element root = document.getRootElement();
|
|
|
+// List <Element>pList = root.elements("p");
|
|
|
+// Element p = (Element)pList.get(0);
|
|
|
+// List <Element>prList = p.elements("r");
|
|
|
+// for(Element r: prList){
|
|
|
+// Element t = r.element("t");
|
|
|
+// if(t == null){
|
|
|
+// return xtStr_temp;
|
|
|
+// }
|
|
|
+// String text = t.getTextTrim();
|
|
|
+// if(text.contains("\\[")){
|
|
|
+// String omml = General.latex2OMML(text);
|
|
|
+// if(omml.equals("")){
|
|
|
+// return xtStr_temp;
|
|
|
+// }
|
|
|
+// List <Element>pchildren = r.getParent().content();
|
|
|
+// //omml = Consts.PAPERTMPBODY_START + omml + Consts.PAPERTMPBODY_END;
|
|
|
+// Document omml_doc = DocumentHelper.parseText(omml);
|
|
|
+// Element oMath = (Element)omml_doc.getRootElement();
|
|
|
+// if(oMath != null){
|
|
|
+// Attribute attr_mml = oMath.attribute("xmlns:mml");
|
|
|
+// Attribute attr_m = oMath.attribute("xmlns:m");
|
|
|
+// oMath.remove(attr_mml);
|
|
|
+// oMath.remove(attr_m);
|
|
|
+// pchildren.set(pchildren.indexOf(r), oMath);
|
|
|
+//// p.remove(r);
|
|
|
+//// p.add(oMath);
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
+// xtStr = document.asXML();
|
|
|
+// xtStr = xtStr.substring(xtStr.indexOf(Consts.PAPERTMPBODY_START) + Consts.PAPERTMPBODY_START.length(),
|
|
|
+// xtStr.length() - Consts.PAPERTMPBODY_END.length());
|
|
|
+// return xtStr;
|
|
|
+// }
|
|
|
+
|
|
|
+ public static void main(String[] args) {
|
|
|
+ String xtStr = "<w:p w:rsidR=\"0011633E\" w:rsidRDefault=\"0011633E\" w:rsidP=\"0048118D\"><w:r w:rsidRPr=\"00F43A3E\"><w:rPr><w:rFonts w:hint=\"eastAsia\"/></w:rPr><w:t>12312312312</w:t></w:r><w:r w:rsidR=\"00EE29F7\" w:rsidRPr=\"00F43A3E\"><w:rPr><w:rFonts w:hint=\"eastAsia\"/></w:rPr><w:t>$$x=\\frac {-b\\pm \\sqrt {{b}^{2}-4ac}} {2a}$$</w:t></w:r><w:r w:rsidRPr=\"00F43A3E\"><w:rPr><w:rFonts w:hint=\"eastAsia\"/></w:rPr><w:t xml:space=\"preserve\">123123123</w:t></w:r><w:r w:rsidR=\"00C275D3\" w:rsidRPr=\"00F43A3E\"><w:rPr><w:rFonts w:hint=\"eastAsia\"/></w:rPr><w:t>$$f(x)$$</w:t></w:r><w:r w:rsidR=\"00C275D3\" w:rsidRPr=\"005C45B7\"><w:rPr><w:rFonts w:hint=\"eastAsia\"/></w:rPr><w:t>##满分##</w:t></w:r><w:r w:rsidR=\"00C275D3\" w:rsidRPr=\"00F43A3E\"><w:rPr><w:rFonts w:hint=\"eastAsia\"/></w:rPr><w:t>分</w:t></w:r><w:r w:rsidRPr=\"00F43A3E\"><w:rPr><w:rFonts w:hint=\"eastAsia\"/></w:rPr><w:t xml:space=\"preserve\"> </w:t></w:r><w:r><w:rPr><w:rFonts w:hint=\"eastAsia\"/></w:rPr><w:t xml:space=\"preserve\"> </w:t></w:r><w:r w:rsidRPr=\"00F43A3E\"><w:rPr><w:rFonts w:hint=\"eastAsia\"/></w:rPr><w:t>考试时间:</w:t></w:r><w:r w:rsidRPr=\"00F43A3E\"><w:rPr><w:rFonts w:hint=\"eastAsia\"/></w:rPr><w:t>90</w:t></w:r><w:r w:rsidRPr=\"00F43A3E\"><w:rPr><w:rFonts w:hint=\"eastAsia\"/></w:rPr><w:t>分钟</w:t></w:r></w:p><w:p w:rsidR=\"0011633E\" w:rsidRPr=\"0011633E\" w:rsidRDefault=\"00C275D3\" w:rsidP=\"00D26082\"><w:r w:rsidRPr=\"008C75B3\"><w:rPr><w:rFonts w:hint=\"eastAsia\"/></w:rPr><w:t></w:t></w:r></w:p>";
|
|
|
+ // try {
|
|
|
+ // System.out.println(addBeforeLines(xtStr));
|
|
|
+ // } catch (UnsupportedEncodingException e) {
|
|
|
+ // e.printStackTrace();
|
|
|
+ // } catch (DocumentException e) {
|
|
|
+ // e.printStackTrace();
|
|
|
+ // }
|
|
|
+
|
|
|
+// try {
|
|
|
+// File htmlFile = new File("E:/temp/htmls/1.html");
|
|
|
+// String htmlStr = IOUtils.toString(new FileInputStream(htmlFile), "UTF-8");
|
|
|
+// IOUtils.write(General.htmlToDocx(htmlStr), new FileOutputStream(new File(htmlFile.getPath() + ".docx")));
|
|
|
+// } catch (Exception e) {
|
|
|
+// e.printStackTrace();
|
|
|
+// }
|
|
|
+// try {
|
|
|
+// int len1 = getQuestionBodyLength("当代中国对人生价值观的评价标准是");
|
|
|
+// int len2 = getQuestionBodyLength("自明清以来的公文程式构成有什么");
|
|
|
+// int len3 = getQuestionBodyLength("【 】");
|
|
|
+// System.out.println(len3);
|
|
|
+// System.out.println(len1);
|
|
|
+// System.out.println(len2);
|
|
|
+// System.out.println((39 - len1 - 4)/ 2.0);
|
|
|
+// System.out.println((int) Math.ceil((39 - len1 - 5) / 2));
|
|
|
+// System.out.println((int) Math.ceil((39 - len2 - 5) / 2));
|
|
|
+//
|
|
|
+// } catch (UnsupportedEncodingException e) {
|
|
|
+// // TODO Auto-generated catch block
|
|
|
+// e.printStackTrace();
|
|
|
+// }
|
|
|
+ //System.out.println(General.repairHtmlFormula("<p>123<img class='kfformula' data-latex='\\sqrtsdfsdfsdf'></img>3333</p>"));
|
|
|
+ //System.out.println(General.latex2MML("$$x=\\frac {-b\\pm \\sqrt {{b}^{2}-4ac}} {2a}$$"));
|
|
|
+ }
|
|
|
+}
|