本文讲解通过 WordGo,生成word文件,并通过该项目实现,生成试卷 word 文件。

业务背景

一个试题库系统组卷功能,需要将获取到的试题,通过一定排版,生成word文件。通常来说我们可以通过freemark 模板引擎生成试卷,但是需要编写固定的模板文件,十分繁琐与麻烦,不够灵活。wordgo 是一个通过Java实现的word文件生成工具。通过其提供的 API 方法,我们可以很便捷生成所需格式的 word 文件。

WordGo 介绍

WordGO - 让Java生成word文档更容易。更多API方法,请看官方项目文档

兼容性说明

导入

不知道为什么通过maven下载不了,我是通过jar包引入的。

  • IDEA导入:点击File-Project Structure;然后在左侧找到Modules并点击;最后在右侧点击绿色的+号,选择JARs or directories选取要导入的jar包即可。
  • Maven导入:添加下述maven依赖即可。
<dependency>
 <groupId>com.github.qrpcode</groupId>
 <artifactId>wordgo</artifactId>
 <version>1.0-SNAPSHOT</version>
</dependency>

常用 API 方法

// 设置word页面大小为 A3,纸张横向显示
WordPaper paper = new WordPaper("A3", true);

// 新建一个word
WordGo wordGo = new WordGo(paper);

// 添加文字,并设置文字样式
wordGo.add("Hello World", "font-size: 15; color: #FF0000");

// 添加文字,并设置文字样式,并在后面添加换行符
wordGo.addLine("Hello World", "font-size: 15; color: #FF0000");

// 生成文件,文件名必须以.docx结尾
wordGo.create("C:\\demo.docx");

生成试卷

数据表信息

  • question_single_choice:单选题:
  • question_multiple_choice:多选题:
  • question_case_father:案例题(题干,一个案例题由多个小题组成)
  • question_case_child:案例题(小题)
  • question_case_father_child_relation:案例题(主题、子题关联)

image-20201025084317348
image-20201025084401750
image-20201025084702869

生成单选题

private void generatorSingleChoiceQuestion(WordGo word, int i, @NotNull List<QuestionSingleChoice> singleChoiceListList) {

    generatorQuestionTitle(word, "(一)单项选择题(每题正确答案选项仅为一个,每题1分)");
    // 简单的输出换行符,通过 数字指定换行数量
    addBlankLine(word, 1);
    
    for (; i < singleChoiceListList.size(); i++) {
        // 生成题目题干
        generatorQuestion(word, i, singleChoiceListList.get(i).getQuestion());
        // 生成单选题选项
        generatorQuestionOptions(word, singleChoiceListList.get(i));
        addBlankLine(word, 1);
    }

    addBlankLine(word, 1);
}

// 生成题目标题
private void generatorQuestionTitle(WordGo word, String title) {
        word.addLine(title, "font-width:bold;font-family:宋体;");
}

// 生成题目
private void generatorQuestion(WordGo word, int i, String question) {
        word.addLine((i + 1) + ". " + question, "font-size:五号;font-family:宋体;");
}

// 生成单选题目选项
private static void generatorQuestionOptions(WordGo word, QuestionSingleChoice singleChoice) {
        generatorOptions(word, singleChoice.getA(), singleChoice.getB(), singleChoice.getC(), singleChoice.getD(), singleChoice.getE());
}

// 生成题目选项
private static void generatorOptions(WordGo word, String a, String b, String c, String d, String e) {
    // 通用样式 "font-size: 五号; font-family: 宋体;"
	word.addLine("A" + ". " + a, COMMON_FONT_STYLE);
	word.addLine("B" + ". " + b, COMMON_FONT_STYLE);
	word.addLine("C" + ". " + c, COMMON_FONT_STYLE);
	word.addLine("D" + ". " + d, COMMON_FONT_STYLE);
	word.addLine("E" + ". " + e, COMMON_FONT_STYLE);
}

生成多选题

// 主要代码与上面单选题一致,省略部分代码。
private void generatorMultipleChoiceQuestion(WordGo word, int i, @NotNull List<QuestionMultipleChoice> multipleChoiceListList) {
    // 生成多选题标题
    generatorQuestionTitle(word, "(二)多项选择题(题目答案为不少于两个选项,错选、漏选、多选均不得分,每题1分)");
    addBlankLine(word, 1);

    for (; i < multipleChoiceListList.size(); i++) {
        // 生成题目题干
        generatorQuestion(word, i, multipleChoiceListList.get(i).getQuestion());
        // 生成多选题选项
        generatorQuestionOptions(word, multipleChoiceListList.get(i));
        addBlankLine(word, 1);
    }

    addBlankLine(word, 1);
}

生成案例题

private void generatorCaseQuestion(WordGo word, int i, @NotNull List<QuestionCaseFather> caseFatherList){
    // 生成案例标题
    generatorQuestionTitle(word, "(三)案例题(部分题目以案例内容作为共用题干,共用题干下的题目考查内容皆与案例相关;除在题目前注明“单选题”的题目正确答案为单选项外,其余题目正确答案皆为不定项,即不限定答案选项个数,可为单个,可为多个,错选、多选、漏选,均不得分。)");
    addBlankLine(word, 1);

    for (; i < caseFatherList.size(); i++) {
        List<QuestionCaseChild> childList = getCaseChildByFatherId(caseFatherList.get(i).getId());
        
        if (CollUtil.isEmpty(childList)){
            continue;
        }
        
        // 生成案例题题干
        generatorQuestion(word, i, caseFatherList.get(i).getQuestion());

        for (int j = 1; j < childList.size(); j++){
            generatorCaseChoiceQuestion(word, i, childList.get(j));
            generatorQuestionOptions(word, childList.get(j));

            addBlankLine(word, 1);
        }

        addBlankLine(word, 1);
    }

    addBlankLine(word, 1);
}

生成试卷

private void generator() {
    LOGGER.info("start generating paper!");
    WordGo word = new WordGo();

    word.addLine("试卷标题", TITLE_FONT_STYLE);
    addBlankLine(word, 2);

    int i = 0;

    generatorSingleChoiceQuestion(word, i, getQuestionSingleChoiceList());
    generatorMultipleChoiceQuestion(word, i, getQuestionMultipleChoiceList());
    generatorCaseQuestion(word, i, getQuestionCaseFatherList());
    
    word.create("E:\\wordgo\\demo.docx");

    LOGGER.info("end generating paper!");
}

样例效果

image-20201025090000523