java開發以word文檔錄入試題的考試系統

eclipse,maven,jdbc

一:流程說明,

1、以word文檔形式的的試卷,格式要求第一行爲試卷名,以非word自動生成的數字爲題號 開頭,以題型或固定格式文字爲結尾,這裏使用'[單選題]'。上傳word,解析word文檔內容,詳細解析出試卷名,題號,問題,選項,題型等插入數據庫。注,同試卷不能重複錄入。

2、插入對應的答案和分值。 

3、考試計分。

二:pom,有部分依賴沒有用到,可刪除

<dependencies>
        <dependency>
            <groupId>org.jsoup</groupId>
            <artifactId>jsoup</artifactId>
            <version>1.8.1</version>
        </dependency>

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.11</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.11</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml-schemas</artifactId>
            <version>3.11</version>
        </dependency>

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-scratchpad</artifactId>
            <version>3.11</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.3.2</version>
        </dependency>
        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.5</version>
        </dependency>

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-examples</artifactId>
            <version>3.11</version>
        </dependency>

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-excelant</artifactId>
            <version>3.11</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.41</version>
        </dependency>
    </dependencies>
    
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.2</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>

一:word文檔錄入;

@Test
    public void didposeTestFinal() {
        ArrayList<Question> list = new ArrayList<>();
        XWPFDocument doc = null;
        try{
            doc = new XWPFDocument(POIXMLDocument.openPackage("E:/test.docx"));
            
            List<XWPFParagraph> paragraphs = doc.getParagraphs();
            System.out.println(paragraphs.size());
            /**
             * 處理paragraphs
             *         每個paragraphs是一行文本內容
             */
            String rule = "^[\\d]{1,3}$";        //正則表達式,^表示起始,$表示結束
//            String ruleA = "^[A-E]";
            Pattern pTitle = Pattern.compile(rule);
            //首先確定第一行爲試卷標題。title
            for (int i = 1;i < paragraphs.size();i++) {
                String text = paragraphs.get(i).getParagraphText().trim();   //獲取選中行的內容   去空格
                //匹配題目,先整行一題
                Matcher pTm = pTitle.matcher(text.substring(0, text.indexOf("、") == -1 ? 0 : text.indexOf("、")));   //正則匹配是否有題號
                boolean matcher = pTm.find();    //注意,pTm.find()第一次使用時爲正常匹配,連續使用會無效,所以需要把這個提取出來
                if(matcher && text.contains("[單選題]")){  //如果題號匹配上且以題型結尾,說明是一行的題
                    //單選,整行一題 
                    Question q = new Question();
                    q.setTitle(paragraphs.get(0).getParagraphText());  //設置問題的試卷名,所有問題都是以第一行的試卷名
                    q.setNumber(Integer.parseInt(pTm.group(0)));        //獲取匹配的項。
                    q.setQuestion(text);                                //設置問題內容
                    
                    i = matchingAnswer(paragraphs, pTitle, i, q);        //匹配答案
                    
                    q.setQuestionType(QuestionType.SINGLE_SELECT);        //設置題型,這裏使用了枚舉,不好用,可以直接使用String
                    q.setRightAnswer(null);                             //錄入的時候沒有正確答案和得分
                    q.setGetScore(null);
                    list.add(q);                                        //加入list
                }else if(matcher&&!text.contains("[單選題]")){
                    //多行一題,題號開頭。非題型結尾
                    i++;       //先跳下一行
                    while(!paragraphs.get(i).getParagraphText().contains("[單選題]")){ //如果當前行不是以題型結尾
                        text = text + paragraphs.get(i).getParagraphText();             //題目內容拼接
                        i++;                                                         //跳轉下一行
                    }
                    text = text + paragraphs.get(i).getParagraphText();                 //如果是以題型爲結尾,則跳出循環,拼接題目內容爲最終內容
                    
                    Question q = new Question();
                    q.setTitle(paragraphs.get(0).getParagraphText());
                    q.setNumber(Integer.parseInt(pTm.group(0)));
                    q.setQuestion(text);
                    
                    i = matchingAnswer(paragraphs, pTitle, i, q);
                    
                    q.setQuestionType(QuestionType.SINGLE_SELECT);
                    q.setRightAnswer(null);
                    q.setGetScore(null);
                    
                    list.add(q);
                }else if(matcher && text.contains("[多選題]")){
                    //多選,整行一題 
                    Question q = new Question();
                    q.setTitle(paragraphs.get(0).getParagraphText());
                    q.setNumber(Integer.parseInt(pTm.group(0)));
                    q.setQuestion(text);
                    
                    i = matchingAnswer(paragraphs, pTitle, i, q);
                    
                    q.setQuestionType(QuestionType.MULTI_SELECT);
                    q.setRightAnswer(null); 
                    q.setGetScore(null);
                    
                    list.add(q);
                    
                }else if(matcher && !text.contains("[多選題]")){
                    i++;       //先跳下一行
                    while(!paragraphs.get(i).getParagraphText().contains("[多選題]")){ //如果當前行不是以題型結尾
                        text = text + paragraphs.get(i).getParagraphText();             //題目內容拼接
                        i++;                                                         //跳轉下一行
                    }
                    text = text + paragraphs.get(i).getParagraphText();                 //如果是以題型爲結尾,則跳出循環,拼接題目內容爲最終內容
                    
                    Question q = new Question();
                    q.setTitle(paragraphs.get(0).getParagraphText());
                    q.setNumber(Integer.parseInt(pTm.group(0)));
                    q.setQuestion(text);
                    
                    i = matchingAnswer(paragraphs, pTitle, i, q);
                    
                    q.setQuestionType(QuestionType.MULTI_SELECT);
                    q.setRightAnswer(null);
                    q.setGetScore(null);
                    
                    list.add(q);
                }
            }
            for(int i=0;i<list.size();i++){
                System.out.println(list.get(i).toString());
            }
            if(list.size()<100){
                System.out.println("試卷錄入異常,題數不足100");
                System.exit(0);
//                throw new Exception("試卷錄入異常,題數不足100");
            }
            Examination e = new Examination();
            e.insertExamination(list);
        }catch(Exception e){
            e.printStackTrace();
        }
    }

    private int matchingAnswer(List<XWPFParagraph> paragraphs, Pattern pTitle, int i, Question q) {
        String text;
        //匹配答案
        while(true){  //多行答案處理!!!!!!!!!!
            i++;   //先加一行
            text = paragraphs.get(i).getParagraphText().trim();
            
            if( text != null && text != "" ){
                //如果4個答案在一行,或者5個答案在一行
                if(text.contains("A")&& text.contains("B")&&text.contains("C")&&text.contains("D")){
                    q.setAnswerA(text.substring(0,text.indexOf("B")));
                    q.setAnswerB(text.substring(text.indexOf("B"),text.indexOf("C")));
                    q.setAnswerC(text.substring(text.indexOf("C"),text.indexOf("D")));
                    if(text.contains("E")){
                        q.setAnswerD(text.substring(text.indexOf("D"),text.indexOf("E")));
                        q.setAnswerE(text.substring(text.indexOf("E")));
                    }else{
                        q.setAnswerD(text.substring(text.indexOf("D")));
                    }
                    break;
                }
                if( text.startsWith("A") ){
                    while(!paragraphs.get(i+1).getParagraphText().trim().startsWith("B")){
                        i++;
                        text = text + paragraphs.get(i).getParagraphText();
                    }
                    q.setAnswerA(text);
                }else if( text.startsWith("B") ){
                    while(!paragraphs.get(i+1).getParagraphText().trim().startsWith("C")){
                        i++;
                        text = text + paragraphs.get(i).getParagraphText();
                    }
                    q.setAnswerB(text);
                }else if( text.startsWith("C") ){
                    while(!paragraphs.get(i+1).getParagraphText().trim().startsWith("D")){
                        i++;
                        text = text + paragraphs.get(i).getParagraphText();
                    }
                    q.setAnswerC(text);
                }else if( text.startsWith("D") ){
                    if(paragraphs.size() == i+1){  //防止已經到最後一行了,防止索引越界
                        q.setAnswerD(text);
                        break;
                    }
                    String textD = paragraphs.get(i+1).getParagraphText().trim();
                    System.out.println(textD);
                    System.out.println(pTitle.matcher(textD.substring(0, textD.indexOf("、") == -1 ? 0 : textD.indexOf("、"))).find());
                    while( textD != null &&     //如果選項中有4項時,這一行有內容,且不是題號開頭,
                            !pTitle.matcher(textD.substring(0, textD.indexOf("、") == -1 ? 0 : textD.indexOf("、"))).find() 
                            && !textD.equals("")){
                        if( textD.startsWith("E")){   //如果是E開頭,說明有答案E,
                            q.setAnswerD(text);
                            break;
                        }
                        i++;
                        text = text + paragraphs.get(i).getParagraphText();
                    }
                    q.setAnswerD(text);
                    break;
                }else if( text.startsWith("E")){
                    if(paragraphs.size() == i+1){
                        q.setAnswerD(text);
                        break;
                    }
                    String textE = paragraphs.get(i+1).getParagraphText().trim();
                    System.out.println(pTitle.matcher(textE.substring(0, textE.indexOf("、") == -1 ? 0 : textE.indexOf("、"))).find());
                    while( textE != null && 
                            !pTitle.matcher(textE.substring(0, textE.indexOf("、") == -1 ? 0 : textE.indexOf("、"))).find() && !textE.equals("")){
                        i++;
                        text = text + paragraphs.get(i).getParagraphText();
                    }
                    q.setAnswerE(text);
                    break;
                }
            }
        }
        return i;
    }

jdbc----------------

public Boolean insertExamination(List<Question> list) throws SQLException, ClassNotFoundException{
        
        Class.forName("com.mysql.jdbc.Driver");
        java.sql.Connection conn = DriverManager.getConnection(
                "jdbc:mysql://***************************?characterEncoding=UTF-8","root","123456");
        
        java.sql.PreparedStatement ps = conn.prepareStatement("insert into yucs_exam "
                + "(title,number,answerA,answerB,answerC,answerD,answerE,questionType,rightAnswer,getScore,question)"
                + " values (?,?,?,?,?,?,?,?,?,?,?)");
        
        for(int i =0; i<list.size(); i++){
            Question question = list.get(i);
            ps.setString(1, question.getTitle() ==null ? "":question.getTitle());
            ps.setInt(2, question.getNumber()==null?0:question.getNumber());
            ps.setString(3, question.getAnswerA()==null?"":question.getAnswerA());
            ps.setString(4, question.getAnswerB()==null?"":question.getAnswerB());
            ps.setString(5, question.getAnswerC()==null?"":question.getAnswerC());
            ps.setString(6, question.getAnswerD()==null?"":question.getAnswerD());
            ps.setString(7, question.getAnswerE()==null?"":question.getAnswerE());
            ps.setString(8, question.getQuestionType()==null ? QuestionType.SINGLE_SELECT +"":question.getQuestionType()+"");
            ps.setString(9, question.getRightAnswer()==null?"":question.getRightAnswer());
            ps.setInt(10, question.getGetScore()==null?0:question.getGetScore());
            ps.setString(11, question.getQuestion());
            ps.addBatch();
        }
        ps.executeBatch();
        conn.close();
        return false;
    }

二:答案及分值錄入,使用測試手段

@Test
    public void insertAnswer() throws Exception{
        String[] ss = {"A","B","C","D"};
        Random r = new Random();
        ArrayList<Question> list = new ArrayList<>();
        for(int i = 1 ; i<=100;i++){
            int nextInt = r.nextInt(4);
            Question q = new Question();
            q.setRightAnswer(ss[nextInt]);
            q.setGetScore(1);
            q.setTitle("test");
            q.setNumber(i);
            list.add(q);
        }
        Examination e = new Examination();
        e.insertAnswerAndScore(list);
    }

jdbc--------------

public Boolean insertAnswerAndScore(List<Question> list) throws Exception{
        Class.forName("com.mysql.jdbc.Driver");
        java.sql.Connection conn = DriverManager.getConnection(
                "jdbc:mysql://****************************?characterEncoding=UTF-8","root","123456");
        
        java.sql.PreparedStatement ps = conn.prepareStatement("update yucs_exam set rightAnswer=?,getScore=? where title =? and number=?");
        
        for(int i =0; i<list.size(); i++){
            Question question = list.get(i);
            ps.setString(1, question.getRightAnswer()==null?"":question.getRightAnswer());
            ps.setInt(2, question.getGetScore()==null?0:question.getGetScore());
            ps.setString(3, question.getTitle());
            ps.setInt(4, question.getNumber());
            ps.addBatch();
        }
        ps.executeBatch();
        conn.close();
        
        return true;
    }

三:計分

/**
     * 打分系統
     * 獲取考生答題項:包括試卷title或編號、考生id、答題答案
     * 
     * 1,匹配數據庫,獲取表中當前卷的正確答案
     *         1、單選,直接匹配
     *         2、多選,----------
     * @throws Exception
     */
    @Test
    public void checkAnswer() throws Exception{
        Examination e = new Examination();
        Map<Integer,Question> m = e.checkAnswer();
        
        String[] ss = {"A","B","C","D"};
        Random r = new Random();
        ArrayList<Question> list = new ArrayList<>();
        for(int i = 1 ; i<=100;i++){
            int nextInt = r.nextInt(4);
            Question q = new Question();
            q.setRightAnswer(ss[nextInt]);
            q.setTitle("testOne");
            q.setNumber(i);
            list.add(q);
        }
        
        int totalScore = 0;
        for(int j =0; j<list.size();j++){
            String rightAnswer = m.get(j+1).getRightAnswer();
            String rightAnswer2 = list.get(j).getRightAnswer();
            if(m.get(j+1).getQuestionType().equals(QuestionType.SINGLE_SELECT)){
                //單選
                if(rightAnswer.equals(rightAnswer2)){
                    totalScore += m.get(j).getGetScore();     //如果答案匹配正確,得分
                }
            }else if(m.get(j+1).getQuestionType().equals(QuestionType.MULTI_SELECT)){
                //多選
                m.get(j+1).getRightAnswer();
                String[] answers = rightAnswer.split(",");   //截取答案
                String[] answers2 = rightAnswer2.split(",");
                if(Arrays.equals(answers, answers2)){        //如果答案完全匹配,得全分
                    totalScore += m.get(j).getGetScore();
                }else {                    //否則說明答案不完全正確,需要詳細匹配。                    
                    for(int i=0; i<answers2.length;i++){    
                        if(!Arrays.asList(answers).contains(answers2[i])){        //否則,具體匹配,如果有一個選項不在正確答案選項中,則不得分,整題不正確
                            continue;        //跳過當前題的
                        }
                    }
                    totalScore += (m.get(j).getGetScore()/2);        //如果選項沒有錯誤的,說明答案不完全,給一半分。
                }
            }
            
        }
        
        System.out.println(totalScore);
        
    }

jdbc---------------

public Map<Integer,Question> checkAnswer() throws Exception{
        Class.forName("com.mysql.jdbc.Driver");
        java.sql.Connection conn = DriverManager.getConnection(
                "jdbc:mysql://**********************************?characterEncoding=UTF-8","root","123456");
        
        java.sql.PreparedStatement ps = conn.prepareStatement("select rightAnswer,number,questionType,getScore from yucs_exam "
                + "where title=?");
        
        ps.setString(1, "test");
        
        ResultSet executeQuery = ps.executeQuery();
        
        Map<Integer, Question> m  = new HashMap<>();
        while(executeQuery.next()){
            Question q = new Question();
            q.setRightAnswer(executeQuery.getString(1));
            int int1 = executeQuery.getInt(2);
            q.setNumber(int1);            //以題號做map,方便匹配
            q.setQuestionType(QuestionType.SINGLE_SELECT);
            q.setGetScore(executeQuery.getInt(4));
            
            m.put(int1, q);
        }
        
        System.out.println(m.size());
        conn.close();
        return m;
        
    }

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章