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

本文介绍了如何使用Java将word文档中的试题数据导入并存储到数据库。内容涵盖模板要求,如题间距和样式规范,以及代码实现的各个部分,包括依赖引入、VO对象创建、word解析、service和controller层的代码示例。
摘要由CSDN通过智能技术生成

 最近有一个项目需要将一个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(
  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 16
    评论
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值