Java利用Apache POI实现多模板Word文档生成的示例代码

 更新时间:2025年07月14日 08:45:53   作者:自由的疯  
当 Word 模板文档的内容是复杂表单时,处理方式会比普通文字更复杂一些,但依旧可以借助 Apache POI 库来完成,以下是详细的处理思路和示例代码,需要的朋友可以参考下

处理思路

  1. 识别表单元素:复杂表单里可能包含表格、文本框、下拉框等元素。你需要对这些元素进行识别,并且明确要替换内容的位置。
  2. 替换表格内容:对于表格,要定位到具体的单元格,然后对单元格内的内容进行替换。
  3. 处理文本框:文本框也是需要特别处理的元素,要遍历文档中的文本框并替换其中的内容。
  4. 动态赋值:和处理普通文字一样,利用占位符来进行动态赋值。

示例代码

import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBody;

import java.io.*;
import java.util.HashMap;
import java.util.Map;

public class ComplexFormDocGenerator {

    public static void main(String[] args) {
        String[] templatePaths = {"complex_template.docx"};
        String outputPath = "complex_output.docx";
        Map<String, String> values = new HashMap<>();
        values.put("${name}", "李四");
        values.put("${department}", "技术部");

        try {
            generateDocument(templatePaths, outputPath, values);
            System.out.println("文档生成成功,路径为: " + outputPath);
        } catch (IOException e) {
            System.err.println("生成文档时出现错误: " + e.getMessage());
            e.printStackTrace();
        }
    }

    public static void generateDocument(String[] templatePaths, String outputPath, Map<String, String> values) throws IOException {
        XWPFDocument finalDocument = new XWPFDocument();

        for (String templatePath : templatePaths) {
            try (FileInputStream templateStream = new FileInputStream(templatePath);
                 XWPFDocument templateDocument = new XWPFDocument(templateStream)) {

                replacePlaceholders(templateDocument, values);
                appendDocument(finalDocument, templateDocument);
            }
        }

        try (FileOutputStream outputStream = new FileOutputStream(outputPath)) {
            finalDocument.write(outputStream);
        }
    }

    private static void replacePlaceholders(XWPFDocument document, Map<String, String> values) {
        // 处理段落中的占位符
        for (XWPFParagraph paragraph : document.getParagraphs()) {
            for (XWPFRun run : paragraph.getRuns()) {
                String text = run.getText(0);
                if (text != null) {
                    for (Map.Entry<String, String> entry : values.entrySet()) {
                        text = text.replace(entry.getKey(), entry.getValue());
                    }
                    run.setText(text, 0);
                }
            }
        }

        // 处理表格中的占位符
        for (XWPFTable table : document.getTables()) {
            for (XWPFTableRow row : table.getRows()) {
                for (XWPFTableCell cell : row.getTableCells()) {
                    for (XWPFParagraph paragraph : cell.getParagraphs()) {
                        for (XWPFRun run : paragraph.getRuns()) {
                            String text = run.getText(0);
                            if (text != null) {
                                for (Map.Entry<String, String> entry : values.entrySet()) {
                                    text = text.replace(entry.getKey(), entry.getValue());
                                }
                                run.setText(text, 0);
                            }
                        }
                    }
                }
            }
        }

        // 处理文本框中的占位符(POI 对文本框处理有限,可结合其他库)
        // 这里仅简单示例,实际可能需要更复杂逻辑
        // 可以使用 docx4j 等库来更好地处理文本框
        for (IBodyElement element : document.getBodyElements()) {
            if (element instanceof XWPFSDT) {
                XWPFSDT sdt = (XWPFSDT) element;
                for (XWPFParagraph paragraph : sdt.getContent().getParagraphs()) {
                    for (XWPFRun run : paragraph.getRuns()) {
                        String text = run.getText(0);
                        if (text != null) {
                            for (Map.Entry<String, String> entry : values.entrySet()) {
                                text = text.replace(entry.getKey(), entry.getValue());
                            }
                            run.setText(text, 0);
                        }
                    }
                }
            }
        }
    }

    private static void appendDocument(XWPFDocument mainDocument, XWPFDocument appendDocument) throws IOException {
        CTBody mainBody = mainDocument.getDocument().getBody();
        CTBody appendBody = appendDocument.getDocument().getBody();

        for (Object object : appendBody.getContent()) {
            mainBody.addNewP().set(object);
        }
    }
}

代码解释

  1. ​main​方法:和处理普通文字的示例类似,定义了模板文件路径、输出文件路径以及动态赋值的内容,然后调用 ​​generateDocument​​ 方法生成文档。
  2. ​generateDocument​方法:循环读取每个模板文件,对其进行动态赋值,再将内容追加到最终文档里,最后把最终文档写入输出文件。
  3. ​replacePlaceholders​方法
  • 处理段落:和普通文字处理一样,遍历文档中的段落和运行对象,把占位符替换成实际的值。
  • 处理表格:遍历文档中的所有表格,再遍历表格的行和单元格,对单元格内的段落和运行对象进行占位符替换。
  • 处理文本框:使用 ​​XWPFSDT​​​ 来识别文本框,遍历文本框内的段落和运行对象,进行占位符替换。不过 Apache POI 对文本框的处理能力有限,实际应用中可能需要结合 ​​docx4j​​ 等其他库。
  1. ​appendDocument​方法:将一个文档的内容追加到另一个文档中。

注意事项

  • 要保证 ​​complex_template.docx​​ 文件存在于项目的根目录下,或者根据实际情况修改文件路径。
  • 运行代码前,要确保项目中已经正确引入了 Apache POI 的依赖。
  • 对于复杂的表单元素,如下拉框、复选框等,可能需要更复杂的处理逻辑,你可以结合 ​​docx4j​​ 等库来实现。

到此这篇关于Java利用Apache POI实现多模板Word文档生成的示例代码的文章就介绍到这了,更多相关Java Apache POI多模板Word生成内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • MyBatis与SpringMVC相结合实现文件上传、下载功能

    MyBatis与SpringMVC相结合实现文件上传、下载功能

    这篇文章主要介绍了MyBatis与SpringMVC相结合实现文件上传、下载功能的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2016-06-06
  • Scala递归函数调用自身

    Scala递归函数调用自身

    这篇文章主要介绍了Scala递归函数,Scala递归函数是一种函数可以调用自身的函数,直到满足某个特定的条件为止。在函数式编程的语言中,递归函数起着重要的作用,因为它可以用来表示循环或迭代的逻辑
    2023-04-04
  • Spring中单例和多例的深入理解

    Spring中单例和多例的深入理解

    这篇文章主要介绍了Spring中单例和多例的深入理解,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-08-08
  • Java形参和实参的实例之Integer类型与Int类型用法说明

    Java形参和实参的实例之Integer类型与Int类型用法说明

    这篇文章主要介绍了Java形参和实参的实例之Integer类型与Int类型用法说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-10-10
  • java实现微信抢红包算法

    java实现微信抢红包算法

    这篇文章主要为大家详细介绍了java实现微信抢红包算法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-09-09
  • java中Date日期类型的大小比较方式

    java中Date日期类型的大小比较方式

    这篇文章主要介绍了java中Date日期类型的大小比较方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-07-07
  • Java中跨域问题解决的几种方式举例详解

    Java中跨域问题解决的几种方式举例详解

    这篇文章主要介绍了前后端分离项目中跨域问题的解决方法,包括设置响应头信息、使用iframe、WebSocket、HttpServletResponse添加头信息以及通过配置类等多种方式,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2024-12-12
  • java正则表达式简单应用

    java正则表达式简单应用

    这篇文章主要介绍了java正则表达式简单应用,在之前几篇文章中已经深入学习了java正则表达式基础知识,本文对java正则表达式应用进行研究,感兴趣的小伙伴们可以参考一下
    2015-12-12
  • java jpa如何自定义sql语句

    java jpa如何自定义sql语句

    这篇文章主要介绍了java jpa如何自定义sql语句方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-11-11
  • Java修改图片大小尺寸的简单实现

    Java修改图片大小尺寸的简单实现

    这篇文章主要介绍了Java修改图片大小尺寸的简单实现方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09

最新评论