1秒钟实现Springboot 替换/写入 word文档里面的文字、图片功能

 更新时间:2022年12月13日 12:04:31   作者:小目标青年  
这篇文章主要介绍了Springboot 替换/写入 word文档里面的文字、图片,1秒钟实现,本文结合示例代码给大家介绍的非常详细,需要的朋友可以参考下

前言

 图片加水印:
Springboot 图片需要添加水印,怎么办? 1秒就实现

那么word文档替换文字、插入图片,当然也是1秒钟了(jar包引入,工具类代码复制粘贴,调试,完事)。

事不宜迟,开始敲代码。

正文

本篇内容:

1.word文档 替换内容里面的文字 (模板占位符方式传参替换)

2.word文档 插入图片 (指定位置传参插入)

① pom.xml 引入依赖:     

<dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.15</version>
        </dependency>

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-scratchpad</artifactId>
            <version>3.15</version>
        </dependency>

② 工具类  MyDocxUtil.java

import org.apache.poi.POIXMLDocument;
import org.apache.poi.xwpf.usermodel.*;
import java.io.FileOutputStream;
import java.util.*;
import java.util.Map.Entry;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
 
public class MyDocxUtil {
    /**
     * 文字替换
     * @param srcPath
     * @param destPath
     * @param map
     */
    public static void searchAndReplace(String srcPath, String destPath, Map<String, String> map) {
        try {
            //doc文件使用HWPFDocument读取,docx文件使用XWPFDocument读取。
            XWPFDocument document = new XWPFDocument(POIXMLDocument.openPackage(srcPath));
            /**
             * 替换段落中的指定文字
             */
            Iterator<XWPFParagraph> itPara = document.getParagraphsIterator();
            while (itPara.hasNext()) {
                XWPFParagraph paragraph = (XWPFParagraph) itPara.next();
                Set<String> set = map.keySet();
                Iterator<String> iterator = set.iterator();
                while (iterator.hasNext()) {
                    String key = iterator.next();
                    List<XWPFRun> run=paragraph.getRuns();
                    for(int i=0;i<run.size();i++)
                    {
                        if(run.get(i).getText(run.get(i).getTextPosition())!=null &&
                                run.get(i).getText(run.get(i).getTextPosition()).equals(key))
                        {
                            /**
                             * 参数0表示生成的文字是要从哪一个地方开始放置,设置文字从位置0开始
                             * 就可以把原来的文字全部替换掉了
                             */
                            run.get(i).setText(map.get(key),0);
                        }
                    }
                }
            }
 
            /**
             * 替换表格中的指定文字
             */
            Iterator<XWPFTable> itTable = document.getTablesIterator();
            while (itTable.hasNext()) {
                XWPFTable table = (XWPFTable) itTable.next();
                int count = table.getNumberOfRows();
                for (int i = 0; i < count; i++) {
                    XWPFTableRow row = table.getRow(i);
                    List<XWPFTableCell> cells = row.getTableCells();
                    for (XWPFTableCell cell : cells) {
                        for (Entry<String, String> e : map.entrySet()) {
                            if (cell.getText().equals(e.getKey())) {
                                cell.removeParagraph(0);
                                cell.setText(e.getValue());
                            }
                        }
                    }
                }
            }
            FileOutputStream outStream = null;
            outStream = new FileOutputStream(destPath);
            document.write(outStream);
            outStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
 
    }
 
    public static void main(String[] args) {
        Map<String, String> map = new HashMap<>();
        map.put("<v1>", "认可");
        map.put("<phone>", "136919xxxxx");
        map.put("<地址>", "中国广东省深圳市");
        String srcPath = "D:\\test.docx";
        String destPath = "D:\\mytestNew.docx";
        searchAndReplace(srcPath, destPath, map);
        System.out.println("操作完毕");
    }
}

③ 调试

准备一个简单的word内容文档, 假装这就是我们业务需求使用的模板内容:

可以看到 我这个模板内容里面,有三个类似站位符的内容(红色标识)


 

 然后对照看下怎么用这个工具类,传参来替换这个模板内容的文字:

    public static void main(String[] args) {
        Map<String, String> map = new HashMap<>();
        map.put("<v1>", "认可");
        map.put("<phone>", "136919xxxxx");
        map.put("<地址>", "中国广东省深圳市");
        String srcPath = "D:\\test.docx";
        String destPath = "D:\\mytestNew.docx";
        searchAndReplace(srcPath, destPath, map);
        System.out.println("操作完毕");
    }

 代码简析:  

运行方法,看看效果:

 效果:

好了文字替换玩了一下,接下来玩下插入图片:

先准备一张 ‘公章’图片:

然后在模板文档里面, 需要盖章的地方 ,设置一个占位标识 :

然后加下插入图片的函数代码:

    /**
     * <b> Word中添加图章
     * </b><br><br><i>Description</i> :
     * String srcPath, 源Word路径
     * String storePath, 添加图章后的路径
     * String sealPath, 图章路径(即图片)
     * tString abText, 在Word中盖图章的标识字符串,如:(签字/盖章)
     * int width, 图章宽度
     * int height, 图章高度
     * int leftOffset, 图章在编辑段落向左偏移量
     * int topOffset, 图章在编辑段落向上偏移量
     * boolean behind,图章是否在文字下面
     *
     * @return void
     * <br><br>Date: 2019/12/26 15:12     <br>Author : dxl
     */
    public static void sealInWord(String srcPath, String storePath, String sealPath, String tabText,
                                  int width, int height, int leftOffset, int topOffset, boolean behind) throws Exception {
        File fileTem = new File(srcPath);
        InputStream is = new FileInputStream(fileTem);
        XWPFDocument document = new XWPFDocument(is);
        List<XWPFParagraph> paragraphs = document.getParagraphs();
        XWPFRun targetRun = null;
        for (XWPFParagraph paragraph : paragraphs) {
            if (!"".equals(paragraph.getText()) && paragraph.getText().contains(tabText)) {
                List<XWPFRun> runs = paragraph.getRuns();
                targetRun = runs.get(runs.size() - 1);
            }
        }
        if (targetRun != null) {
            InputStream in = new FileInputStream(sealPath);//设置图片路径
            if (width <= 0) {
                width = 100;
            }
            if (height <= 0) {
                height = 100;
            }
            //创建Random类对象
            Random random = new Random();
            //产生随机数
            int number = random.nextInt(999) + 1;
            targetRun.addPicture(in, Document.PICTURE_TYPE_PNG, "Seal" + number, Units.toEMU(width), Units.toEMU(height));
            in.close();
            // 2. 获取到图片数据
            CTDrawing drawing = targetRun.getCTR().getDrawingArray(0);
            CTGraphicalObject graphicalobject = drawing.getInlineArray(0).getGraphic();
 
            //拿到新插入的图片替换添加CTAnchor 设置浮动属性 删除inline属性
            CTAnchor anchor = getAnchorWithGraphic(graphicalobject, "Seal" + number,
                    Units.toEMU(width), Units.toEMU(height),//图片大小
                    Units.toEMU(leftOffset), Units.toEMU(topOffset), behind);//相对当前段落位置 需要计算段落已有内容的左偏移
            drawing.setAnchorArray(new CTAnchor[]{anchor});//添加浮动属性
            drawing.removeInline(0);//删除行内属性
        }
        document.write(new FileOutputStream(storePath));
        document.close();
    }
 
    /**
     * @param ctGraphicalObject 图片数据
     * @param deskFileName      图片描述
     * @param width             宽
     * @param height            高
     * @param leftOffset        水平偏移 left
     * @param topOffset         垂直偏移 top
     * @param behind            文字上方,文字下方
     * @return
     * @throws Exception
     */
    public static CTAnchor getAnchorWithGraphic(CTGraphicalObject ctGraphicalObject,
                                                String deskFileName, int width, int height,
                                                int leftOffset, int topOffset, boolean behind) {
        System.out.println(">>width>>" + width + "; >>height>>>>" + height);
        String anchorXML =
                "<wp:anchor xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\" "
                        + "simplePos=\"0\" relativeHeight=\"0\" behindDoc=\"" + ((behind) ? 1 : 0) + "\" locked=\"0\" layoutInCell=\"1\" allowOverlap=\"1\">"
                        + "<wp:simplePos x=\"0\" y=\"0\"/>"
                        + "<wp:positionH relativeFrom=\"column\">"
                        + "<wp:posOffset>" + leftOffset + "</wp:posOffset>"
                        + "</wp:positionH>"
                        + "<wp:positionV relativeFrom=\"paragraph\">"
                        + "<wp:posOffset>" + topOffset + "</wp:posOffset>" +
                        "</wp:positionV>"
                        + "<wp:extent cx=\"" + width + "\" cy=\"" + height + "\"/>"
                        + "<wp:effectExtent l=\"0\" t=\"0\" r=\"0\" b=\"0\"/>"
                        + "<wp:wrapNone/>"
                        + "<wp:docPr id=\"1\" name=\"Drawing 0\" descr=\"" + deskFileName + "\"/><wp:cNvGraphicFramePr/>"
                        + "</wp:anchor>";
 
        CTDrawing drawing = null;
        try {
            drawing = CTDrawing.Factory.parse(anchorXML);
        } catch (XmlException e) {
            e.printStackTrace();
        }
        CTAnchor anchor = drawing.getAnchorArray(0);
        anchor.setGraphic(ctGraphicalObject);
        return anchor;
    }

调用一下函数玩下:

    public static void main(String[] args) throws Exception {
        sealInWord("D:\\mytestNew.docx",
                "D:\\mytestWithImg.docx",
                "D:\\gz.png", "(印章)", 0, 0,
                310, 110, false);
    }

 代码简析: 

运行一下,打开新文件看看效果:

好了,该篇就到这吧。

到此这篇关于Springboot 替换/写入 word文档里面的文字、图片,1秒钟实现的文章就介绍到这了,更多相关Springboot 替换word文档文字内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • SpringBoot项目中引入本地JAR包配置的几种方法

    SpringBoot项目中引入本地JAR包配置的几种方法

    SpringBoot有时需要引入本地JAR包以便重用已有的代码库或者第三方库,本文主要介绍了SpringBoot项目中引入本地JAR包配置的几种方法,具有一定的参考价值,感兴趣的可以了解一下
    2024-08-08
  • 利用java制作简单的音乐播放器

    利用java制作简单的音乐播放器

    这篇文章主要为大家详细介绍了利用java的swing技术制作简单的音乐播放器,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-06-06
  • 快速了解JAVA中的Random()函数

    快速了解JAVA中的Random()函数

    这篇文章主要介绍了JAVA中的Random()函数的使用方法,文中代码非常详细,供大家参考和学习,感兴趣的朋友可以了解下
    2020-06-06
  • SpringSecurity HttpSecurity 类处理流程分析

    SpringSecurity HttpSecurity 类处理流程分析

    SpringSecurity在SSM项目中使用基于配置文件,通过XML标签定义认证信息,HttpSecurity在SpringBoot中通过代码配置实现与XML相同功能,详细介绍了HttpSecurity的类结构、处理过程及其与SecurityBuilder的关系,感兴趣的朋友一起看看吧
    2024-09-09
  • Java中join线程操作实例分析

    Java中join线程操作实例分析

    这篇文章主要介绍了Java中join线程操作,结合实例形式分析了java使用join方法操作线程的相关原理与实现技巧,需要的朋友可以参考下
    2019-09-09
  • 简述Java中的四种引用类型

    简述Java中的四种引用类型

    从JDK1.2版本开始,把对象的引用分为四种级别,从而使程序能更加灵活的控制对象的生命周期。这四种级别由高到低依次为:强引用、软引用、弱引用和虚引用,下面分别介绍下这四种引用。
    2021-04-04
  • 详谈jvm线程栈空间内存分配位置

    详谈jvm线程栈空间内存分配位置

    这篇文章主要介绍了jvm线程栈空间内存分配位置,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09
  • Java中使用正则检查有效日期的实现

    Java中使用正则检查有效日期的实现

    要判断一个字符串是否符合时间格式,可以使用正则表达式,本文主要介绍了Java中使用正则检查有效日期的实现,具有一定的参考价值,感兴趣的可以了解一下
    2023-10-10
  • springboot的logback配置源码解读

    springboot的logback配置源码解读

    这篇文章主要为大家介绍了springboot的logback配置,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-11-11
  • Java 反射机制实例详解

    Java 反射机制实例详解

    这篇文章主要介绍了Java 反射机制实例详解的相关资料,这里对java中反射机制进行了详细的分析,需要的朋友可以参考下
    2017-09-09

最新评论