基于springBoot+Vue的在线考试:题库的导入与导出

7 篇文章 0 订阅
5 篇文章 17 订阅

基于springBoot+Vue的在线考试系统,在题库管理模块,新增了题库的导入与导出功能:

导入导出题库,使用的是EasyExcel,这里是多个sheet的导入和导出,还是有一点难度的,所以大概说一下(这里只讲后端,前端请自行查看源码):

1.引入依赖:

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
            <version>2.2.6</version>
        </dependency>

2.导出题库:

按题目类型导出Excel,代码如下,注释也在代码中了:

    // 导出题库
    @PostMapping("/exportExcel")
    public void exportExcel(HttpServletResponse response){
        ExcelWriter excelWriter = null;
        try {
            excelWriter = EasyExcel.write(response.getOutputStream()).autoCloseStream(Boolean.FALSE).build();
            // 指定要导出的属性
            Set<String> names = new HashSet<>(8);
            names.add("questionContent");
            names.add("questionAnswer");
            names.add("questionExplain");
            names.add("questionLevelStr");

            // 1. 填空题
            WriteSheet fillSheet = EasyExcel.writerSheet(0, "填空题").head(QuestionDto.class)
                    .includeColumnFiledNames(names).build();
            List<QuestionDto> fillData = fillQuestionService.getListByPage(null);
            excelWriter.write(fillData,fillSheet);
            // 2. 判断题
            WriteSheet judgeSheet = EasyExcel.writerSheet(1, "判断题").head(QuestionDto.class)
                    .includeColumnFiledNames(names).build();
            List<QuestionDto> judgeData = judgeQuestionService.getListByPage(null);
            excelWriter.write(judgeData,judgeSheet);

            // 选择题导出的属性,增加四个选项
            names.add("choiceA");
            names.add("choiceB");
            names.add("choiceC");
            names.add("choiceD");

            // 3. 单选题
            WriteSheet singleSheet = EasyExcel.writerSheet(2, "单选题").head(QuestionDto.class)
                    .includeColumnFiledNames(names).build();
            List<QuestionDto> singleData = singleQuestionService.getListByPage(null);
            excelWriter.write(singleData,singleSheet);
            // 4. 多选题
            WriteSheet multiSheet = EasyExcel.writerSheet(3, "多选题").head(QuestionDto.class)
                    .includeColumnFiledNames(names).build();
            List<QuestionDto> multiData = multiQuestionService.getListByPage(null);
            excelWriter.write(multiData,multiSheet);

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 千万别忘记finish 会帮忙关闭流
            if (excelWriter != null) {
                excelWriter.finish();
            }
        }
    }

3.题库导入:

    // 导入题库
    @PostMapping("/import")
    public ResultUtil importExcel(MultipartFile file){
        ExcelReader excelReader = null;
        try {
            excelReader = EasyExcel.read(file.getInputStream()).build();
            FillListener fillListener = new FillListener(fillQuestionService);
            JudgeListener judgeListener = new JudgeListener(judgeQuestionService);
            SingleListener singleListener = new SingleListener(singleQuestionService);
            MultiListener multiListener = new MultiListener(multiQuestionService);
            ReadSheet sheet0 = EasyExcel.readSheet(0).registerReadListener(fillListener).headRowNumber(1).build();
            ReadSheet sheet1 = EasyExcel.readSheet(1).registerReadListener(judgeListener).headRowNumber(1).build();
            ReadSheet sheet2 = EasyExcel.readSheet(2).registerReadListener(singleListener).headRowNumber(1).build();
            ReadSheet sheet3 = EasyExcel.readSheet(3).registerReadListener(multiListener).headRowNumber(1).build();
            excelReader.read(sheet0,sheet1,sheet2,sheet3);
        } catch (IOException e) {
            e.printStackTrace();
            return new ResultUtil(EnumCode.OK.getValue(),"导入失败");
        }finally {
            if (excelReader != null) {
                // 这里千万别忘记关闭,读的时候会创建临时文件,到时磁盘会崩的
                excelReader.finish();
            }
        }
        return new ResultUtil(EnumCode.OK.getValue(),"导入成功");
    }

这里有FillListener 之类的Listener,继承了AnalysisEventListener,主要是为了实现业务数据的组装的,以填空题为例:

public class FillListener extends AnalysisEventListener<Map<Integer,String>>{
    private List<FillQuestion> fillQuestionList;
    private FillQuestionService fillQuestionService;

    public FillListener(FillQuestionService questionService){
        this.fillQuestionService = questionService;
        this.fillQuestionList = new ArrayList<>();
    }

    @Override
    public void invoke(Map<Integer, String> map, AnalysisContext analysisContext) {
        FillQuestion question = new FillQuestion();
        question.setId(UUID.randomUUID().toString().replace("-",""));
        question.setCreateTime(new Date());
        question.setQuestionContent(map.get(0));
        question.setQuestionAnswer(map.get(1));
        question.setQuestionExplain(map.get(2));
        question.setQuestionLevel(QuestionLevelMap.getLevelByValue(map.get(3)));
        fillQuestionList.add(question);
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        // 将数据插入数据库
        fillQuestionService.batchInsert(fillQuestionList);
        fillQuestionList.clear();
    }

在AnalysisEventListener中,我使用是泛型是Map<Integer,String>,表示将每一行数据封装成map,key是第几列,从0开始,value就是值,之所以用map接收,是因为有一些数据字典的值需求自己转换,如题目难度:

导入的时候是:简单、中等、困难,但是存入数据库是:1,2,3,所以需要转换

在invoke方法封装成自己需要的对象:

    @Override
    public void invoke(Map<Integer, String> map, AnalysisContext analysisContext) {
        FillQuestion question = new FillQuestion();
        question.setId(UUID.randomUUID().toString().replace("-",""));
        question.setCreateTime(new Date());
        question.setQuestionContent(map.get(0));
        question.setQuestionAnswer(map.get(1));
        question.setQuestionExplain(map.get(2));
        question.setQuestionLevel(QuestionLevelMap.getLevelByValue(map.get(3)));
        fillQuestionList.add(question);
    }

最后执行批量插入即可:

    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        // 将数据插入数据库
        fillQuestionService.batchInsert(fillQuestionList);
        fillQuestionList.clear();
    }

批量插入的实现,这里使用的是foreach循环:

    <!--批量插入-->
    <insert id="batchInsert">
        INSERT INTO fill_question(id,create_time,question_content,question_answer,question_explain,question_level) VALUES
        <foreach collection="list" item="question" separator=",">
          (#{question.id}, #{question.createTime},#{question.questionContent}, #{question.questionAnswer}, #{question.questionExplain}, #{question.questionLevel})
        </foreach>
    </insert>

 

  • 3
    点赞
  • 53
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值