POI给WORD添加水印(亲测可用)

最近要做电子合同,客户提出为了安全性要将合同中都添加水印,这个之前在网上看到过,貌似使用POI很好加。去网上一搜发现,清一色的只有一篇文章,并且这段代码是用不了的;在文章下边的评论里也发现都说用不了,不能用。唉,木办法了,只能自己探索。

一、依赖

依赖当然是还就那些,demo里我用了Lombok打印日志了,依赖里我没写出来。

<!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
<dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>4.1.0</version>
</dependency>
<dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>4.1.0</version>
</dependency>
<dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml-schemas</artifactId><version>4.1.0</version>
</dependency>
<dependency><groupId>org.apache.poi</groupId><artifactId>ooxml-schemas</artifactId><version>1.1</version>
</dependency>

二、Demo

废话不多说,上demo;将下边代码直接复制到自己创建的类中,改一下文件地址就可以直接测试。注意使用了lombok的@Slf4j注解,不想用可以删掉。

import lombok.extern.slf4j.Slf4j;
import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFHeader;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlToken;import javax.xml.namespace.QName;
import java.io.*;
import java.util.List;@Slf4j
public class XWPFDocTest {private static String filePath = "C:\\tmp\\个人合同.docx";private static String waterMark = "<w:r><w:rPr><w:noProof/></w:rPr><w:pict w14:anchorId=\"58771E30\"><v:shapetype id=\"_x0000_t136\" coordsize=\"21600,21600\" o:spt=\"136\" adj=\"10800\" path=\"m@7,l@8,m@5,21600l@6,21600e\"><v:formulas><v:f eqn=\"sum #0 0 10800\"/><v:f eqn=\"prod #0 2 1\"/><v:f eqn=\"sum 21600 0 @1\"/><v:f eqn=\"sum 0 0 @2\"/><v:f eqn=\"sum 21600 0 @3\"/><v:f eqn=\"if @0 @3 0\"/><v:f eqn=\"if @0 21600 @1\"/><v:f eqn=\"if @0 0 @2\"/><v:f eqn=\"if @0 @4 21600\"/><v:f eqn=\"mid @5 @6\"/><v:f eqn=\"mid @8 @5\"/><v:f eqn=\"mid @7 @8\"/><v:f eqn=\"mid @6 @7\"/><v:f eqn=\"sum @6 0 @5\"/></v:formulas><v:path textpathok=\"t\" o:connecttype=\"custom\" o:connectlocs=\"@9,0;@10,10800;@11,21600;@12,10800\" o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\"/><v:handles><v:h position=\"#0,bottomRight\" xrange=\"6629,14971\"/></v:handles><o:lock v:ext=\"edit\" text=\"t\" shapetype=\"t\"/></v:shapetype><v:shape id=\"PowerPlusWaterMarkObject1584793859\" o:spid=\"_x0000_s2049\" type=\"#_x0000_t136\" style=\"position:absolute;left:0;text-align:left;margin-left:0;margin-top:0;width:470.5pt;height:115pt;rotation:315;z-index:-251657216;mso-position-horizontal:center;mso-position-horizontal-relative:margin;mso-position-vertical:center;mso-position-vertical-relative:margin\" o:allowincell=\"f\" fillcolor=\"silver\" stroked=\"f\"><v:fill opacity=\".5\"/><v:textpath style=\"font-family:&quot;宋体&quot;;font-size:1pt\" string=\"水印\"/></v:shape></w:pict></w:r></xml-fragment>";public static void main(String[] args) throws Exception{String waterMarkValue = "传入水印";addWaterMark(filePath,waterMarkValue);}/*** 添加水印* 根据传入的word文档地址给word添加水印,添加完成后在相同路径下生成后缀为_after.docx的文件* 保留了源文件。如源文件为C:\tmp\个人合同.docx;添加水印后有水印的文件为C:\tmp\个人合同_after.docx;* @param filePath 要添加的水印word* @param waterMarkValue 水印字符串* @throws IOException* @throws XmlException*/public static void addWaterMark(String filePath,String waterMarkValue) throws IOException,XmlException {InputStream in = new FileInputStream(new File(filePath));XWPFDocument document = new XWPFDocument(in);XWPFHeaderFooterPolicy xFooter = new XWPFHeaderFooterPolicy(document);XWPFHeader header = xFooter.getHeader(XWPFHeaderFooterPolicy.DEFAULT);List<XWPFParagraph> paragraphs = header.getParagraphs();for(XWPFParagraph graph: paragraphs){String paraText = graph.getCTP().xmlText();//如果已经有水印了,那么就进行替换if(paraText.contains("id=\"PowerPlusWaterMarkObject")){replaceWaterMark(graph,waterMarkValue);}else {//如果没有水印就添加String newParaText = waterMark.replace("水印",waterMarkValue);String newText = paraText.replace("</xml-fragment>", newParaText);XmlToken token = XmlToken.Factory.parse(newText);graph.getCTP().set(token);}}String afterPath = filePath.substring(0, filePath.lastIndexOf(".")) + "_after.docx";OutputStream out = new FileOutputStream(new File(afterPath));document.write(out);out.flush();if (in != null) {try {in.close();} catch (IOException e) {e.printStackTrace();}}if (out != null) {try {out.close();} catch (IOException e) {e.printStackTrace();}}}/*** 将水印中的文字替换成传进来的字符串* @param graph 要替换的段落* @param waterMarkValue 水印文字* @throws IOException* @throws XmlException*/public static void replaceWaterMark(XWPFParagraph graph,String waterMarkValue) throws IOException,XmlException{String paraText = graph.getCTP().xmlText();if(paraText.contains("id=\"PowerPlusWaterMarkObject")){//<v:shape id=\"PowerPlusWaterMarkObjectString beginStr = "string=\"";int begin = paraText.indexOf(beginStr) + beginStr.length();int end = paraText.indexOf("\"", begin);String oldWaterMarkText = paraText.substring(begin, end);String newText = paraText.replace("string=\""+ oldWaterMarkText +"\"","string=\"" + waterMarkValue + "\"");XmlToken token = XmlToken.Factory.parse(newText);graph.getCTP().set(token);}}
}

三、总结

虽然实现了,但是还是比较简陋;水印的字体、大小、颜色等都木有设置,用的都是默认的;这是以后可以优化的地方。不过整体效果还是可以的,而且这样添加水印后生成pdf也是带有水印的。至于生成pdf的代码后边有时间再写吧,谁想要可以在评论区给我留言,我看到了就把demo发给你。

POI给WORD添加水印(亲测可用)相关推荐

  1. jquery将html转换word,HTML代码转word!亲测!可用!!!

    现在项目中遇到一个需求,就是一个富文本编辑区中,有echars表格.用户点击保存按钮,需要导出为word文档. 因为现在接手的项目,是基于上一个项目的框架.两个项目功能点差不多.但是在导出word这块 ...

  2. dom4j将word转pdf详细介绍(亲测可用)

    背景:本文介绍的是已经存在一个word文件,将其转换成pdf文件,利用dom4j将word转换成pdf.跟着我的步骤一步一步,最后一定会成功!! 1.创建项目 2.pom,导包 <depende ...

  3. HTML代码转word!亲测!可用!!!

    现在项目中遇到一个需求,就是一个富文本编辑区中,有echars表格.用户点击保存按钮,需要导出为word文档. 因为现在接手的项目,是基于上一个项目的框架.两个项目功能点差不多.但是在导出word这块 ...

  4. word,ppt等office文档转化为pdf进行展示(POI + iText)(亲测有效)

    word,ppt等office软件转化为pdf进行展示(POI +iText)(亲测有效) 1. ppt转化为pdf,利用java的POI和itext进行转化 2.wordtopdf 3.处理pptx ...

  5. PDF转word并去除水印以及处理的页数限制【pdf转word可编辑 百分百还原文件 亲测可用】

    提示:操作aspose-pdf-22.10-jdk16.jar 对其重编译修改校验权限 使用javassist 重编译(学习测试使用,aspose所有的包都可以用该教程.亲自测试过的) 文章目录 前言 ...

  6. Excel2010多开独立窗口【亲测可用】

    Excel2010多开独立窗口[亲测可用] 前言 解决方案 参考 前言 电脑上装的Excel居然没法独立开多个窗口,而Word和PPT却可以,这也太不合理了吧.baidu,google搜了一波,终于找 ...

  7. 每日起床前做这五个动作,可保障你终身不感冒——奥运福娃设计师韩美林老师亲测可用

    1.醒来后第一件事不是起身,先在床上躺着伸懒腰→四肢拉直了→让经脉拉直了(来回拉三四次) 2.然后做下图的姿势,侧卧→抱膝→弯曲→膝盖顶住胸部→吐气,把所有体内的浊气吐出 3.然后坐起来,双手在脸上的 ...

  8. java正则 括号_java正则表达式获取大括号小括号内容并判断数字和小数亲测可用...

    获取大括号小括号内容 项目开发用到了,暂做个简单记录 private static String regex = "\\{([^}]*)\\}";//匹配大括号 private s ...

  9. Android FFmpeg移植总攻略——获取视频帧数(亲测可用)

    第一次尝试使用Android 移植FFmpeg算法,一路坎坷,最终做如下总结,适用于Android手机.Android开发板.亲测可用. 一.下载组件 在Android Studio中下载所需组件:C ...

最新文章

  1. 一般网站基本建设离不开这三要素!
  2. 牵引力教育学校分析UI设计师的薪酬水平
  3. OFBiz + Opentaps 目录管理 四. 产品(二)可配置产品
  4. 基于华为云的Django网站部署
  5. 脸部细微表情识别_您可以仅使用面部表情来控制字体吗?
  6. 数据库最最常用语句(10年工作笔记)
  7. 舔狗日记网PHP源码
  8. java 11_Java 11 正式发布!8年免费使用!
  9. 在Hisi3531环境中为wm8978芯片添加音量调节功能及测试
  10. 论文邮箱不是导师的_我的漫漫读研路,就是导师对我的套路
  11. 顶尖作者介绍 | 心理学领域研究“情绪”的大牛们有哪些?
  12. Method annotated with @Bean is called directly. Use dependency injection instead
  13. HCIA-Big Data华为认证大数据工程师在线课程笔记
  14. Mac电脑chrome打不开脸书,但是saf可以,请教是因为什么
  15. unity如果编辑器意外崩溃了,但场景未保存,怎么办
  16. CodeForces #379(734A|734B|734C|734D|734E|734F)|二分查找|模拟|树的半径|位运算
  17. 阿里薪资谈判技巧_如何像专业人士一样处理技术职业中的薪资谈判
  18. excel怎么设置打印区域_excel:将多个表格的不同区域打印在一张纸上
  19. Hashtable用法
  20. 个人空间岁末大回报活动12月26日获奖名单

热门文章

  1. 真丶深入理解 JavaScript 原型和原型链(二):原型和原型链
  2. 【python】——setup.py build_ext --inplace命令解析
  3. 大数据学习路线图(2023完整版)适合收藏
  4. TexturePacker破解办法
  5. Repo:Deep Learning with Differential Privacy
  6. 高通平台关机闹钟设置
  7. excel VLOOKUP查找
  8. Synplify 综合Gtech 网表
  9. 给LINUX安装JDK
  10. 解析dump的几种方式