前言
- 此文档实现的过程主要针对docx格式的word文档;
- 由于docx本身是可编辑的格式,因此处理后的文件水印也能被删除;
- 由于word文档可以改变页大小(A3,A4等纸张),那么内容的总页数就会不固定,因此我们无法按照具体内容有多少页,针对性地为每一页添加水印,只能通过为页眉或者页脚添加默认格式来保证页数变更的情况下,水印依旧随着页数增加和减少都生效;
- 由于word文档纸张大小不确定,因此水印覆盖的范围有限,所以要支持极端情况下的纸张大小,只能手动调节参数;
- 本文记录的实现方式不依赖windows运行环境,Linux下依旧可以正常使用。
为了实现添加水印功能,费了不少精力,考虑到项目需要运行在Linux环境下,很多网上的解决方案都是依赖windows平台,最终选择了使用Apache的POI框架,官网地址:http://poi.apache.org/。
由于POI框架对doc格式的word文档已经不再支持了,并且目前能为doc格式文档提供的API非常少,其中大多都是读类型的API,本人能力有限,暂时没有效的办法,如果有大佬有较好的方案,求发邮箱 lantingshuxu@sina.com,感激不尽!!
实现效果

依赖
依赖库主要是POI相关的库,核心依赖如下:
1 | <!-- !! POI依赖包 --> |
附加的IO库(Commons-IO)依赖如下:
1 | <dependency> |
实现思路
水印效果的实现思路:为word文档添加艺术文字路径效果(与绘制五角星、矩形、圆形这类型的形状类似),通过编辑页眉,选中水印文字的效果如下:

水印斜纹与水印行间距实现思路: 先水平从上到下先按照特定规则生成水平的水印,其中每一行水印是按照水印文字[空格][空格][空格]水印文字[空格][空格]...
这样的规则生成的重复字符串,每个字符的高度和宽度固定,具体需要绘制多长,只需要控制字符串重复的次数即可【本文是空格8个,总共一行重复10次】,最后再将水印旋转45度,示意图如下:

核心实现代码来源于POI某段源代码(但是该源代码的水印实现不是很好使,修改后完整的代码见后文),该代码代码位于org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy
类的getWatermarkParagraph(String text, int idx)
的实现,如下:
1 | /** |
源代码
说明:
- 水印字体是否显示正常取决于宿主机,如果该机器没安装指定字体会导致水印字体效果可能不同;
- 字体大小与word软件一致,使用 pt 作为单位;
- 使用方式,只需要通过构造函数传递水印文字,最后调用makeSlopeWaterMark方法,传入目标docx的输入流和指定的输出流即可。
实现源代码如下:
1 | import com.microsoft.schemas.office.office.CTLock; |