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}$$"));
    }
}
