2007word与PDF添加水印

因itext和spire.office 商业收费,在网上找了许多样例,最后找到了POI与PDFbox来为文档添加水印

一、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>2.3.3.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>WaterRemark</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>WaterRemark</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <!--<repositories>
        <repository>
            <id>com.e-iceblue</id>
            <url>http://repo.e-iceblue.cn/repository/maven-public/</url>
        </repository>
    </repositories>-->

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!--<dependency>
            <groupId>e-iceblue</groupId>
            <artifactId>spire.doc</artifactId>
            <version>3.5.5</version>
        </dependency>-->
        <!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>4.1.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>4.1.2</version>
        </dependency>
        <!--2003版本-->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-scratchpad</artifactId>
            <version>4.1.2</version>
        </dependency>
        <!--PDF添加水印-->
        <!-- https://mvnrepository.com/artifact/org.apache.pdfbox/pdfbox -->
        <dependency>
            <groupId>org.apache.pdfbox</groupId>
            <artifactId>pdfbox</artifactId>
            <version>2.0.20</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
View Code

二、word简单生成水印

package com.example.demo.office;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.usermodel.Range;
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;

public class WordWaterMark {
    
    public static void main(String[] args) {
        String mdocPath = "D:\\installApp\\Java\\tmp\\waterMark.docx";
        String waterParh = "D:\\installApp\\Java\\tmp\\waterMark2.docx";
        String wmText = "水印实验";
        waterMark2007(mdocPath, waterParh, wmText);
        /*
         * String mdocPath1 = "D:\\installApp\\Java\\tmp\\doc1.doc"; String waterParh1 =
         * "D:\\installApp\\Java\\tmp\\waterDoc2.doc";
         */
    }
    
    public static void waterMark2007(String mdocPath,String waterParh, String wmText) {
        XWPFDocument xwpfDocument = null;
        FileOutputStream fileOutputStream = null;
        try {
            xwpfDocument = new XWPFDocument(new FileInputStream(mdocPath));
            //获取所有存在的内容,包含页眉和页脚
            XWPFHeaderFooterPolicy headerFooterPolicy = xwpfDocument.getHeaderFooterPolicy();
            if(headerFooterPolicy==null) {
                headerFooterPolicy = xwpfDocument.createHeaderFooterPolicy();
            }
            //创建水印
            headerFooterPolicy.createWatermark(wmText);
            //获取默认的页眉
            XWPFHeader header = headerFooterPolicy.getHeader(XWPFHeaderFooterPolicy.DEFAULT);
            //段落 返回包含页眉页脚的段落
            XWPFParagraph paragraphArray = header.getParagraphArray(0);
            System.out.println(paragraphArray.getCTP().getRArray(0));
            System.out.println(paragraphArray.getCTP().getRArray(0).getPictArray(0));
            org.apache.xmlbeans.XmlObject[] xmlobjects = paragraphArray.getCTP().getRArray(0).getPictArray(0).selectChildren(
                    new javax.xml.namespace.QName("urn:schemas-microsoft-com:vml", "shape"));
            if (xmlobjects.length > 0) {
                    com.microsoft.schemas.vml.CTShape ctshape = (com.microsoft.schemas.vml.CTShape)xmlobjects[0];
                    // set fill color
                    //ctshape.setFillcolor("#d8d8d8");
                    //设置水印颜色
                    ctshape.setFillcolor("#CC00FF");
                    // set rotation
                    //设置水印倾斜
                    ctshape.setStyle(ctshape.getStyle() + ";rotation:315");
            }
            fileOutputStream = new FileOutputStream(waterParh);
            xwpfDocument.write(fileOutputStream);
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally {
            try {
                if(xwpfDocument!=null) {
                    xwpfDocument.close();
                }
                if(fileOutputStream!=null) {
                    fileOutputStream.close();
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        
    }
//    https://www.jianshu.com/p/911d504193cb

}

三、PDF生成水印

package com.example.demo.pdf;

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDType0Font;
import org.apache.pdfbox.pdmodel.graphics.state.PDExtendedGraphicsState;
import org.apache.pdfbox.util.Matrix;

import java.awt.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class PDFWaterMark {

    public static void main(String[] args) {
        String sourcePath = "D:\\杂项\\tmp.pdf";
        String targetPath = "D:\\杂项\\tmpwater1.pdf";
        String fontPath = "D:\\杂项\\msyh.ttf";
        String waterStr = "    泰康    ";
        addWaterMark(sourcePath,targetPath,waterStr,fontPath);
     //第二种生成PDF水印方法,tmp文件作为Pdf 水印添加测试文件.pdf的水印来生成带水印的PDF

      String sourcePath = "/home/tmpPackage/Pdf 水印添加测试文件.pdf";
      String waterMarkPath = "/home/tmpPackage/tmp.pdf";
      addWaterMark2(sourcePath,waterMarkPath);


    }
public static void addWaterMark2(String sourcePath,String waterMarkPath) {
        //加载pdf文件
        try {
            PDDocument document = PDDocument.load(new File(sourcePath));
            HashMap<Integer, String> overlayGuide = new HashMap<Integer, String>();
            for(int i=0; i<document.getNumberOfPages(); i++){
                overlayGuide.put(i+1, waterMarkPath);
                //watermark.pdf is the document which is a one page PDF with your watermark image in it. 
                //Notice here, you can skip pages from being watermarked.
            }
            Overlay overLay = new Overlay();
            overLay.setInputPDF(document);
            overLay.setOverlayPosition(Overlay.Position.BACKGROUND);
            PDDocument finalDOc = overLay.overlay(overlayGuide);
            finalDOc.save(sourcePath);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

public static void addWaterMark(String sourcePath,String targetPath,String waterStr,String fontPath){
        try {
            //加载pdf文件
            PDDocument document = PDDocument.load(new File(sourcePath));
            //解除安全
            document.setAllSecurityToBeRemoved(true);
            //获取PDF所有页,遍历
            for(PDPage page : document.getPages()){
                //PDF内容流
                //第一个参数要修改的文件,第二个修改的页面,第三个更改是追加还是覆盖,第四个是否压缩,第五个参数是否重置是第三位追加时true
                PDPageContentStream pdPageContentStream = new PDPageContentStream(document, page, PDPageContentStream.AppendMode.APPEND, true, true);
                //引入字体文件 解决中文汉字乱码问题
                PDFont font = PDType0Font.load(document, new FileInputStream(fontPath), true);
//                PDFont font = PDType1Font.HELVETICA_OBLIQUE;
                //字体大小
                float fontHeight = 20; // arbitrary for short text
                //整页只有一个水印 start
                //页面宽度
                /*float width = page.getMediaBox().getWidth();
                //页面高度
                float height = page.getMediaBox().getHeight();
                //水印宽度
                float stringWidth = font.getStringWidth(waterStr) / 1000 * fontSize;
                //一脸懵的开平方根
                float diagonalLength = (float) Math.sqrt(width * width + height * height);
                //正切,现象就是水印是斜的~-~
                float angle = (float) Math.atan2(height, width);
                //x轴坐标
                float x = (diagonalLength - stringWidth) / 2; // "horizontal" position in rotated world
                //y轴坐标
                float y = -fontSize / 4; // 4 is a trial-and-error thing, this lowers the text a bit
                pdPageContentStream.transform(Matrix.getRotateInstance(angle, 0, 0));*/
                //整页只有一个水印 end
                //创建图形拓展字典类
                PDExtendedGraphicsState pdExtendedGraphicsState = new PDExtendedGraphicsState();
                //透明度
                pdExtendedGraphicsState.setNonStrokingAlphaConstant(0.3f);
                pdExtendedGraphicsState.setStrokingAlphaConstant(0.3f);
                pdExtendedGraphicsState.setAlphaSourceFlag(true);
                pdPageContentStream.setGraphicsStateParameters(pdExtendedGraphicsState);
                //水印颜色
                pdPageContentStream.setNonStrokingColor(Color.GREEN);
                pdPageContentStream.setStrokingColor(Color.red);
                pdPageContentStream.beginText();

                pdPageContentStream.setFont(font, fontHeight);
                //根据水印文字大小长度计算横向坐标需要渲染几次水印
                float h = waterStr.length() * fontHeight;
                for (int i = 0; i <= 10; i++) {

                    // 获取旋转实例

                    pdPageContentStream.setTextMatrix(Matrix.getRotateInstance(-150, i * 100, 0));

                    pdPageContentStream.showText(waterStr);

                    for (int j = 0; j < 20; j++) {

                        pdPageContentStream.setTextMatrix(Matrix.getRotateInstance(-150, i * 100, j * h));

                        pdPageContentStream.showText(waterStr);

                    }

                }
//                pdPageContentStream.showText(waterStr);

                pdPageContentStream.endText();
                pdPageContentStream.restoreGraphicsState();

                pdPageContentStream.close();
            }
            document.save(new File(targetPath));
            document.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

*有不足请指出,仅是学习过程中记录

posted @ 2020-08-20 11:51  书生素白衣  阅读(628)  评论(0)    收藏  举报