poi-tl模板引擎根据树形结构输出word文档(文档模板)

        最近在做一个需求,就是根据当前的树形结构,输出到word文档中。下面展示一下小demo

目录

1、输入:

2、输出:文档.docx

3、代码展示

4、测试结果

4.1、模板文档内容

4.2、输出文档

5、总结


1、输入:

root---树节点1
         ------树节点1.1
         ------树节点1.2
    ---树节点2
         ------树节点2.1
                   ------树节点2.1.1
                   ------树节点2.1.2
                   ------树节点2.1.3
         ------树节点2.2

2、输出:文档.docx

文档内容:
1、树节点1
    树节点1.text
1.1、树节点1.1
    树节点1.1.text
1.2、树节点1.2
    树节点1.2.text
2、树节点2
    树节点2.text
2.1、树节点2.1
    树节点2.1.text
2.1.1、树节点2.1.1
    树节点2.1.1.text
2.1.2、树节点2.1.2
    树节点2.1.2.text
2.1.3、树节点2.1.3
    树节点2.1.3.text
2.2、树节点2.2
    树节点2.2.text

3、代码展示

//测试类
public static void main(String[] args) {
        //模板文件路径,后续会给出模板文档全部内容
        String templatePath = "D:\git_projec\区块对v3.docx";
        //输出文档文件路径
        String outputPath = "D:\git_project\测试输出v3.docx";
        outputToWord(templatePath,outputPath);
    }
//文档输出函数
private static void outputToWord(String templatePath,String outputPath) {
        ArrayList<TitleAndContent> list = new ArrayList<>();
        setWordDataList(list);

        //需要将数据封装到Map集合中
        HashMap<String, Object> data = new HashMap<>();
        //使用模板中的占位符,就要告诉模板占位符为哪个,即下面map的key值
        data.put("titleAndContentList", list);

        /*//下面的配置是完成的标签绑定的配置,例如:标签占位符为哪个、标签的开头以什么字符开头
        ConfigureBuilder builder = Configure.builder();
        builder.bind("titleContentList", new TitleContentRender());
        Configure config = builder.build();
        XWPFTemplate template = XWPFTemplate.compile(templatePath, config)
                .render(data);*/

        Configure configure = Configure.builder()
                .useSpringEL().build();
        XWPFTemplate template = XWPFTemplate.compile(templatePath,configure)
                .render(data);

        // 保存生成的 Word 文档
        try (FileOutputStream out = new FileOutputStream(outputPath)) {
            template.write(out);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 关闭模板
        try {
            template.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
//手动创建结构树数据
private static void setWordDataList(List<TitleAndContent> titleAndContentList) {

        Title title1 = new Title("标题1", 1, "style1");
        Title title2 = new Title("标题2", 1, "style1");
        Title title3 = new Title("标题3", 1, "style1");
        Title title1_1 = new Title("标题1.1", 2, "style2");
        Title title1_2 = new Title("标题1.2", 2, "style2");
        Title title2_1 = new Title("标题2.1", 2, "style2");
        Title title3_1 = new Title("标题3.1", 2, "style2");
        Title title3_2 = new Title("标题3.2", 2, "style2");
        Title title1_1_1 = new Title("标题1.1.1", 3, "style3");
        Title title1_1_2 = new Title("标题1.1.2", 3, "style3");


        TitleAndContent titleAndContent3_1 = new TitleAndContent(title3_1, "content3_1",null);
        TitleAndContent titleAndContent3_2 = new TitleAndContent(title3_2, "content3_2",null);
        TitleAndContent titleAndContent3 = new TitleAndContent(title3, "content2");
        List<TitleAndContent> contents1 = titleAndContent3.getTitleAndContents();
        contents1.add(titleAndContent3_1);
        contents1.add(titleAndContent3_2);

        TitleAndContent titleAndContent2_1 = new TitleAndContent(title2_1, "content2_1",null);
        TitleAndContent titleAndContent2 = new TitleAndContent(title2, "content2");
        List<TitleAndContent> contents2 = titleAndContent2.getTitleAndContents();
        contents2.add(titleAndContent2_1);

        TitleAndContent titleAndContent1_1_1 = new TitleAndContent(title1_1_1, "content1_1_1",null);
        TitleAndContent titleAndContent1_1_2 = new TitleAndContent(title1_1_2, "content1_1_2",null);
        TitleAndContent titleAndContent1_1 = new TitleAndContent(title1_1, "content1_1");
        List<TitleAndContent> contents3 = titleAndContent1_1.getTitleAndContents();
        contents3.add(titleAndContent1_1_1);
        contents3.add(titleAndContent1_1_2);
        TitleAndContent titleAndContent1_2 = new TitleAndContent(title1_2, "content1_2", null);

        TitleAndContent titleAndContent1 = new TitleAndContent(title1, "content1");
        List<TitleAndContent> contents = titleAndContent1.getTitleAndContents();
        contents.add(titleAndContent1_1);
        contents.add(titleAndContent1_2);

        //将数据添加到list中
        titleAndContentList.add(titleAndContent1);
        titleAndContentList.add(titleAndContent2);
        titleAndContentList.add(titleAndContent3);


    }
//自定义的标题类
public class Title {
    private String titleName;
    private int level;
    private String style;

    public Title() {
    }

    public Title(String titleName, int level, String style) {

        this.titleName = titleName;
        this.level = level;
        this.style = style;
    }

    public String getTitleName() {
        return titleName;
    }

    public void setTitleName(String titleName) {
        this.titleName = titleName;
    }

    public int getLevel() {
        return level;
    }

    public void setLevel(int level) {
        this.level = level;
    }

    public String getStyle() {
        return style;
    }

    public void setStyle(String style) {
        this.style = style;
    }
}
//自定义的类,用于封装数据,可以说是树节点
public class TitleAndContent {
    private Title title;
    private String content;
    private List<TitleAndContent> titleAndContents = new ArrayList<>();

    public TitleAndContent() {
    }

    public TitleAndContent(Title title, String content) {
        this.title = title;
        this.content = content;
    }

    public TitleAndContent(Title title, String content, List<TitleAndContent> titleAndContents) {
        this.title = title;
        this.content = content;
        this.titleAndContents = titleAndContents;
    }

    public Title getTitle() {
        return title;
    }

    public void setTitle(Title title) {
        this.title = title;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public List<TitleAndContent> getTitleAndContents() {
        return titleAndContents;
    }

    public void setTitleAndContents(List<TitleAndContent> titleAndContents) {
        this.titleAndContents = titleAndContents;
    }
}

4、测试结果

4.1、模板文档内容

        文档内容如下所示,其中的1、1.1等是设置文章标题级别,自行设置即可,输出的内容格式会被设置成文档中标签的格式。

##章节+文本
{{?titleAndContentList}}
1	{{title.titleName}}
{{content}}
{{?titleAndContents}}
1.1	{{title.titleName}}
{{content}}
{{?titleAndContents}}
1.1.1	{{title.titleName}}
{{content}}
{{?titleAndContents}}
1.1.1.1	{{title.titleName}}
{{content}}
{{?titleAndContents}}
1.1.1.1.1	{{title.titleName}}
{{content}}
{{?titleAndContents}}
1.1.1.1.1.1	{{title.titleName}}
{{content}}
{{?titleAndContents}}
1.1.1.1.1.1.1	{{title.titleName}}
{{content}}
{{?titleAndContents}}
1.1.1.1.1.1.1.1	{{title.titleName}}
{{content}}
{{/titleAndContents}}
{{/titleAndContents}}
{{/titleAndContents}}
{{/titleAndContents}}
{{/titleAndContents}}
{{/titleAndContents}}
{{/titleAndContents}}
{{/titleAndContentList}}

文档内容截图

图1.文档内容截图

4.2、输出文档

图2.输出文档内容截图

5、总结

        以上就是一个小demo的实现过程,简单记录下,有什么问题可以探讨下。

下面附上poi-tl文档官网,github上也可以搜索到。

        最后祝你写代码从头顺到尾!

学习之所以会想睡觉,是因为那是梦开始的地方。
?(?ˊ?ˋ)? (开心) ?(?ˊ?ˋ)? (开心)?(?ˊ?ˋ)? (开心)?(?ˊ?ˋ)? (开心)?(?ˊ?ˋ)? (开心)
                                                                                                        ------不写代码不会凸的小刘