poi word 添加水印

2024-08-23 11:12
文章标签 word 水印 poi

本文主要是介绍poi word 添加水印,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

poi word 添加水印

  • 依赖
  • DocxUtil
  • 调用
  • 遇到的问题
    • 部分客户给的word无法添加水印
      • 水印文案 过长会导致字变小变形 超过一定长度就会显示异常。消失等情况

依赖

        <!--poi-tl--><dependency><groupId>com.deepoove</groupId><artifactId>poi-tl</artifactId><version>1.12.1</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>5.2.2</version></dependency>

DocxUtil

import com.microsoft.schemas.office.office.CTLock;
import com.microsoft.schemas.vml.*;
import org.apache.poi.wp.usermodel.HeaderFooterType;
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.openxmlformats.schemas.wordprocessingml.x2006.main.*;import java.io.InputStream;
import java.util.stream.Stream;import static org.openxmlformats.schemas.officeDocument.x2006.sharedTypes.STTrueFalse.FALSE;
import static org.openxmlformats.schemas.officeDocument.x2006.sharedTypes.STTrueFalse.T;/*** @author wangshuai9776* @date 2024/8/8 13:37*/
public class DocxUtil {//	public final static String DEFAULT_WATERMARK = "XXX科技有限公司"; // 后续按 系统设置获取public final static String DEFAULT_FONT_COLOR = "#d8d8d8";// 字体大小public static final String FONT_SIZE = "0.5pt";// 文本旋转角度public static final String STYLE_ROTATION = "-45";/*** 水印参数*/// private static final String fontColor = "#D3D3D3"; // 字体颜色/*** 艺术字水印参数*/private static final String fontName = "Microsoft YaHei"; // word字体// private static final String fontSize = "0.5pt"; // 字体大小private static final int widthPerWord = 10; // 一个字平均长度,单位pt,用于:计算文本占用的长度(文本总个数*单字长度)// private static final String styleRotation = "-45"; // 文本旋转角度private static final String SHAPE_TYPE = "#_x0000_t136"; // 形状类型:多边形private static final String SHAPE_SPID = "_x0000_s102";/*** word文字水印(调用poi封装的createWatermark方法)* @param doc XWPFDocument对象* @param markStr 水印文字*/public static void setWordWaterMark(XWPFDocument doc, String markStr,String fontColor) {XWPFParagraph paragraph = doc.createParagraph();XWPFHeaderFooterPolicy headerFooterPolicy = doc.getHeaderFooterPolicy();if (headerFooterPolicy == null) {headerFooterPolicy = doc.createHeaderFooterPolicy();}// create default Watermark - fill color black and not rotatedheaderFooterPolicy.createWatermark(markStr);// get the default header// Note: createWatermark also sets FIRST and EVEN headers// but this code does not updating those other headersXWPFHeader header = headerFooterPolicy.getHeader(XWPFHeaderFooterPolicy.DEFAULT);paragraph = header.getParagraphArray(0);
//            // get com.microsoft.schemas.vml.CTShape where fill color and rotation is setparagraph.getCTP().newCursor();org.apache.xmlbeans.XmlObject[] xmlobjects = paragraph.getCTP().getRArray(0).getPictArray(0).selectChildren(new javax.xml.namespace.QName("urn:schemas-microsoft-com:vml", "shape"));if (xmlobjects.length > 0) {CTShape ctshape = (CTShape) xmlobjects[0];ctshape.setFillcolor(fontColor);ctshape.setStyle(ctshape.getStyle() + ";rotation:315");}}/*** 以艺术字方式加上水印(平铺)* @param docx XWPFDocument对象* @param customText 水印文字*/public static void makeFullWaterMarkByWordArt(XWPFDocument docx, String customText,String fontColor,String fontSize,String styleRotation) {customText = customText + repeatString(" ", 16); // 水印文字之间使用8个空格分隔customText = repeatString(customText, 3); // 一行水印重复水印文字次数 //重复次数不能太多,内容过长会导致字体展示不出来。String styleTop = "0pt";  // 与顶部的间距if (docx == null) {return;}// 遍历文档,添加水印for (int lineIndex = -10; lineIndex < 20; lineIndex++) {styleTop = 200 * lineIndex + "pt";waterMarkDocXDocument(docx, customText, styleTop, 1,fontColor, fontSize ,styleRotation);}}/*** 以艺术字方式加上水印(单个)* @param docx XWPFDocument对象* @param customText 水印文字*/public static void makeWaterMarkByWordArt(XWPFDocument docx, String customText,String fontColor,String fontSize,String rotation) {String styleTop = "0pt";  // 与顶部的间距if (docx == null) {return;}// 添加水印waterMarkDocXDocument(docx, customText, styleTop, 2,fontColor,fontSize,rotation);}/*** 将指定的字符串重复repeats次.* @param pattern 字符串* @param repeats 重复次数* @return 生成的字符串*/private static String repeatString(String pattern, int repeats) {StringBuilder buffer = new StringBuilder(pattern.length() * repeats);Stream.generate(() -> pattern).limit(repeats).forEach(buffer::append);return new String(buffer);}/*** 为文档添加水印* 实现参考了{@link XWPFHeaderFooterPolicy#(String, int)}* @param doc 需要被处理的docx文档对象* @param customText 水印文本* @param type 类型:1.平铺;2.单个*/private static void waterMarkDocXDocument(XWPFDocument doc, String customText, String styleTop, int type,String fontColor,String fontSize,String rotation) {XWPFHeader header = doc.createHeader(HeaderFooterType.DEFAULT); // 如果之前已经创建过 DEFAULT 的Header,将会复用之int size = header.getParagraphs().size();if (size == 0) {header.createParagraph();}CTP ctp = header.getParagraphArray(0).getCTP();byte[] rsidr = doc.getDocument().getBody().getPArray(0).getRsidR();byte[] rsidrdefault = doc.getDocument().getBody().getPArray(0).getRsidRDefault();ctp.setRsidP(rsidr);ctp.setRsidRDefault(rsidrdefault);CTPPr ppr = ctp.addNewPPr();ppr.addNewPStyle().setVal("Header");for (int i = 0; i < 3; i++) {// 开始加水印CTR ctr = ctp.addNewR();CTRPr ctrpr = ctr.addNewRPr();ctrpr.addNewNoProof();CTGroup group = CTGroup.Factory.newInstance();CTShape shape = group.addNewShape();shape.setSpid(SHAPE_SPID);shape.setType(SHAPE_TYPE);if(type != 2){shape.setStyle(getShapeStyle(customText, styleTop,rotation)); // 设置形状样式(旋转,位置,相对路径等参数)}else{shape.setStyle(getShapeStyle()); // 设置形状样式(旋转,位置,相对路径等参数)}shape.setFillcolor(fontColor);shape.setStroked(FALSE); // 字体设置为实心CTLock lock = shape.addNewLock();lock.setExt(STExt.VIEW);CTTextPath shapeTextPath = shape.addNewTextpath(); // 绘制文本的路径shapeTextPath.setOn(T);shapeTextPath.setFitshape(T);shapeTextPath.setStyle("font-family:" + fontName + ";font-size:" + fontSize); // 设置文本字体与大小shapeTextPath.setString(customText+i);CTPicture pict = ctr.addNewPict();pict.set(group);}}/*** 加载docx格式的word文档* @param inputStream* @return*/private static XWPFDocument loadDocXDocument(InputStream inputStream) {XWPFDocument doc;try {doc = new XWPFDocument(inputStream);} catch (Exception e) {throw new RuntimeException("文档加载失败!!");}return doc;}/*** 构建Shape的样式参数* @param customText 水印文本* @return*/private static String getShapeStyle(String customText, String styleTop,String styleRotation) {StringBuilder sb = new StringBuilder();sb.append("position: ").append("absolute"); // 文本path绘制的定位方式sb.append(";width: ").append(customText.length() * widthPerWord).append("pt"); // 计算文本占用的长度(文本总个数*单字长度)sb.append(";height: ").append("20pt"); // 字体高度sb.append(";z-index: ").append("-251654144");sb.append(";mso-wrap-edited: ").append("f");sb.append(";margin-top: ").append(styleTop);sb.append(";mso-position-horizontal-relative: ").append("margin");sb.append(";mso-position-horizontal: ").append("center");sb.append(";mso-position-vertical-relative: ").append("margin");sb.append(";mso-position-vertical: ").append("left");sb.append(";rotation: ").append(styleRotation);return sb.toString();}/*** 构建Shape的样式参数* @return*/private static String getShapeStyle() {StringBuilder sb = new StringBuilder();sb.append("position: ").append("absolute"); // 文本path绘制的定位方式sb.append(";left: ").append("opt");sb.append(";width: ").append("500pt"); // 计算文本占用的长度(文本总个数*单字长度)sb.append(";height: ").append("150pt"); // 字体高度sb.append(";z-index: ").append("-251654144");sb.append(";mso-wrap-edited: ").append("f");sb.append(";margin-left: ").append("-50pt");sb.append(";margin-top: ").append("270pt");sb.append(";mso-position-horizontal-relative: ").append("margin");sb.append(";mso-position-vertical-relative: ").append("margin");sb.append(";mso-width-relative: ").append("page");sb.append(";mso-height-relative: ").append("page");sb.append(";rotation: ").append("-2949120f");return sb.toString();}}

调用

DocxUtil.makeFullWaterMarkByWordArt(doc, watermark, DocxUtil.DEFAULT_FONT_COLOR, DocxUtil.FONT_SIZE, DocxUtil.STYLE_ROTATION);

遇到的问题

部分客户给的word无法添加水印

  • 在选取模式下 有水印
    在这里插入图片描述
  • 编辑模式下就看不见水印了
    在这里插入图片描述

水印文案 过长会导致字变小变形 超过一定长度就会显示异常。消失等情况

在这里插入图片描述

这篇关于poi word 添加水印的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


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

相关文章

Python实现一键PDF转Word(附完整代码及详细步骤)

《Python实现一键PDF转Word(附完整代码及详细步骤)》pdf2docx是一个基于Python的第三方库,专门用于将PDF文件转换为可编辑的Word文档,下面我们就来看看如何通过pdf2doc... 目录引言:为什么需要PDF转Word一、pdf2docx介绍1. pdf2docx 是什么2. by

如何Python使用设置word的页边距

《如何Python使用设置word的页边距》在编写或处理Word文档的过程中,页边距是一个不可忽视的排版要素,本文将介绍如何使用Python设置Word文档中各个节的页边距,需要的可以参考下... 目录操作步骤代码示例页边距单位说明应用场景与高级用China编程途小结在编写或处理Word文档的过程中,页边距是一个

Python使用python-docx实现自动化处理Word文档

《Python使用python-docx实现自动化处理Word文档》这篇文章主要为大家展示了Python如何通过代码实现段落样式复制,HTML表格转Word表格以及动态生成可定制化模板的功能,感兴趣的... 目录一、引言二、核心功能模块解析1. 段落样式与图片复制2. html表格转Word表格3. 模板生

Java如何根据word模板导出数据

《Java如何根据word模板导出数据》这篇文章主要为大家详细介绍了Java如何实现根据word模板导出数据,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... pom.XML文件导入依赖 <dependency> <groupId>cn.afterturn</groupId>

POI从入门到实战轻松完成EasyExcel使用及Excel导入导出功能

《POI从入门到实战轻松完成EasyExcel使用及Excel导入导出功能》ApachePOI是一个流行的Java库,用于处理MicrosoftOffice格式文件,提供丰富API来创建、读取和修改O... 目录前言:Apache POIEasyPoiEasyExcel一、EasyExcel1.1、核心特性

Python实现word文档内容智能提取以及合成

《Python实现word文档内容智能提取以及合成》这篇文章主要为大家详细介绍了如何使用Python实现从10个左右的docx文档中抽取内容,再调整语言风格后生成新的文档,感兴趣的小伙伴可以了解一下... 目录核心思路技术路径实现步骤阶段一:准备工作阶段二:内容提取 (python 脚本)阶段三:语言风格调

JS+HTML实现在线图片水印添加工具

《JS+HTML实现在线图片水印添加工具》在社交媒体和内容创作日益频繁的今天,如何保护原创内容、展示品牌身份成了一个不得不面对的问题,本文将实现一个完全基于HTML+CSS构建的现代化图片水印在线工具... 目录概述功能亮点使用方法技术解析延伸思考运行效果项目源码下载总结概述在社交媒体和内容创作日益频繁的

Java利用docx4j+Freemarker生成word文档

《Java利用docx4j+Freemarker生成word文档》这篇文章主要为大家详细介绍了Java如何利用docx4j+Freemarker生成word文档,文中的示例代码讲解详细,感兴趣的小伙伴... 目录技术方案maven依赖创建模板文件实现代码技术方案Java 1.8 + docx4j + Fr

vue使用docxtemplater导出word

《vue使用docxtemplater导出word》docxtemplater是一种邮件合并工具,以编程方式使用并处理条件、循环,并且可以扩展以插入任何内容,下面我们来看看如何使用docxtempl... 目录docxtemplatervue使用docxtemplater导出word安装常用语法 封装导出方

Python FastAPI+Celery+RabbitMQ实现分布式图片水印处理系统

《PythonFastAPI+Celery+RabbitMQ实现分布式图片水印处理系统》这篇文章主要为大家详细介绍了PythonFastAPI如何结合Celery以及RabbitMQ实现简单的分布式... 实现思路FastAPI 服务器Celery 任务队列RabbitMQ 作为消息代理定时任务处理完整