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

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

一、word模板

要求:

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*/@SneakyThrowsprivate 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*/@SneakyThrowsprivate static TestQuestionsImportWordVo divideOption(TestQuestionsImportWordVo questionsImportWordVo, String questionOption) {if (StrUtil.isNotBlank(questionOption)) {//选项,如:A,B,CString[] 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());}}

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

java实现导入word模板导入试题相关推荐

  1. Vue 自定义富文本编辑器 tinymce 支持导入 word 模板

    自定义富文本编辑器分为前端项目和后端项目两个部分,首先先说一下前端项目 前端 前端项目地址: https://github.com/haoxiaoyong1014/editor-ui 编辑器名称: t ...

  2. Java实现根据Word模板填充表格数据(poi方式),以及doc和docx转PDF,最全最详细版本,解决外部引用jar在linux上报ClassNotFound的问题。

    Java实现根据Word模板填充表格数据(poi方式),以及doc和docx转PDF,最全最详细版本,解决外部引用jar在linux上报ClassNotFound的问题. 适用场景: 1.固定格式的W ...

  3. vue 是否有word编辑控件_GitHub - C84882428/editor-ui: vue集成 tinymce 富文本编辑器,增加导入 word 模板...

    editor-ui vue 集成 tinymce 富文本编辑器 自定义 tinymce 富文本编辑器, 在原来的编辑器中增加上传 word 模板 最终展示效果: 主要代码: 整体思路: 1,在编辑器原 ...

  4. Java根据excel/word模板进行值替换并且打成压缩包

    目录 一  前端代码(MbTemplateList.vue) 二  后端代码 MbTemplateController.java IMbTemplateService.java MbTemplateS ...

  5. java 导出word,java根据提供word模板导出word文档

    本文主要讲解,利用poi-tl在word中动态生成表格行,进行文字.图片填充.一共提供了两种方式,1.基于本地文件 2.基于网络文件 本文讲解思路,1.先看示例,2. 示例对应的代码展示 3. 基本概 ...

  6. 基于Easypoi+jfree,使用SpringBoot架构,Java编程实现word模板导出Word报表

    目录 1.项目目录结构 2.pom.xml添加的依赖 3.编写jfreeutil工具类 4.编写wordutil工具类 5.编写word模板 7.运行效果 8.复杂布局实现 8.1如何实现图片并排 S ...

  7. java根据提供word模板导出word文档

    涉及主要jar包为 freemarker-2.3.10.jar,servlet-api-2.4.jar. (1)首先修改 word模板如下形式,把需要查询写入word的值用${}形式封装 (2)把 w ...

  8. JAVA ( EasyExcel 通过模板 导入、导出、下载模板)——亲测有用

    本文参考:https://liuyanzhao.com/10060.html 先说两个实体类对象. 我这里举例 Student 和 StudentExcel Student 就是你数据库表的对象 St ...

  9. asp.net 页面数据导入word模板

    首先添加应用"Microsoft Word 11.0 Object library"的COM组件,从而来实现读取word文档的对象. 点击事件代码 代码 protected voi ...

最新文章

  1. 01两数之和(哈希表)
  2. https和http的主要区别
  3. 大牛书单 | 云原生技术领域好书推荐
  4. CLR Via C# 学习笔记(5) 静态构造函数的性能
  5. 大学计算机学情分析,大学生学情分析
  6. 【转】C# 控件的自定义拖动、改变大小方法
  7. 2022华为杯研究生数学建模竞赛F题思路解析
  8. pyLDA系列︱gensim中的主题模型(Latent Dirichlet Allocation)
  9. Score UVA - 1585
  10. 英语情景对话计算机专业,工作有关情景对话英语
  11. 如何利用python盗qq_一个团队为了让我帮他提高流量,竟然盗我QQ,没办法,我只好帮他用python刷了刷流量!...
  12. 使用curl查询本机ipv4或者ipv6
  13. Beautiful Soup 4.2.0 文档¶
  14. 总结五:如何正确的编写招聘程序员职位描述
  15. 清理C盘(浪费了很多时间,终于找到了一个比较高效的方法)
  16. kermit的安装、配置、使用 .
  17. jQuery中的end()的定义与用法
  18. linux全角和半角的切换,全角和半角
  19. 编程趣味知识:固执的“and”和变通的“or”
  20. SRM587 (div2)

热门文章

  1. php滴滴抢单系统,抢单系统_抢单系统教程_抢单系统视频教程 _课课家
  2. lane是什么意思_lane是什么意思
  3. 五脏六腑在脸上的反射区图片_面部穴位对应的反射区图片
  4. ​美国多项经济数据表现不佳 美元走势将难以摆脱颓势?
  5. IBM:蓝色巨人是颓势?还是沉淀?
  6. 随着投资者转向其他投资领域,证券交易狂热有所缓解
  7. CSS实现隐藏滚动条并可以滚动内容
  8. 【张朝阳的物理课笔记】 7. 气体的内能,能量均分原理,量子物理的曙光
  9. ubuntu 20.04挂载机械硬盘及修改windows下ntfs格式读写权限的详细步骤
  10. 调用手机扫二维码 并且识别其信息