Java 通过POI填充模版word [word工具类]

该文章介绍了一个Java工具类,利用ApachePOI库来读取和编辑Word文档,实现模版文本和表格内容的替换。通过传入模版路径、输出路径和替换信息Map,可以动态生成定制化的Word文档。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Java 通过POI填充模版word [word工具类]

  • POI依赖
        <!-- poi -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.17</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.17</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml-schemas</artifactId>
            <version>3.17</version>
        </dependency>
  • 工具类代码
/**
 * @Author: RedRush
 * @Date: 2023/2/20 13:52
 * @description: Word文档工具类
 */
public class WordUtils {

    /**
     * @Author: RedRush
     * @Date:   2023/2/20 17:42
     * @param path 模版路径
     * @param outPath 输出路径
     * @param dict 需要替换的信息集合
     * @Return: boolean
     * @description: 根据dict编译模版中的文本和表格
     */
    public static void compile(String path, String outPath, Map<String, Object> dict) throws Exception{
        FileInputStream is = new FileInputStream(path);
        XWPFDocument document = new XWPFDocument(is);
        if (dict != null) {
            // 替换掉表格之外的文本(仅限文本)
            WordUtils.compileText(document, dict);
            // 替换表格内的文本对象
            WordUtils.compileTable(document, dict);
        }
        File f = new File(outPath.substring(0, outPath.lastIndexOf(File.separator)));
        if(!f.exists()){
            f.mkdirs();
        }
        FileOutputStream out = new FileOutputStream(outPath);
        document.write(out);
    }

    /***
     * @Description :替换段落文本
     * @param document docx解析对象
     * @param dict 需要替换的信息集合
     * @return void
     * @Date 2022/11/17 17:22
     */
    public static void compileText(XWPFDocument document, Map<String, Object> dict) {
        // 获取段落集合
        Iterator<XWPFParagraph> iterator = document.getParagraphsIterator();
        XWPFParagraph paragraph = null;
        while (iterator.hasNext()) {
            paragraph = iterator.next();
            // 判断此段落是否需要替换
            if (checkText(paragraph.getText())) {
                replaceValue(paragraph, dict);
            }
        }
    }

    /***
     * @Description :替换表格内的文字
     * @param document
     * @param dict 需要替换的信息集合
     * @return void
     * @Date 2022/11/18 11:29
     */
    public static void compileTable(XWPFDocument document, Map<String, Object> dict) {
        // 获取文件的表格
        Iterator<XWPFTable> tableList = document.getTablesIterator();
        XWPFTable table;
        List<XWPFTableRow> rows;
        List<XWPFTableCell> cells;
        // 循环所有需要进行替换的文本,进行替换
        while (tableList.hasNext()) {
            table = tableList.next();
            if (checkText(table.getText())) {
                rows = table.getRows();
                // 遍历表格,并替换模板
                for (XWPFTableRow row : rows) {
                    cells = row.getTableCells();
                    for (XWPFTableCell cell : cells) {
                        // 判断单元格是否需要替换
                        if (checkText(cell.getText())) {
                            List<XWPFParagraph> paragraphs = cell.getParagraphs();
                            for (XWPFParagraph paragraph : paragraphs) {
                                replaceValue(paragraph, dict);
                            }
                        }
                    }
                }
            }
        }
    }

    /**
     * @Author: RedRush
     * @Date:   2023/2/20 17:31
     * @param paragraph word文本
     * @param dict 需要替换的信息集合
     * @description: 替换字符串
     */
    private static void replaceValue(XWPFParagraph paragraph, Map<String, Object> dict) {
        String nextLine;
        List<XWPFRun> runs = paragraph.getRuns();
        for (int i = 0; i < runs.size(); i++) {
            // 读取当前行
            String readLine = runs.get(i).text();
//            System.out.println("readLine:" + readLine);
            // 如果为空 或 不包含目标字符串 则跳过
            if(StringUtils.isEmpty(readLine) || !readLine.contains("$"))    continue;
            // 初始化结果集
            StringBuffer sb = new StringBuffer();
            // 循环处理当前行的模版串
            while (readLine.contains("$")){
                // 获取模版串左侧字符串
                int left;
                if(readLine.contains("${")){
                    left = readLine.indexOf("${");
                }else {
                    if(runs.size() < i+1){
                        break;
                    }
                    nextLine = runs.get(i+1).text();
                    if(!nextLine.startsWith("{"))   break;
                    readLine += nextLine;
                    paragraph.removeRun(i+1);
                    left = readLine.indexOf("${");
                }
                sb.append(readLine.substring(0, left));
                // 获取模版串右侧
                while(runs.size() >= i+1 && !readLine.contains("}")){
                    nextLine = runs.get(i+1).text();
                    readLine += nextLine;
                    paragraph.removeRun(i+1);
                }
                int right = readLine.indexOf("}");
                if(right == -1) break;
                // 替换模版串 [如果字典中不存在 则替换为空串]
                sb.append(dict.getOrDefault(readLine.substring(left, right+1), ""));
                if(right + 1 < readLine.length()){
                    sb.append(readLine.substring(right + 1));
                }
                readLine = sb.toString();
            }
            runs.get(i).setText(sb.toString(), 0);
        }
    }


    /***
     * @Description :检查文本中是否包含指定的字符(此处为“$”)
     * @param text
     * @return boolean
     * @Date 2022/11/17 17:22
     */
    private static boolean checkText(String text) {
        return text.contains("$");
    }
}

  • 测试
    /**
     * @Author: ChenZL
     * @Date:   2023/2/20 14:07
     * @description: 模版word填充测试
     */
    @Test
    public void TestReplaceWord() throws Exception {
        Map<String, Object> strData = new HashMap<>();
        strData.put("${title}", "测试文档标题");
        strData.put("${name}", "小陈");
        strData.put("${company}", "大刘的魔法学院");
        strData.put("${leader}", "张");
        String readPath = "C:\\Users\\Lenovo\\Desktop\\DOCX_demo.docx";
        String outPath = "C:\\Users\\Lenovo\\Desktop\\ABC\\EFG\\Demo.docx";
        WordUtils.compile(readPath, outPath, strData);
    }
  • word模版
    word模版
    word表格模版
  • 模版填充效果
    文字模版填充
    表格模版填充
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值