欢迎访问悦橙教程(wld5.com),关注java教程。悦橙教程  java问答|  每日更新
页面导航 : > > 文章正文

SpringBoot+POI实现给word添加水印功能,

来源: javaer 分享于  点击 14380 次 点评:251

SpringBoot+POI实现给word添加水印功能,


目录
  • 1、前言
  • 2、人狠话不多,上效果图
  • 3、人狠话不多,直接来代码
    • 3.1、我的代码结构
    • 3.2 、直接贴代码了
      • 3.2.1、pom 依赖
      • 3.2.2、处理工具类
  • 4、OK 完事~

    1、前言

    有个需求:整一个给 Word 加水印的demo,于是我就网上找呗~
    看到那个 Aspose 好像是收费的,然后就把目光转向了 POI,看到各种形形色色的也不知道哪个能用。整了一会,自己拷贝出一个比较精简的能用的 demo 了。

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

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

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

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

    3.1、我的代码结构

    3.2 、直接贴代码了

    3.2.1、pom 依赖

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>3.2.2</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
        <groupId>com.lyk</groupId>
        <artifactId>springboot-word-finger</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>springboot-word-finger</name>
        <description>springboot-word-finger</description>
        <properties>
            <java.version>17</java.version>
        </properties>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
    
            <dependency>
                <groupId>org.jsoup</groupId>
                <artifactId>jsoup</artifactId>
                <version>1.11.2</version>
            </dependency>
    
    
            <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi</artifactId>
                <version>4.1.0</version>
            </dependency>
            <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi-scratchpad</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>
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
    </project>
    
    

    3.2.2、处理工具类

    
    import com.microsoft.schemas.office.office.CTLock;
    import com.microsoft.schemas.vml.*;
    import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
    import org.apache.poi.openxml4j.opc.OPCPackage;
    import org.apache.poi.wp.usermodel.HeaderFooterType;
    import org.apache.poi.xwpf.usermodel.XWPFDocument;
    import org.apache.poi.xwpf.usermodel.XWPFHeader;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import java.io.*;
    import java.util.stream.Stream;
    
    /**
     * @author: lyk
     * @description: Word 添加水印工具类
     **/
    public class WatermarkUtil {
    
        private static final Logger LOGGER = LoggerFactory.getLogger(WatermarkUtil.class);
    
        /** word字体 */
        private static final String FONT_NAME = "宋体";
        /** 字体大小 */
        private static final String FONT_SIZE = "0.2pt";
        /** 字体颜色 */
        private static final String FONT_COLOR = "#d0d0d0";
    
        /** 一个字平均长度,单位pt,用于:计算文本占用的长度(文本总个数*单字长度)*/
        private static final Integer WIDTH_PER_WORD = 10;
        /** 与顶部的间距 */
        private static Integer STYLE_TOP = 0;
        /** 文本旋转角度 */
        private static final String STYLE_ROTATION = "30";
    
    
        /**
         * @param inPutPath
         * @param putPutPath
         * @param fingerText
         * @author: lyk
         * @description: 添加水印入口方法
         * @date: 2024/1/25 23:42
         **/
        public static void waterMarkDocXDocument(String inPutPath, String putPutPath, String fingerText) {
    
            long beginTime = System.currentTimeMillis();
    
            try (
                    OutputStream out = new FileOutputStream(putPutPath);
                    InputStream in = new FileInputStream(inPutPath);
                    OPCPackage srcPackage = OPCPackage.open(in);
                    XWPFDocument doc = new XWPFDocument(srcPackage)
            ) {
    
                // 把整页都打上水印
                for (int lineIndex = -5; lineIndex < 20; lineIndex++) {
                    STYLE_TOP = 100 * lineIndex;
                    waterMarkDocXDocument(doc, fingerText);
                }
    
                // 输出新文档
                doc.write(out);
    
                LOGGER.info("添加水印成功!,一共耗时" + (System.currentTimeMillis() - beginTime) + "毫秒");
    
            } catch (IOException e) {
                throw new RuntimeException(e);
            } catch (InvalidFormatException e) {
                throw new RuntimeException(e);
            }
        }
    
    
    
        /**
         * 为文档添加水印
         * @param doc        需要被处理的docx文档对象
         * @param fingerText 需要添加的水印文字
         */
        public static void waterMarkDocXDocument(XWPFDocument doc, String fingerText) {
            // 水印文字之间使用8个空格分隔
            fingerText = fingerText + repeatString(" ", 8);
            // 一行水印重复水印文字次数
            fingerText = repeatString(fingerText, 10);
            // 如果之前已经创建过 DEFAULT 的Header,将会复用
            XWPFHeader header = doc.createHeader(HeaderFooterType.DEFAULT);
            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");
            // 开始加水印
            CTR ctr = ctp.addNewR();
            CTRPr ctrpr = ctr.addNewRPr();
            ctrpr.addNewNoProof();
            CTGroup group = CTGroup.Factory.newInstance();
            CTShapetype shapeType = group.addNewShapetype();
            CTTextPath shapeTypeTextPath = shapeType.addNewTextpath();
            shapeTypeTextPath.setOn(STTrueFalse.T);
            shapeTypeTextPath.setFitshape(STTrueFalse.T);
            CTLock lock = shapeType.addNewLock();
            lock.setExt(STExt.VIEW);
            CTShape shape = group.addNewShape();
            shape.setId("PowerPlusWaterMarkObject");
            shape.setSpid("_x0000_s102");
            shape.setType("#_x0000_t136");
            // 设置形状样式(旋转,位置,相对路径等参数)
            shape.setStyle(getShapeStyle(fingerText));
            shape.setFillcolor(FONT_COLOR);
            // 字体设置为实心
            shape.setStroked(STTrueFalse.FALSE);
            // 绘制文本的路径
            CTTextPath shapeTextPath = shape.addNewTextpath();
            // 设置文本字体与大小
            shapeTextPath.setStyle("font-family:" + FONT_NAME + ";font-size:" + FONT_SIZE);
            shapeTextPath.setString(fingerText);
            CTPicture pict = ctr.addNewPict();
            pict.set(group);
        }
    
        /**
         * 构建Shape的样式参数
         *
         * @param fingerText
         * @return
         */
        private static String getShapeStyle(String fingerText) {
            StringBuilder sb = new StringBuilder();
            // 文本path绘制的定位方式
            sb.append("position: ").append("absolute");
            // 计算文本占用的长度(文本总个数*单字长度)
            sb.append(";width: ").append(fingerText.length() * WIDTH_PER_WORD).append("pt");
            // 字体高度
            sb.append(";height: ").append("20pt");
            sb.append(";z-index: ").append("-251654144");
            sb.append(";mso-wrap-edited: ").append("f");
            // 设置水印的间隔,这是一个大坑,不能用top,必须要margin-top。
            sb.append(";margin-top: ").append(STYLE_TOP);
            sb.append(";mso-position-horizontal-relative: ").append("page");
            sb.append(";mso-position-vertical-relative: ").append("page");
            sb.append(";mso-position-vertical: ").append("left");
            sb.append(";mso-position-horizontal: ").append("center");
            sb.append(";rotation: ").append(STYLE_ROTATION);
            return sb.toString();
        }
    
        /**
         * 将指定的字符串重复repeats次.
         */
        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);
        }
    }
    
    
    
    /**
     * @author lyk
     * @version 1.0
     * @date 2024/1/25 23:16
     * @description
     */
    public class Main {
    
        public static void main(String[] args) {
            final String inPath = "src/main/java/com/lyk/finger/doc/aaaa.docx";
            final String outPath = "src/main/java/com/lyk/finger/doc/out.docx";
    
            // 添加水印
            WatermarkUtil.waterMarkDocXDocument(inPath, outPath, "落魄程序员在线炒粉");
    
        }
    
    }
    

    4、OK 完事~

    到此这篇关于SpringBoot+POI实现给word添加水印功能的文章就介绍到这了,更多相关SpringBoot POI Word添加水印内容请搜索3672js教程以前的文章或继续浏览下面的相关文章希望大家以后多多支持3672js教程!

    您可能感兴趣的文章:
    • SpringBoot使用iText7实现将HTML转成PDF并添加页眉页脚水印
    • SpringBoot实现PDF添加水印的三种方法
    • SpringBoot实现PDF添加水印的示例
    • 1秒实现Springboot 图片添加水印功能
    • springboot中poi使用操作方法
    • SpringBoot中使用 POI的示例代码
    相关栏目:

    用户点评