java实现导入word模板导入试题

最近有一个项目需要将一个word文档中的试题数据导入,并存储到数据库中。试题类型包括:单选题、多选题、判断题、填空题、简答题。支持图片导入(我的这篇是借鉴JAVA实现Excel、Word模板导入 - JAVA - 华仔部落,java poi 解析上传word试卷(题库管理系统) - 爱码网)这两位大神的。

废话不多说,进入正题,直接上代码。

一、word模板

3476f8cb4ce6405686589c21db8f6a19.png

要求:

1)、题目间隔:上一题与下一题之间必须换行,开始下一题;

2)、试题编辑的样式:[单选题][答案][章][节][考点][难度] [解析]是固定样式,不能删除。 如果试题无[解析],无[章][节][考点][难度],可以不填。

二、代码:

1、引入依赖

   <dependency>
       <groupId>org.apache.poi</groupId>
       <artifactId>poi-scratchpad</artifactId>
       <version>4.1.1</version>
   </dependency>
   <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>4.1.1</version>
   </dependency>

2、创建VO对象TestQuestionsImportVo和TestQuestionsImportWordVo

/**
 * 试题导入对应字段
 */
@Data
public class TestQuestionsImportVo implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * 试题类型1=单选2=多选3=判断4=填空5=简答,6=不定项,7=材料题
     */
    private Integer type;
    /**
     * 题目名称
     */
    private String name;
    /**
     * 答案
     */
    private String answer;

    /**
     * 选项A
     */
    private String optionA;

    /**
     * 选项B
     */
    private String optionB;

    /**
     * 选项C
     */
    private String optionC;

    /**
     * 选项D
     */
    private String optionD;

    /**
     * 选项E
     */
    private String optionE;

    /**
     * 选项F
     */
    private String optionF;

    /**
     * 选项G
     */
    private String optionG;

    /**
     * 选项H
     */
    private String optionH;

    /**
     * 选项I
     */
    private String optionI;

    /**
     * 选项J
     */
    private String optionJ;

    /**
     * 选项K
     */
    private String optionK;

    /**
     * 选项L
     */
    private String optionL;

    /**
     * 文字解析
     */
    private String analysis;

    /**
     * 难度,1=简单,2=一般,3=困难
     */
    private String difficulty;

    /**
     * 题库章名称
     */
    private String qbChapName;

    /**
     * 题库节名称
     */
    private String qbNodeName;

    /**
     * 题库考点名称
     */
    private String qbExsiName;
}
/**
 * 试题导入对应字段
 */
@Data
public class TestQuestionsImportWordVo extends TestQuestionsImportVo implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * 材料题字试题
     */
    private List<TestQuestionsImportWordVo> children;

    /**
     * 题目名称图片
     */
    private List<XWPFPicture> questionNameXwpfPicture;

    /**
     * 选项A图片
     */
    private List<XWPFPicture> optionXwpfPictureA;

    /**
     * 选项B图片
     */
    private List<XWPFPicture> optionXwpfPictureB;

    /**
     * 选项C图片
     */
    private List<XWPFPicture> optionXwpfPictureC;

    /**
     * 选项D图片
     */
    private List<XWPFPicture> optionXwpfPictureD;

    /**
     * 选项E图片
     */
    private List<XWPFPicture> optionXwpfPictureE;

    /**
     * 选项F图片
     */
    private List<XWPFPicture> optionXwpfPictureF;

    /**
     * 选项G图片
     */
    private List<XWPFPicture> optionXwpfPictureG;

    /**
     * 选项H图片
     */
    private List<XWPFPicture> optionXwpfPictureH;

    /**
     * 选项I图片
     */
    private List<XWPFPicture> optionXwpfPictureI;

    /**
     * 选项J图片
     */
    private List<XWPFPicture> optionXwpfPictureJ;

    /**
     * 选项K图片
     */
    private List<XWPFPicture> optionXwpfPictureK;

    /**
     * 选项L图片
     */
    private List<XWPFPicture> optionXwpfPictureL;

}

3、word解析试题核心代码

/**
 * word导入处理
 */
public class ImportWordParagraphHandleUtil {

    // 该正则用来匹配一个大题(例如:二、多选题)
    private static String bigQuestionRegex = "([一|二|三|四|五|六|七|八|九|十]{1,3})([、.]{1})([\\u4E00-\\u9FA5\\s]+题)";
    // 该正则用来匹配一个选项(例如:A\B\C\D)
    private static String optionRegex = "([A|B|C|D|E|F|G|H|I|J|K|L]{1,3})";

    /**
     * 解析导入题目word模板
     *
     * @param file
     */
    public static List<TestQuestionsImportWordVo> analysisImportQuestionSubjectWord(MultipartFile file) throws IOException {
        List<TestQuestionsImportWordVo> questionsImportWordVoList = new ArrayList<>();
        // 获取文件流
        InputStream fileInputStream = file.getInputStream();
        // 解析文档
        XWPFDocument xd = new XWPFDocument(fileInputStream);
        // 获取全部的文本段落
        List<XWPFParagraph> xwPfParagraphList = xd.getParagraphs();
        // 过滤掉 大题(例如:二、多选题) 开头的段落
        xwPfParagraphList = xwPfParagraphList.stream().filter(xwpfParagraph -> !Pattern.compile(bigQuestionRegex).matcher(getObjectValue(xwpfParagraph.getText())).find()).collect(Collectors.toList());
        // 题目段落列表
        List<List<XWPFParagraph>> subjectParagraphList = generateSubjectParagraphList(xwPfParagraphList);
        if (CollectionUtil.isEmpty(subjectParagraphList)) {
            return questionsImportWordVoList;
        }
        for (List<XWPFParagraph> xwpfParagraphs : subjectParagraphList) {
            // 解析考试题目保存对象根据段落列表
            TestQuestionsImportWordVo testQuestionsImportWordVo = analysisQuestionsSubjectByParagraph(xwpfParagraphs);
            questionsImportWordVoList.add(testQuestionsImportWordVo);
        }
        return questionsImportWordVoList;
    }

    /**
     * 按照题目生成 段落列表
     * 每个题目一个段落列表
     *
     * @param xwPfParagraphLis
     * @return
     */
    private static List<List<XWPFParagraph>> generateSubjectParagraphList(List<XWPFParagraph> xwPfParagraphLis) {
        List<List<XWPFParagraph>> list = new ArrayList<>();
        if (CollectionUtil.isEmpty(xwPfParagraphLis)) {
            return list;
        }
        boolean isStart = false;
        list.add(new ArrayList<XWPFParagraph>());
        for (int i = 9; i < xwPfParagraphLis.size(); i++) {
            // 当前项
            XWPFParagraph xwPfParagraphLi = xwPfParagraphLis.get(i);
            // 获取文本内容
            String text = xwPfParagraphLi.getText();
            //获取图片内容
            List<XWPFPicture> pictures = StrUtil.isEmpty(text) ? CollectionUtil.isNotEmpty(xwPfParagraphLi.getRuns()) ? xwPfParagraphLi.getRuns().get(0).getEmbeddedPictures() : null : null;
            // 以题目类型开头 算做起始段落
            if (MapUtil.isNotEmpty(getQuestionTypeMap(text))) {
                isStart = true;
            }
            // 开始标志 且 当前是空行
            if (isStart && StrUtil.isBlank(text) && CollectionUtil.isEmpty(pictures)) {
                // 获取最后一个题目段落列表
                List<XWPFParagraph> last = list.get(list.size() - 1);
                // 段落列表不为空
                if (last.size() > 0) {
                    // 算做结束段落
                    isStart = false;
                    // 空行不是最后一行时
                    if (i < xwPfParagraphLis.size() - 1) {
                        // 继续添加段落列表
                        list.add(new ArrayList<XWPFParagraph>());
                    }
                }
            }
            // 处于开始标志时
            if (isStart) {
                // 获取最后一个题目段落列表
                List<XWPFParagraph> last = list.get(list.size() - 1);
                // 为空处理
                last = CollectionUtil.isEmpty(last) ? new ArrayList<>() : last;
                // 将当前段落添加到列表中
                last.add(xwPfParagraphLi);
                list.set(list.size() - 1, last);
            }
        }
        if (CollectionUtil.isNotEmpty(list)) {
            // 如果最后一项是空的,就删除最后一项
            List<XWPFParagraph> tempList = list.get(list.size() - 1);
            if (tempList.size() == 0) {
                list.remove(list.size() - 1);
            }
        }

        return list;
    }

    /**
     * 解析考试题目保存对象根据段落列表
     *
     * @param xwpfParagraphs
     * @return
     */
    private static TestQuestionsImportWordVo analysisQuestionsSubjectByParagraph(List<XWPFParagraph> xwpfParagraphs) {
        // 创建题目保存对象
        TestQuestionsImportWordVo testQuestionsImportWordVo = new TestQuestionsImportWordVo();

       // 调用方法获取解析对象
      List<TestQuestionsImportWordVo> questionsImportWordVoList = generateQuestionSubjectSaveDTOList(xwpfParagraphs);
     if (CollectionUtil.isNotEmpty(questionsImportWordVoList)) {
          testQuestionsImportWordVo = questionsImportWordVoList.get(0);
      }

        return testQuestionsImportWordVo;
    }

    /**
     * 生成题目保存对象列表
     *
     * @return
     */
    @SneakyThrows
    private static List<TestQuestionsImportWordVo> generateQuestionSubjectSaveDTOList(List<XWPFParagraph> xwpfParagraphs) {
        List<TestQuestionsImportWordVo> questionsImportWordVoList = new ArrayList<>();
        if (CollectionUtil.isEmpty(xwpfParagraphs)) {
            return questionsImportWordVoList;
        }
        boolean typeFlag = false;
        boolean contentFlag = false;
        boolean optionsFlag = false;
        for (int i = 0; i < xwpfParagraphs.size(); i++) {
            XWPFParagraph xwpfParagraph = xwpfParagraphs.get(i);
            if (ObjectUtil.isEmpty(xwpfParagraph)) {
                continue;
            }
            // 读取当前段落内容
            String text = getObjectValue(xwpfParagraph.getText()).trim();
            //试题类型1=单选2=多选3=判断4=填空5=简答
            Integer questionType = null;
            //题目名称
            String questionName = null;
            //题目名称图片
            List<XWPFPicture> questionNameXwpfPicture = null;
            //试题选项
            String questionOption = null;
            //试题答案
            String questionAnswer = null;
            //试题章
            String questionChapter = null;
            //试题节
            String questionNode = null;
            //考点
            String questionExam = null;
            //难度
            String questionDifficulty = null;
            //解析
            String questionAnalysis = null;
            //保存的试题类
            TestQuestionsImportWordVo questionsImportWordVo = null;
            if (MapUtil.isNotEmpty(getQuestionTypeMap(text))) {
                questionsImportWordVo = new TestQuestionsImportWordVo();
                //处理试题类型
                questionType = Integer.valueOf(getQuestionTypeMap(text).get("questionType").toString());
                questionName = getQuestionTypeMap(text).get("content").toString();
                List<XWPFPicture> xwpfPictureList = getXwpfPictureList(xwpfParagraph);
                questionNameXwpfPicture = CollectionUtil.isNotEmpty(xwpfPictureList) ? xwpfPictureList : new ArrayList<>();
                i++;
                //如果标签不是以[答案]或选项A.\A、结尾,该题目为多行一题
                if (questionType.intValue() == 5) {
                    while (!(xwpfParagraphs.get(i).getText().contains(ImportWordQuestionTypeEnum.ANSWER.getDesc()))) {
                        questionName += getObjectValue(xwpfParagraphs.get(i).getText());
                        if (CollectionUtil.isNotEmpty(getXwpfPictureList(xwpfParagraphs.get(i)))) {
                            questionNameXwpfPicture.addAll(getXwpfPictureList(xwpfParagraphs.get(i)));
                        }
                        i++;
                    }
                } else {
                    while (!(xwpfParagraphs.get(i).getText().contains("A"))) {
                        questionName += getObjectValue(xwpfParagraphs.get(i).getText());
                        if (CollectionUtil.isNotEmpty(getXwpfPictureList(xwpfParagraphs.get(i)))) {
                            questionNameXwpfPicture.addAll(getXwpfPictureList(xwpfParagraphs.get(i)));
                        }
                        i++;
                    }
                }

                typeFlag = true;
                contentFlag = true;
            }
            // 获取选项部分
            questionOption = getObjectValue(xwpfParagraphs.get(i).getText());
            if (typeFlag && contentFlag && !optionsFlag && questionOption.contains("A")) {
                // 处理选项
                List<XWPFPicture> xwpfPictureList = getXwpfPictureList(xwpfParagraphs.get(i));
                if (CollectionUtil.isNotEmpty(xwpfPictureList)) {
                    questionsImportWordVo.setOptionXwpfPictureA(xwpfPictureList);
                }
                i++;
                //如果标签不是以[答案]结尾,该试题选项为多行
                while (!xwpfParagraphs.get(i).getText().contains(ImportWordQuestionTypeEnum.ANSWER.getDesc())) {
                    questionOption += getObjectValue(xwpfParagraphs.get(i).getText());
                    //匹配的模式
                    Matcher m = Pattern.compile(optionRegex).matcher(xwpfParagraphs.get(i).getText());
                    if (m.find()) {
                        Method method = TestQuestionsImportWordVo.class.getMethod("setOptionXwpfPicture" + m.group(1), List.class);
                        method.invoke(questionsImportWordVo, getXwpfPictureList(xwpfParagraphs.get(i)));
                    }
                    i++;
                }
            }
            // 获取回答部分
            questionAnswer = getObjectValue(xwpfParagraphs.get(i).getText()).trim();
            if (questionAnswer.startsWith(ImportWordQuestionTypeEnum.ANSWER.getDesc())) {
                // 处理答案
                questionAnswer = getStrContent(questionAnswer, ImportWordQuestionTypeEnum.ANSWER.getDesc()).trim();
                i++;
                //如果标签不是以[章]结尾,该答案为多行
                while (!xwpfParagraphs.get(i).getText().contains(ImportWordQuestionTypeEnum.CHAPTER.getDesc())) {
                    questionAnswer += getObjectValue(xwpfParagraphs.get(i).getText());
                    i++;
                }
                optionsFlag = true;
            }
            // 获取章部分
            questionChapter = getObjectValue(xwpfParagraphs.get(i).getText()).trim();
            if (questionChapter.startsWith(ImportWordQuestionTypeEnum.CHAPTER.getDesc())) {
                // 处理章
                questionChapter = getStrContent(questionChapter, ImportWordQuestionTypeEnum.CHAPTER.getDesc()).trim();
                i++;
                //如果标签不是以[节]结尾,该章为多行
                while (!xwpfParagraphs.get(i).getText().contains(ImportWordQuestionTypeEnum.NODE.getDesc())) {
                    questionChapter += getObjectValue(xwpfParagraphs.get(i).getText());
                    i++;
                }
                optionsFlag = true;
            }
            // 获取节部分
            questionNode = getObjectValue(xwpfParagraphs.get(i).getText()).trim();
            if (questionNode.startsWith(ImportWordQuestionTypeEnum.NODE.getDesc())) {
                // 处理节
                questionNode = getStrContent(questionNode, ImportWordQuestionTypeEnum.NODE.getDesc()).trim();
                i++;
                //如果标签不是以[考点]结尾,该节为多行
                while (!xwpfParagraphs.get(i).getText().contains(ImportWordQuestionTypeEnum.EXAMINATION.getDesc())) {
                    questionNode += getObjectValue(xwpfParagraphs.get(i).getText());
                    i++;
                }
                optionsFlag = true;
            }
            // 获取考点部分
            questionExam = getObjectValue(xwpfParagraphs.get(i).getText()).trim();
            if (questionExam.startsWith(ImportWordQuestionTypeEnum.EXAMINATION.getDesc())) {
                // 处理考点
                questionExam = getStrContent(questionExam, ImportWordQuestionTypeEnum.EXAMINATION.getDesc()).trim();
                i++;
                //如果标签不是以[难度]结尾,该考点为多行
                while (!xwpfParagraphs.get(i).getText().contains(ImportWordQuestionTypeEnum.DIFFICULTY.getDesc())) {
                    questionExam += getObjectValue(xwpfParagraphs.get(i).getText());
                    i++;
                }
                optionsFlag = true;
            }
            // 获取难度部分
            questionDifficulty = getObjectValue(xwpfParagraphs.get(i).getText()).trim();
            if (questionDifficulty.startsWith(ImportWordQuestionTypeEnum.DIFFICULTY.getDesc())) {
                // 处理难度
                questionDifficulty = getStrContent(questionDifficulty, ImportWordQuestionTypeEnum.DIFFICULTY.getDesc()).trim();
                i++;
                optionsFlag = true;
            }
            // 获取解析部分
            questionAnalysis = getObjectValue(xwpfParagraphs.get(i).getText()).trim();
            if (questionAnalysis.startsWith(ImportWordQuestionTypeEnum.ANALYSIS.getDesc())) {
                // 处理解析
                questionAnalysis = getStrContent(questionAnalysis, ImportWordQuestionTypeEnum.ANALYSIS.getDesc()).trim();
                i++;
                //如果不是最后一行,该解析为多行
                while (i != xwpfParagraphs.size()) {
                    questionAnalysis += getObjectValue(xwpfParagraphs.get(i).getText());
                    i++;
                }
                // 恢复完成标志
                typeFlag = false;
                contentFlag = false;
                optionsFlag = false;
            }
            if (ObjectUtil.isNotEmpty(questionType) && StrUtil.isNotBlank(questionName)) {
                questionsImportWordVo.setType(questionType);
                questionsImportWordVo.setName(questionName);
                questionsImportWordVo.setAnswer(questionAnswer);
                questionsImportWordVo.setAnalysis(questionAnalysis);
                questionsImportWordVo.setDifficulty(questionDifficulty);
                questionsImportWordVo.setQbChapName(questionChapter);
                questionsImportWordVo.setQbNodeName(questionNode);
                questionsImportWordVo.setQbExsiName(questionExam);
                if (CollectionUtil.isNotEmpty(questionNameXwpfPicture)) {
                    questionsImportWordVo.setQuestionNameXwpfPicture(questionNameXwpfPicture);
                }
                //试题类型1=单选2=多选3=判断4=填空5=简答
                if (questionType == 1 || questionType == 2 || questionType == 4 || questionType == 6) {
                    //处理选项
                    questionsImportWordVo = divideOption(questionsImportWordVo, questionOption);
                }
                questionsImportWordVoList.add(questionsImportWordVo);
            }
        }
        return questionsImportWordVoList;
    }

    /**
     * 将选项分隔出来
     *
     * @param questionsImportWordVo
     * @param questionOption        选项
     * @return
     */
    @SneakyThrows
    private static TestQuestionsImportWordVo divideOption(TestQuestionsImportWordVo questionsImportWordVo, String questionOption) {
        if (StrUtil.isNotBlank(questionOption)) {
            //选项,如:A,B,C
            String[] optionName = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L"};
            for (int i = 0; i < optionName.length; i++) {
                String option = getOption(questionOption, optionName[i], optionName[i + 1]);
                if (StrUtil.isBlank(option)) {
                    break;
                }
                Method method = TestQuestionsImportWordVo.class.getMethod("setOption" + optionName[i], String.class);
                method.invoke(questionsImportWordVo, option);
            }
        }
        return questionsImportWordVo;
    }

    //判空,如果等于空返回空字符串
    private static String getObjectValue(String value) {
        return StrUtil.isBlank(value) ? "" : value;
    }

    //获取内容
    private static String getStrContent(String content, String questionTypeDesc) {
        return getObjectValue(content.substring(content.indexOf(questionTypeDesc) + questionTypeDesc.length()));
    }

    //获取图片
    private static List<XWPFPicture> getXwpfPictureList(XWPFParagraph xwpfParagraph) {
        //图片
        List<XWPFPicture> resultXwpfPictureList = new ArrayList<>();
        List<XWPFRun> runs = xwpfParagraph.getRuns();
        for (XWPFRun run : runs) {
            //判断是否存在图片,获取图片并上传
            if (CollectionUtil.isNotEmpty(run.getEmbeddedPictures())) {
                //获取图片
                List<XWPFPicture> xwpfPictureList = run.getEmbeddedPictures();
                if (CollectionUtil.isNotEmpty(xwpfPictureList)) {
                    for (XWPFPicture xwpfPicture : xwpfPictureList) {
                        //获取图片类型
                        String fileExtension = xwpfPicture.getPictureData().suggestFileExtension();
                        //获取图片名称
                        String fileName = xwpfPicture.getPictureData().getFileName();
                        System.out.println("图片类型:" + fileExtension);
                        System.out.println("图片名称:" + fileName);
                    }
                    resultXwpfPictureList.addAll(xwpfPictureList);
                }
            }
        }
        return resultXwpfPictureList;
    }

    /**
     * 获取选项
     *
     * @param content 内容
     * @param begin   开始条件
     * @param end     结束条件
     * @return
     */
    private static String getOption(String content, String begin, String end) {
        if (content.contains(end)) {
            return content.substring(content.indexOf(begin), content.indexOf(end));
        } else if (content.contains(begin)) {
            return content.substring(content.indexOf(begin));
        } else {
            return null;
        }
    }

    //获取试题类型
    private static Map<String, Object> getQuestionTypeMap(String text) {
        Map<String, Object> resultMap = new HashMap<>();
        if (text.contains(ImportWordQuestionTypeEnum.SINGLE_CHOICE_QUESTION.getDesc())) {
            resultMap.put("questionType", ImportWordQuestionTypeEnum.SINGLE_CHOICE_QUESTION.getCode());
            resultMap.put("content", text.substring(text.indexOf(ImportWordQuestionTypeEnum.SINGLE_CHOICE_QUESTION.getDesc()) + ImportWordQuestionTypeEnum.SINGLE_CHOICE_QUESTION.getDesc().length()));
            return resultMap;
        } else if (text.contains(ImportWordQuestionTypeEnum.MULTIPLE_CHOICE_QUESTION.getDesc())) {
            resultMap.put("questionType", ImportWordQuestionTypeEnum.MULTIPLE_CHOICE_QUESTION.getCode());
            resultMap.put("content", text.substring(text.indexOf(ImportWordQuestionTypeEnum.MULTIPLE_CHOICE_QUESTION.getDesc()) + ImportWordQuestionTypeEnum.MULTIPLE_CHOICE_QUESTION.getDesc().length()));
            return resultMap;
        } else if (text.contains(ImportWordQuestionTypeEnum.JUDGE_QUESTION.getDesc())) {
            resultMap.put("questionType", ImportWordQuestionTypeEnum.JUDGE_QUESTION.getCode());
            resultMap.put("content", text.substring(text.indexOf(ImportWordQuestionTypeEnum.JUDGE_QUESTION.getDesc()) + ImportWordQuestionTypeEnum.JUDGE_QUESTION.getDesc().length()));
            return resultMap;
        } else if (text.contains(ImportWordQuestionTypeEnum.GAP_FILLING_QUESTION.getDesc())) {
            resultMap.put("questionType", ImportWordQuestionTypeEnum.GAP_FILLING_QUESTION.getCode());
            resultMap.put("content", text.substring(text.indexOf(ImportWordQuestionTypeEnum.GAP_FILLING_QUESTION.getDesc()) + ImportWordQuestionTypeEnum.GAP_FILLING_QUESTION.getDesc().length()));
            return resultMap;
        } else if (text.contains(ImportWordQuestionTypeEnum.QA_QUESTION.getDesc())) {
            resultMap.put("questionType", ImportWordQuestionTypeEnum.QA_QUESTION.getCode());
            resultMap.put("content", text.substring(text.indexOf(ImportWordQuestionTypeEnum.QA_QUESTION.getDesc()) + ImportWordQuestionTypeEnum.QA_QUESTION.getDesc().length()));
            return resultMap;
        } else if (text.contains(ImportWordQuestionTypeEnum.INDEFINITE_TERM_QUESTION.getDesc())) {
            resultMap.put("questionType", ImportWordQuestionTypeEnum.INDEFINITE_TERM_QUESTION.getCode());
            resultMap.put("content", text.substring(text.indexOf(ImportWordQuestionTypeEnum.INDEFINITE_TERM_QUESTION.getDesc()) + ImportWordQuestionTypeEnum.INDEFINITE_TERM_QUESTION.getDesc().length()));
            return resultMap;
        } else if (text.contains(ImportWordQuestionTypeEnum.MATERIAL_QUESTION.getDesc())) {
            resultMap.put("questionType", ImportWordQuestionTypeEnum.MATERIAL_QUESTION.getCode());
            resultMap.put("content", text.substring(text.indexOf(ImportWordQuestionTypeEnum.MATERIAL_QUESTION.getDesc()) + ImportWordQuestionTypeEnum.MATERIAL_QUESTION.getDesc().length()));
            return resultMap;
        } else {
            return null;
        }
    }
}

4、service层代码:

 public Result importWordTestQuestions(TestQuestionsImportDto testQuestionsImportDto) {
        try {
            List<TestQuestionsImportWordVo> questionsImportWordVoList = ImportWordParagraphHandleUtil.analysisImportQuestionSubjectWord(testQuestionsImportDto.getFile());
            if (CollectionUtil.isEmpty(questionsImportWordVoList)) {
                return Result.failed(ResultCode.SUBJECT_NOT_EXIST);
            }
            //试题类型为空数量
            long typeIsEmptyCount = questionsImportWordVoList.stream().filter(testQuestionsImportVo -> ObjectUtil.isEmpty(testQuestionsImportVo.getType())).count();
            if (typeIsEmptyCount > 0) {
                throw new BaseException(ResultCode.SUBJECT_TYPE_IS_EMPTY);
            }
            //存储试题id列表
            List<String> subjectIdList = Lists.newArrayList();
            questionsImportWordVoList.stream().forEach(importWord -> {
                Subject subject = new Subject();
                StringBuffer sbf = new StringBuffer();
                //题目名称
                sbf.append(importWord.getName());
                if (CollectionUtil.isNotEmpty(importWord.getQuestionNameXwpfPicture())) {
                    for (XWPFPicture xwpfPicture : importWord.getQuestionNameXwpfPicture()) {
                        XWPFPictureData pictureData = xwpfPicture.getPictureData();
                        try {
                            MockMultipartFile multipartFile = new MockMultipartFile(pictureData.getFileName(), pictureData.getFileName(), ContentType.APPLICATION_OCTET_STREAM.toString(), pictureData.getPackagePart().getInputStream());
                            //oss上传图片
                            String excelUrl = uploadOSSService.uploadFile(multipartFile, 1);
                            System.out.println("试题图片地址===" + excelUrl);
                            sbf.append(";");
                            sbf.append(excelUrl);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
                subject.setName(sbf.toString());
                subject.setType(importWord.getType());
                //试题类型1=单选2=多选3=判断4=填空5=简答
                if (importWord.getType().intValue() == 2 || importWord.getType().intValue() == 6) {
                    String answers = importWord.getAnswer().chars().mapToObj(b -> (char) b).map(answer -> String.valueOf(answer).toUpperCase()).collect(Collectors.joining(","));
                    subject.setAnswer(answers);
                } else if (importWord.getType().intValue() == 4) {
                    StringBuffer sbu = new StringBuffer();
                    for (int i = 0; i < optionName.length; i++) {
                        try {
                            Method method = importWord.getClass().getMethod("getOption" + optionName[i]);
                            Object o = method.invoke(importWord);
                            if (ObjectUtil.isEmpty(o)) {
                                break;
                            }
                            sbu.append(o.toString().substring(o.toString().indexOf(optionName[i]) + 2)).append(";");
                        } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
                            e.printStackTrace();
                        }
                    }
                    subject.setAnswer(sbu.substring(0, sbu.length() - 1));
                } else {
                    subject.setAnswer(importWord.getAnswer());
                }
                if (StrUtil.isNotBlank(importWord.getAnalysis())) {
                    subject.setAnalysis(importWord.getAnalysis());
                }

                if (StrUtil.isNotBlank(importWord.getDifficulty())) {
                    if ("简单".equals(importWord.getDifficulty())) {
                        subject.setDifficulty(1);
                    } else if ("一般".equals(importWord.getDifficulty())) {
                        subject.setDifficulty(2);
                    } else if ("困难".equals(importWord.getDifficulty())) {
                        subject.setDifficulty(3);
                    }
                }

                subject.setReviewerTime(LocalDateTime.now());
                subject.setCreateTime(LocalDateTime.now());
                subject.setUpdateTime(LocalDateTime.now());
                int count = baseMapper.insert(subject);
                if (count > 0) {
                    subjectIdList.add(subject.getId());
                    //添加试题选项
                    //试题类型1=单选2=多选3=判断4=填空5=简答
                    if (subject.getType() == 1 || subject.getType() == 2 || subject.getType() == 6) {
                        List<Option> optionList = new ArrayList<>();
                        for (int i = 1; i <= optionName.length; i++) {
                            try {
                                Method method = importWord.getClass().getMethod("getOption" + optionName[i - 1]);
                                Object o = method.invoke(importWord);
                                if (ObjectUtil.isEmpty(o)) {
                                    break;
                                }
                                Option option = new Option();
                                option.setName(optionName[i - 1]);
                                StringBuffer sbuf = new StringBuffer();
                                sbuf.append(o.toString().substring(o.toString().indexOf(optionName[i - 1]) + 2));
                                Field optionPictureField = importWord.getClass().getDeclaredField("optionXwpfPicture" + optionName[i - 1]);
                                optionPictureField.setAccessible(true);
                                Object o1 = optionPictureField.get(importWord);
                                List<XWPFPicture> xwpfPictureList = (List<XWPFPicture>) o1;
                                if (CollectionUtil.isNotEmpty(xwpfPictureList)) {
                                    for (XWPFPicture xwpfPicture : xwpfPictureList) {
                                        XWPFPictureData pictureData = xwpfPicture.getPictureData();
                                        try {
                                            MockMultipartFile multipartFile = new MockMultipartFile(pictureData.getFileName(), pictureData.getFileName(), ContentType.APPLICATION_OCTET_STREAM.toString(), pictureData.getPackagePart().getInputStream());
                                            String excelUrl = uploadOSSService.uploadFile(multipartFile, 1);
                                            System.out.println("选项" + optionName[i - 1] + "图片地址===" + excelUrl);
                                            sbuf.append(";");
                                            sbuf.append(excelUrl);
                                        } catch (IOException e) {
                                            e.printStackTrace();
                                        }
                                    }
                                }
                                option.setData(sbuf.toString());
                                option.setSort(i);
                                option.setSubId(subject.getId());
                                option.setCreateTime(LocalDateTime.now());
                                optionList.add(option);
                            } catch (NoSuchFieldException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
                                e.printStackTrace();
                            }
                        }
                        if (CollectionUtil.isNotEmpty(optionList)) {
                            optionService.saveBatch(optionList);
                        }
                    }
                }
            });
            return Result.success();
        } catch (IOException e) {
            e.printStackTrace();
            return Result.failed("上传失败");
        }
    }

5、controller代码:

 /**
     * word导入试题
     *
     * @param file    上传文件
     * @return
     */
    @PostMapping("/importWordTestQuestions")
    public Result importWordTestQuestions(MultipartFile file) {
        String filename = file.getOriginalFilename();
        if (StrUtil.isEmpty(filename)) {
            return Result.failed(ResultCode.PARAM_IS_NULL);
        }
        try {
            TestQuestionsImportDto testQuestionsImportDto = new TestQuestionsImportDto();
            testQuestionsImportDto.setFile(file);
            return subjectService.importWordTestQuestions(testQuestionsImportDto);
        } catch (BaseException e) {
            e.printStackTrace();
            return Result.failed(e.getResultCode());
        }
    }

至此代码完毕,还是有很多需要改进的,希望大神评论指点。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,639评论 6 513
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,093评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 167,079评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,329评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,343评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,047评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,645评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,565评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,095评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,201评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,338评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,014评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,701评论 3 332
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,194评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,320评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,685评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,345评论 2 358

推荐阅读更多精彩内容