Java使用poi-tl库操作wold文档的方法

 更新时间:2025年11月26日 11:48:51   作者:布Coder  
java项目实际开发中经常会遇到制作word表单且表格数据行循环功能,这篇文章主要介绍了Java使用poi-tl库操作wold文档的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下

poi-tl 是一个基于Apache POI的Word模板引擎,也是一个免费开源的Java类库,

适用范围:

在线文档生成、合同签订、信息替换方面具有很大优势、采用 标签-替换的实现策略,简单易上手、避免实际业务中的重复开发. 业务与设计解藕.

开始操作

引入 poi-tl 项目

        <poi-version>5.4.0</poi-version>
        
        -- poi 项目依赖

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>${poi-version}</version>
        </dependency>

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>${poi-version}</version>
        </dependency>

        -- poi-tl 项目依赖
        <dependency>
            <groupId>com.deepoove</groupId>
            <artifactId>poi-tl</artifactId>
            <version>1.12.2</version>
        </dependency>

本讲介绍模版生成(poi - tl支持无模版生成)

读取模版文件、并且定义结果输出

        XWPFTemplate
                .compile("模版文档.docx")
                .render(map)
                .writeAndClose(new FileOutputStream("01.docx"));
  • XWPFTemplate :  模版操作类
    • compile : 模版文档
    • render : 数据
    • writeAndClose : 结果输出

普通图文本替换 (文档内容 {{key}})

模版文件

代码

        HashMap<String, Object> renderMap = new HashMap<>();

        renderMap.put("text","我是被替换的内容");

        XWPFTemplate
                .compile("空白文档.docx")
                .render(renderMap).
                writeAndClose(new FileOutputStream("01.docx"));

输出文件

列表内容生成 {{#key}}

模版

代码实现

        HashMap<String, Object> renderMap = new HashMap<>();

        renderMap.put("text", "我是被替换的内容");

        HashMap<String, Object> ones = new HashMap<>();

        ones.put("name", "981129-1");
        ones.put("date", new Date());

        ArrayList<Object> list = new ArrayList<>();
        list.add(ones);
        list.add(ones);
        list.add(ones);
        list.add(ones);

        renderMap.put("list", list);

        // 表格循环插件
        LoopRowTableRenderPolicy rowTableRenderPolicy = new LoopRowTableRenderPolicy();
        Configure configure = Configure.builder()
                .bind("list", rowTableRenderPolicy)
                .build();


        XWPFTemplate
                .compile("空白文档.docx", configure)
                .render(renderMap).
                writeAndClose(new FileOutputStream("01.docx"));

复杂结构列表内容生成 (循环生成普通文本 + 列表)

自定义实现(代码)

package com.bu.poi.world.plugns;

import com.bu.poi.world.VsEty;
import com.bu.poi.world.domain.DtEntity;
import com.bu.poi.world.domain.ObjEty;
import com.deepoove.poi.policy.AbstractRenderPolicy;
import com.deepoove.poi.render.RenderContext;
import com.deepoove.poi.template.run.RunTemplate;
import com.deepoove.poi.xwpf.BodyContainer;
import com.deepoove.poi.xwpf.BodyContainerFactory;
import com.deepoove.poi.xwpf.XWPFParagraphWrapper;
import org.apache.poi.xwpf.usermodel.*;

import java.util.List;

/**
 * @author haizhuangbu
 * @date 03 8月 2025 06:46
 * @mark CustomTableRenderPolicy
 */
public class CustomTableRenderPolicy extends AbstractRenderPolicy<VsEty> {

    @Override
    protected void afterRender(RenderContext<VsEty> context) {
        clearPlaceholder(context, true);
    }

    @Override
    public void doRender(RenderContext<VsEty> renderContext) {

        // 编辑行
        XWPFRun run = renderContext.getRun();


        RunTemplate runTemplate = (RunTemplate) renderContext.getEleTemplate();


        // 数据
        VsEty data = renderContext.getData();

        BodyContainer bodyContainer = BodyContainerFactory.getBodyContainer(run);


        List<DtEntity> list = data.getList();
        for (DtEntity dtEntity : list) {

            XWPFRun nvRun = createRun(runTemplate, (XWPFParagraph) run.getParent());

            nvRun.setText(dtEntity.getTitle() + "\n");

            bodyContainer.insertNewParagraph(nvRun);
            nvRun.addBreak();

            XWPFRun nvRun1 = createRun(runTemplate, (XWPFParagraph) nvRun.getParent());

            nvRun1.setText(dtEntity.getIdx() + "\n");
            bodyContainer.insertNewParagraph(nvRun1);
            nvRun1.addBreak();


            List<ObjEty> objEtyList = dtEntity.getList();

            for (ObjEty objEty : objEtyList) {
//                createRun(run);
//                XWPFRun tbRun = createRun(runTemplate, (XWPFParagraph) nvRun1.getParent());
                XWPFRun tbRun = createRun(run);
                XWPFTable table = bodyContainer.insertNewTable(tbRun, 0, 0);
                createRow(table, objEty);
                table.setWidth(8000);

            }


        }


    }

    private XWPFRun createRun(RunTemplate runTemplate, XWPFParagraph parent) {
        XWPFParagraphWrapper paragraphWrapper = new XWPFParagraphWrapper(parent);
        return paragraphWrapper.insertNewRun(runTemplate.getRunPos());

    }

    public void createRow(XWPFTable table, ObjEty objEty) {

        table.setInsideHBorder(XWPFTable.XWPFBorderType.SINGLE, 10, 2, "E8E8E8");
        table.setLeftBorder(XWPFTable.XWPFBorderType.SINGLE, 10, 2, "E8E8E8");
        table.setRightBorder(XWPFTable.XWPFBorderType.SINGLE, 10, 2, "E8E8E8");
        table.setTopBorder(XWPFTable.XWPFBorderType.SINGLE, 10, 2, "E8E8E8");
        table.setBottomBorder(XWPFTable.XWPFBorderType.SINGLE, 10, 2, "E8E8E8");
        XWPFTableRow r1 = table.getRow(0);


        XWPFTableCell left = r1.getCell(0);
        left.setText("姓名");


        XWPFTableCell right = r1.createCell();
        right.setText(objEty.getName());


        XWPFTableRow r2 = table.createRow();
        XWPFTableCell r2Left = r2.getCell(0);
        r2Left.setText("码值");
        XWPFTableCell r2Right = r2.getCell(1);
        r2Right.setText(objEty.getTCode());

        XWPFTableRow r3 = table.createRow();
        XWPFTableCell r3Left = r3.getCell(0);
        r3Left.setText("中文名");
        XWPFTableCell r3Right = r3.getCell(1);
        r3Right.setText(objEty.getTName());


    }


    public XWPFRun createRun(XWPFRun run) {
        XWPFDocument document = run.getDocument();
        XWPFParagraph paragraph = document.createParagraph();
        return paragraph.createRun();
    }


}
        VsEty vsEty = new VsEty();

        ArrayList<DtEntity> dtEntities = new ArrayList<>();


        DtEntity dtEntity = new DtEntity();
        dtEntity.setIdx("我是下标\n");
        dtEntity.setTitle("我是标题\n");

        List<ObjEty> objEties = new ArrayList<>();

        ObjEty objEty = new ObjEty();
        objEty.setName("name");
        objEty.setTName("name1");
        objEty.setTCode("code1");


        ObjEty objEty2 = new ObjEty();
        objEty2.setName("name");
        objEty2.setTName("name1");
        objEty2.setTCode("code1");

        objEties.add(objEty);
        objEties.add(objEty2);


        dtEntity.setList(objEties);

        dtEntities.add(dtEntity);


        vsEty.setList(dtEntities);

        renderMap.put("report", vsEty);

        CustomTableRenderPolicy customTableRenderPolicy = new CustomTableRenderPolicy();

        // 表格循环插件
        LoopRowTableRenderPolicy rowTableRenderPolicy = new LoopRowTableRenderPolicy();
        Configure configure = Configure.builder()
                .bind("list", rowTableRenderPolicy)
                .bind("report", customTableRenderPolicy)
                .build();


        XWPFTemplate
                .compile("空白文档.docx", configure)
                .render(renderMap).
                writeAndClose(new FileOutputStream("01.docx"));

模版

输出样式

官方文档地址:https://deepoove.com/poi-tl/#loop-col-table

总结

到此这篇关于Java使用poi-tl库操作wold文档方法的文章就介绍到这了,更多相关Java poi-tl操作word文档内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 关于@RequestParam的主要用法详解

    关于@RequestParam的主要用法详解

    这篇文章主要介绍了关于@RequestParam的主要用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-03-03
  • SpringBoot+MyBatis处理JSON字段的完整指南

    SpringBoot+MyBatis处理JSON字段的完整指南

    本文主要介绍了SpringBoot+MyBatis处理JSON字段的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2026-03-03
  • Java中使用StackWalker和Stream API进行堆栈遍历

    Java中使用StackWalker和Stream API进行堆栈遍历

    StackWalking API是添加到Java中最酷的(并且对大多数开发人员来说完全不切实际,一般不会用,除非深层跟踪调优)的功能之一。在这篇简短的文章中,我们将看到它是什么以及使用它有多么容易,很快的认识它
    2018-09-09
  • java中的数组初始化赋初值方式

    java中的数组初始化赋初值方式

    这篇文章主要介绍了java中的数组初始化赋初值方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-05-05
  • Java使用反射来获取泛型信息示例

    Java使用反射来获取泛型信息示例

    这篇文章主要介绍了Java使用反射来获取泛型信息,结合实例形式分析了java基于反射操作泛型信息的相关实现技巧与注意事项,需要的朋友可以参考下
    2019-07-07
  • 学习Java之Java中的异常处理机制详解

    学习Java之Java中的异常处理机制详解

    在本文中,小编将带领大家来学习Java的异常处理机制,包括异常机制、异常类型、如何捕获异常、如何抛出异常以及如何创建自定义异常等核心内容,感兴趣的同学跟着小编一起来看看吧
    2023-08-08
  • SpringMVC源码之HandlerMapping处理器映射器解析

    SpringMVC源码之HandlerMapping处理器映射器解析

    这篇文章主要介绍了SpringMVC源码之HandlerMapping处理器映射器解析,在Spring MVC中,HandlerMapping处理器映射器用于确定请求处理器对象,请求处理器可以是任何对象,只要它们使用了@Controller注解或注解@RequestMapping,需要的朋友可以参考下
    2023-08-08
  • SpringBoot超详细讲解Thymeleaf模板引擎

    SpringBoot超详细讲解Thymeleaf模板引擎

    这篇文章主要分享了Spring Boot整合使用Thymeleaf,Thymeleaf是新一代的Java模板引擎,类似于Velocity、FreeMarker等传统引擎,关于其更多相关内容,需要的小伙伴可以参考一下
    2022-07-07
  • MyBatis中的SQL映射文件如何配置参数映射和使用方法

    MyBatis中的SQL映射文件如何配置参数映射和使用方法

    MyBatis 是一种开源的 Java 持久化框架,它可以自动将数据库中的数据映射到 Java 对象中,并且使得 Java 对象可以非常方便地存储到数据库中,本文将介绍 MyBatis 中 SQL 映射文件的参数映射配置和使用方法,需要的朋友可以参考下
    2023-07-07
  • SpringBoot中引入MyBatisPlus的常规操作

    SpringBoot中引入MyBatisPlus的常规操作

    这篇文章主要介绍了SpringBoot中引入MyBatisPlus的常规操作,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11

最新评论