itextpdf实现word模板生成文件

news2024/11/20 3:24:16

前言

使用word模板生成文件,如下图,将左侧的模板生成为右侧的填充word文档。
在这里插入图片描述

操作方式

  1. 引入依赖
		 <!-- https://mvnrepository.com/artifact/com.itextpdf/itextpdf -->
		<dependency>
		    <groupId>com.itextpdf</groupId>
		    <artifactId>itextpdf</artifactId>
		    <version>5.5.13.3</version>
		</dependency>
		 <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>4.1.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>4.1.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-excelant</artifactId>
            <version>4.1.2</version>
        </dependency>
        <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-examples</artifactId>
        <version>4.1.2</version>
        </dependency>
  1. 创建模板,创建一份template2.docx文件,内容如下
    在这里插入图片描述
  2. 编写代码
package com.csair.jasypt.myjaspyt.util;

import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.*;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class DocxUtil {

    public static void parseDocTemplate(String sourcePath, String targetPath, Map<String, Object> data, Map<String, Object> picData) {
        try {
            FileInputStream is = new FileInputStream(sourcePath);
            XWPFDocument document = new XWPFDocument(is);
            if (data.size() > 0) {
                changeText(document, data);
                changeTableText(document, data);
            }
            if (picData.size() > 0) {
                changePic(document, picData);
                changeTablePic(document, picData);
            }
            FileOutputStream out = new FileOutputStream(targetPath);
            document.write(out);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void changeText(XWPFDocument document, Map<String, Object> textMap) {
        // 获取段落集合
        Iterator<XWPFParagraph> iterator = document.getParagraphsIterator();
        XWPFParagraph paragraph = null;
        while (iterator.hasNext()) {
            paragraph = iterator.next();
            // 判断此段落是否需要替换
            if (checkText(paragraph.getText())) {
                replaceValue(paragraph, textMap);
            }
        }
    }

    public static boolean checkText(String text) {
        boolean check = false;
        if (text.contains("$")) {
            check = true;
        }
        return check;
    }

    public static void changePic(XWPFDocument document, Map<String, Object> picData) throws Exception {
        // 获取段落集合
        Iterator<XWPFParagraph> iterator = document.getParagraphsIterator();
        XWPFParagraph paragraph;
        while (iterator.hasNext()) {
            paragraph = iterator.next();
            // 判断此段落是否需要替换
            String text = paragraph.getText();
            if (checkText(text)) {
                replacePicValue(paragraph, picData);
            }
        }
    }

    public static void changeTableText(XWPFDocument document, Map<String, Object> data) {
        // 获取文件的表格
        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, data);
                            }
                        }
                    }
                }
            }
        }
    }

    public static void changeTablePic(XWPFDocument document, Map<String, Object> picData) throws Exception {
        // 获取文件的表格
        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) {
                                replacePicValue(paragraph, picData);
                            }
                        }
                    }
                }
            }
        }
    }

    public static void replaceValue(XWPFParagraph paragraph, Map<String, Object> textMap) {
        XWPFRun run, nextRun;
        String runsText;
        List<XWPFRun> runs = paragraph.getRuns();
        for (int i = 0; i < runs.size(); i++) {
            run = runs.get(i);
            runsText = run.getText(0);
            if (runsText.contains("${") || (runsText.contains("$") && runs.get(i + 1).getText(0).substring(0, 1).equals("{"))) {
                while (!runsText.contains("}")) {
                    nextRun = runs.get(i + 1);
                    runsText = runsText + nextRun.getText(0);
                    //删除该节点下的数据
                    paragraph.removeRun(i + 1);
                }

                Iterator<Map.Entry<String, Object>> iterator = textMap.entrySet().iterator();
                while (iterator.hasNext()) {
                    Map.Entry<String, Object> entry = iterator.next();
                    String key = entry.getKey();
                    Object obj = entry.getValue();
                    if (runsText.contains(key) && null != obj) {
                        runsText = runsText.replace(key, obj + "");
                    }
                }
                run.setText(runsText, 0);
            }
        }
    }

    public static void replacePicValue(XWPFParagraph paragraph, Map<String, Object> picData) throws Exception {
        List<XWPFRun> runs = paragraph.getRuns();
        for (XWPFRun run : runs) {
            String str = run.toString();
            Iterator<Map.Entry<String, Object>> it = picData.entrySet().iterator();
            while (it.hasNext()) {
                Map.Entry<String, Object> entry = it.next();
                String key = entry.getKey();
                Object obj = entry.getValue();
                int idx = str.indexOf(key);
                if (idx > -1) {
                    run.setText("", 0);
                    FileInputStream is = new FileInputStream((String) obj);
                    // 图片宽度、高度
                    int width = Units.toEMU(100), height = Units.toEMU(100);
                    // 添加图片信息,段落高度需要在模板中自行调整
                    run.addPicture(is, XWPFDocument.PICTURE_TYPE_PNG, (String) obj, width, height);
                }
            }
        }
    }
}
  1. 编写测试用例,并执行测试用例
 @Test
    void testWord() throws Exception {
        Map<String, Object> data = new HashMap<>();
        Map<String, Object> picData = new HashMap<>();
        data.put("${year}", "2023");
        data.put("${month}", "06");
        data.put("${date}", "20");
        data.put("${birthday}", "2000年6月11日");
        data.put("${name}", "王小鱼");
        data.put("${sex}", "女");
        data.put("${address}", "北京市朝阳区光明街道幸福小区301号");
        data.put("${phoneno}", "1380000000");
        picData.put("${pic}", "D:\\test\\dog.jpg");
        DocxUtil.parseDocTemplate("D:\\test\\template2.docx","D:\\test\\template2_out.docx",data,picData);
        System.out.println("----------------end---------------");
    }

生成得到被填充出来的文件。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/694172.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

多串口数据采集网关有什么功能

数据采集网关是一种通信终端设备&#xff0c;也称物联网网关&#xff0c;它具备数据采集、存储、传输等功能。物通博联WG系列数据采集网关提供多种数据传输方式和接口通道&#xff0c;包括有线、无线和串口传输等&#xff08;5G、4G、WIFI、以太网&#xff09;&#xff0c;可以…

ModaHub魔搭社区:向量数据库Milvus性能调优教程(二)

目录 索引 其他 存储优化 常见问题 索引 向量索引的基本概念请参考 向量索引概述。 选择合适的索引需要在存储空间、查询性能、查询召回率等多个指标中权衡。 FLAT 索引 FLAT 是对向量的暴力搜索&#xff08;brute-force search&#xff09;&#xff0c;速度最慢&#…

Qt/C++编写监控实时显示和取流回放工具(回放支持切换进度)

一、前言 现在各个监控大厂做的设备&#xff0c;基本上都会支持通过rtsp直接取流显示&#xff0c;而且做的比较好的还支持通过rtsp回放取流&#xff0c;基本上都会约定一个字符串的规则&#xff0c;每个厂家都是不一样的规则&#xff0c;比如回放对应的rtsp地址还要带上时间范…

Spring专家课程Day02_Spring-DI

文章目录 一、依赖注入_Autowired1.配置类中Bean 方式注入1.1&#xff09;注入实例1.2&#xff09;自动注入的匹配原则 2.组件扫描实现自动注入 Autowired3.set方法注入 二、接口解耦_自动注入规则1&#xff09;利用接口解耦2&#xff09;Autowired的注入规则3&#xff09;Qual…

学高性能计算难吗?猿代码科技国内首家专注高性能计算人才培养与推荐 ...

高性能计算&#xff08;HPC&#xff09;作为一门专业领域&#xff0c;涉及到复杂的计算架构、并行计算模型和算法优化等方面的知识。因此&#xff0c;学习高性能计算可能对一些人来说是一项挑战。然而&#xff0c;随着正确的学习方法和适当的资源&#xff0c;掌握高性能计算并不…

【UCOS-III】自我学习笔记→第35讲→软件定时器实验

文章目录 前言实验步骤1.复制消息队列工程&#xff0c;并创建单次定时器和周期定时器&#xff0c;并删除task3及其相关内容2.添加task1按键处理和软件定时器超时函数3.查看串口现象 测试代码工程文件总结 前言 无&#xff0c;仅作记录&#xff0c;不具有参考价值&#xff0c;所…

【MATLAB第43期】基于MATLAB的BO-NAR贝叶斯优化动态神经网络NAR时间序列股票预测模型

【MATLAB第43期】基于MATLAB的BO-NAR贝叶斯优化动态神经网络NAR时间序列股票预测模型 一、效果展示 二、模型介绍 1.数据情况 一列数据&#xff0c;499个值 ratio 0.9;% 训练集比例 MaxEpochs 600;% 最大训练次数 % % 导入股票数据 xall importdata(数据.xlsx);2.优化参…

MySQL MMM 双主架构 主主复制 高可用

MMM&#xff08;Master-Master replication manager for MvSQL&#xff0c;MySQL主主复制管理器&#xff09; 是一套支持双主故障切换和双主日常管理的脚本程序。MMM 使用 Perl 语言开发&#xff0c;主要用来监控和管理 MySQL Master-Master &#xff08;双主&#xff09;复制&…

全志V3S嵌入式驱动开发(windows平台镜像烧入)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 对于很多第一次学习嵌入式linux和开发板的同学来说&#xff0c;如何烧入镜像文件常常成为他们要面对的第一个难题。从拿到板子开始&#xff0c;他们…

每个前端开发者都应知道的25个实用网站

微信搜索 【大迁世界】, 我会第一时间和你分享前端行业趋势&#xff0c;学习途径等等。 本文 GitHub https://github.com/qq449245884/xiaozhi 已收录&#xff0c;有一线大厂面试完整考点、资料以及我的系列文章。 快来免费体验ChatGpt plus版本的&#xff0c;我们出的钱 体验地…

Soybean Admin - 基于 Vue3 / vite3 等最新前端技术栈构建的中后台模板,免费开源、清新优雅,主题丰富

一款专业好看、完成度很高的 admin 开源项目&#xff0c;无论是用于生产还是学习&#xff0c;都非常值得尝试。 关于 Soybean Admin Soybean Admin 是一个基于 Vue3 / Vite3 / TypeScript / NaiveUI / Pinia 和 UnoCSS 的中后台模版&#xff0c;它使用了最新流行的前端技术栈…

poium测试库介绍

poium测试库前身为selenium-page-objects测试库&#xff0c;我在以前的文章中也有介绍过:这可能是最简单的Page Object库&#xff0c;项目的核心是基于Page Objects实现元素定位的封装。该项目由我个人在维护&#xff0c;目前在公司项目中已经得到的应用。 ### poium的优势 Pa…

cmd和android studio同时使用adb,解决冲突的方案

问题&#xff1a; android studio 在Terminal使用adb后&#xff0c;cmd的adb就会掉线&#xff1b;同样cmd的adb使用中&#xff0c;android studio的logcat 的设备就是Offline状态&#xff0c;得重新在Terminal adb connect&#xff0c;并且关闭掉cmd窗口&#xff0c;否则adb反…

Centos ifconfig不显示IP地址解决办法之一

虚拟机使用命令ifconfig不显示IP地址&#xff0c;情况如下 原因&#xff1a;我们的虚拟机网络服务没有设置为开机自启动 解决&#xff1a; 1&#xff0c;进入目录 /etc/sysconfig/network-scripts/ cd /etc/sysconfig/network-scripts/ 2&#xff0c;路径下有一个 ifcfg-en…

4.蜂鸣器

1.了解蜂鸣器&#xff1a; 蜂鸣器在使用3.3V无法驱动&#xff0c;需要借助到三极管的放大特性(IcβIb)将蜂鸣器驱动&#xff1b;本次原理图中&#xff0c;接R33电阻是因为当STM32单片机复位时处于浮空状态&#xff0c;防止小电流让蜂鸣器响而添加的。 2.蜂鸣器原理图&#xf…

十一、jenkins将构建时间作为Jenkins变量(BUILD_TIMESTAMP)

插件管理中安装Build Timestamp 插件后可以使用 构建时间变量&#xff0c;变量名称【BUILD_TIMESTAMP】 引用变量方法&#xff1a; linux : ${BUILD_TIMESTAMP} 或 $BUILD_TIMESTAMP 推荐使用 ${BUILD_TIMESTAMP} Windows&#xff1a; %BUILD_TIMESTAMP%

TypeScript——泛型

泛型&#xff08;Generics&#xff09;是指在定义函数、接口或类的时候&#xff0c;不预先指定具体的类型&#xff0c;而在使用的时候再指定类型的一种特性。 函数泛型 本来函数参数类型的不同时&#xff0c;要写多个&#xff0c;现在用泛型&#xff0c;只需要使用时传参即可…

android studio 一直卡在Build android:Download maven-metadata.xml

在android studio进行此操作&#xff0c;关闭gradle的联网功能

使用MM32L0130和HYS1254的电子秤方案验证

使用MM32L0130和HYS1254的电子秤方案验证 文章目录 使用MM32L0130和HYS1254的电子秤方案验证引言电路设计软件设计采集HYS1254数据软件滤波算法换算压力为ADC采样值 实验过程数据可视化优化电路使用软件滤波降低ADC的采样速率使用独立的供电电源再次调整滤波算法 验证总结参考文…

M1 macbook上安装docker 编译内核 并使用qemu启动内核。

1、在M1上安装docker这个就不用提供步骤了&#xff0c;网上自行搜索。 2、在M1上pull一个ubuntu的容器。docker pull ubuntu:18.04 docker images REPOSITORY TAG IMAGE ID CREATED SIZE ubuntu 18.04 d1a528908992 …