0


Java / Spring Boot + POI 给 Word 添加水印

1、前言(瞎扯)

有个需求:整一个给 Word 加水印的demo,于是我就网上找呗~
看到那个

  1. Aspose

好像是收费的,然后就把目光转向了 POI,看到各种形形色色的也不知道哪个能用。整了一会,自己拷贝出一个比较精简的能用的 demo 了。

2、人狠话不多,上效果图

我一般都是直接上图的,先看效果图(每一页都有的):

水印的分布如果不理想,只能小伙伴们自行研究调整了~

在这里插入图片描述

3、人狠话不多,直接来代码

3.1、我的代码结构

目录结构

3.2 、直接贴代码了

  1. pom 依赖的版本不要改,修改版本可能会导致一些东西缺失

代码你们可以直接复制这里的使用
或者在码云仓库:点击这里跳转

3.2.1、pom 依赖

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  4. <modelVersion>4.0.0</modelVersion>
  5. <parent>
  6. <groupId>org.springframework.boot</groupId>
  7. <artifactId>spring-boot-starter-parent</artifactId>
  8. <version>3.2.2</version>
  9. <relativePath/> <!-- lookup parent from repository -->
  10. </parent>
  11. <groupId>com.lyk</groupId>
  12. <artifactId>springboot-word-finger</artifactId>
  13. <version>0.0.1-SNAPSHOT</version>
  14. <name>springboot-word-finger</name>
  15. <description>springboot-word-finger</description>
  16. <properties>
  17. <java.version>17</java.version>
  18. </properties>
  19. <dependencies>
  20. <dependency>
  21. <groupId>org.springframework.boot</groupId>
  22. <artifactId>spring-boot-starter</artifactId>
  23. </dependency>
  24. <dependency>
  25. <groupId>org.springframework.boot</groupId>
  26. <artifactId>spring-boot-starter-test</artifactId>
  27. <scope>test</scope>
  28. </dependency>
  29. <dependency>
  30. <groupId>org.jsoup</groupId>
  31. <artifactId>jsoup</artifactId>
  32. <version>1.11.2</version>
  33. </dependency>
  34. <dependency>
  35. <groupId>org.apache.poi</groupId>
  36. <artifactId>poi</artifactId>
  37. <version>4.1.0</version>
  38. </dependency>
  39. <dependency>
  40. <groupId>org.apache.poi</groupId>
  41. <artifactId>poi-scratchpad</artifactId>
  42. <version>4.1.0</version>
  43. </dependency>
  44. <dependency>
  45. <groupId>org.apache.poi</groupId>
  46. <artifactId>poi-ooxml</artifactId>
  47. <version>4.1.0</version>
  48. </dependency>
  49. <dependency>
  50. <groupId>org.apache.poi</groupId>
  51. <artifactId>poi-ooxml-schemas</artifactId>
  52. <version>4.1.0</version>
  53. </dependency>
  54. </dependencies>
  55. <build>
  56. <plugins>
  57. <plugin>
  58. <groupId>org.springframework.boot</groupId>
  59. <artifactId>spring-boot-maven-plugin</artifactId>
  60. </plugin>
  61. </plugins>
  62. </build>
  63. </project>

3.2.2、处理工具类

  1. importcom.microsoft.schemas.office.office.CTLock;importcom.microsoft.schemas.vml.*;importorg.apache.poi.openxml4j.exceptions.InvalidFormatException;importorg.apache.poi.openxml4j.opc.OPCPackage;importorg.apache.poi.wp.usermodel.HeaderFooterType;importorg.apache.poi.xwpf.usermodel.XWPFDocument;importorg.apache.poi.xwpf.usermodel.XWPFHeader;importorg.openxmlformats.schemas.wordprocessingml.x2006.main.*;importorg.slf4j.Logger;importorg.slf4j.LoggerFactory;importjava.io.*;importjava.util.stream.Stream;/**
  2. * @author: lyk
  3. * @description: Word 添加水印工具类
  4. **/publicclassWatermarkUtil{privatestaticfinalLoggerLOGGER=LoggerFactory.getLogger(WatermarkUtil.class);/** word字体 */privatestaticfinalStringFONT_NAME="宋体";/** 字体大小 */privatestaticfinalStringFONT_SIZE="0.2pt";/** 字体颜色 */privatestaticfinalStringFONT_COLOR="#d0d0d0";/** 一个字平均长度,单位pt,用于:计算文本占用的长度(文本总个数*单字长度)*/privatestaticfinalIntegerWIDTH_PER_WORD=10;/** 与顶部的间距 */privatestaticIntegerSTYLE_TOP=0;/** 文本旋转角度 */privatestaticfinalStringSTYLE_ROTATION="30";/**
  5. * @param inPutPath
  6. * @param putPutPath
  7. * @param fingerText
  8. * @author: lyk
  9. * @description: 添加水印入口方法
  10. * @date: 2024/1/25 23:42
  11. **/publicstaticvoidwaterMarkDocXDocument(String inPutPath,String putPutPath,String fingerText){long beginTime =System.currentTimeMillis();try(OutputStream out =newFileOutputStream(putPutPath);InputStream in =newFileInputStream(inPutPath);OPCPackage srcPackage =OPCPackage.open(in);XWPFDocument doc =newXWPFDocument(srcPackage)){// 把整页都打上水印for(int lineIndex =-5; lineIndex <20; lineIndex++){STYLE_TOP=100* lineIndex;waterMarkDocXDocument(doc, fingerText);}// 输出新文档
  12. doc.write(out);LOGGER.info("添加水印成功!,一共耗时"+(System.currentTimeMillis()- beginTime)+"毫秒");}catch(IOException e){thrownewRuntimeException(e);}catch(InvalidFormatException e){thrownewRuntimeException(e);}}/**
  13. * 为文档添加水印
  14. * @param doc 需要被处理的docx文档对象
  15. * @param fingerText 需要添加的水印文字
  16. */publicstaticvoidwaterMarkDocXDocument(XWPFDocument doc,String fingerText){// 水印文字之间使用8个空格分隔
  17. fingerText = fingerText +repeatString(" ",8);// 一行水印重复水印文字次数
  18. fingerText =repeatString(fingerText,10);// 如果之前已经创建过 DEFAULT 的Header,将会复用XWPFHeader header = doc.createHeader(HeaderFooterType.DEFAULT);int size = header.getParagraphs().size();if(size ==0){
  19. header.createParagraph();}CTP ctp = header.getParagraphArray(0).getCTP();byte[] rsidr = doc.getDocument().getBody().getPArray(0).getRsidR();byte[] rsidrDefault = doc.getDocument().getBody().getPArray(0).getRsidRDefault();
  20. ctp.setRsidP(rsidr);
  21. ctp.setRsidRDefault(rsidrDefault);CTPPr ppr = ctp.addNewPPr();
  22. ppr.addNewPStyle().setVal("Header");// 开始加水印CTR ctr = ctp.addNewR();CTRPr ctrpr = ctr.addNewRPr();
  23. ctrpr.addNewNoProof();CTGroup group =CTGroup.Factory.newInstance();CTShapetype shapeType = group.addNewShapetype();CTTextPath shapeTypeTextPath = shapeType.addNewTextpath();
  24. shapeTypeTextPath.setOn(STTrueFalse.T);
  25. shapeTypeTextPath.setFitshape(STTrueFalse.T);CTLock lock = shapeType.addNewLock();
  26. lock.setExt(STExt.VIEW);CTShape shape = group.addNewShape();
  27. shape.setId("PowerPlusWaterMarkObject");
  28. shape.setSpid("_x0000_s102");
  29. shape.setType("#_x0000_t136");// 设置形状样式(旋转,位置,相对路径等参数)
  30. shape.setStyle(getShapeStyle(fingerText));
  31. shape.setFillcolor(FONT_COLOR);// 字体设置为实心
  32. shape.setStroked(STTrueFalse.FALSE);// 绘制文本的路径CTTextPath shapeTextPath = shape.addNewTextpath();// 设置文本字体与大小
  33. shapeTextPath.setStyle("font-family:"+FONT_NAME+";font-size:"+FONT_SIZE);
  34. shapeTextPath.setString(fingerText);CTPicture pict = ctr.addNewPict();
  35. pict.set(group);}/**
  36. * 构建Shape的样式参数
  37. *
  38. * @param fingerText
  39. * @return
  40. */privatestaticStringgetShapeStyle(String fingerText){StringBuilder sb =newStringBuilder();// 文本path绘制的定位方式
  41. sb.append("position: ").append("absolute");// 计算文本占用的长度(文本总个数*单字长度)
  42. sb.append(";width: ").append(fingerText.length()*WIDTH_PER_WORD).append("pt");// 字体高度
  43. sb.append(";height: ").append("20pt");
  44. sb.append(";z-index: ").append("-251654144");
  45. sb.append(";mso-wrap-edited: ").append("f");// 设置水印的间隔,这是一个大坑,不能用top,必须要margin-top。
  46. sb.append(";margin-top: ").append(STYLE_TOP);
  47. sb.append(";mso-position-horizontal-relative: ").append("page");
  48. sb.append(";mso-position-vertical-relative: ").append("page");
  49. sb.append(";mso-position-vertical: ").append("left");
  50. sb.append(";mso-position-horizontal: ").append("center");
  51. sb.append(";rotation: ").append(STYLE_ROTATION);return sb.toString();}/**
  52. * 将指定的字符串重复repeats次.
  53. */privatestaticStringrepeatString(String pattern,int repeats){StringBuilder buffer =newStringBuilder(pattern.length()* repeats);Stream.generate(()-> pattern).limit(repeats).forEach(buffer::append);returnnewString(buffer);}}
  1. /**
  2. * @author lyk
  3. * @version 1.0
  4. * @date 2024/1/25 23:16
  5. * @description
  6. */publicclassMain{publicstaticvoidmain(String[] args){finalString inPath ="src/main/java/com/lyk/finger/doc/aaaa.docx";finalString outPath ="src/main/java/com/lyk/finger/doc/out.docx";// 添加水印WatermarkUtil.waterMarkDocXDocument(inPath, outPath,"落魄程序员在线炒粉");}}

4、OK 完事~

拿去好好享用吧~
注意:大文档不确定是否有效,我没有大文档测试,如果那种几百页的文档请自行查看,据网友反馈大文档后面的生成不了水印(200页之后的)

标签: java spring boot word

本文转载自: https://blog.csdn.net/qq_17229141/article/details/135856406
版权归原作者 落魄程序员在线炒粉 所有, 如有侵权,请联系我们删除。

“Java / Spring Boot + POI 给 Word 添加水印”的评论:

还没有评论