JAVA 给PDF添加水印

作者: adm 分类: java 发布时间: 2023-10-14

接上一篇,利用ureport生成了PDF文件,现在给PDF加上水印或者在某一位置加上图片

废话不多说,直接上代码

1.定位

WatermarkPosition.java
package org.springboot.demo.util;
 
public enum WatermarkPosition {
    CENTER("center"),
    TOP("top"),
    RIGHT("right"),
    BOTTOM("bottom"),
    LEFT("left"),
    LEFT_BOTTOM("left_bottom"),
    RIGHT_BOTTOM("right_bottom");
 
    private String value;
 
    public String getValue() {
        return this.value;
    }
 
    private WatermarkPosition(String value) {
        this.value = value;
    }
}

2.定义图片宽度、高度等

PdfImageWatermark.java
package org.springboot.demo.util;
 
public class PdfImageWatermark {
    private String imagePath;
    private int imgWidth;
    private int imgHeight;
    private float opacity;
    private WatermarkPosition position;
    private float x;
    private float y;
    private boolean watermark;
    private boolean append;
 
    PdfImageWatermark(String imagePath, int imgWidth, int imgHeight, float opacity, WatermarkPosition position, float x, float y, boolean watermark, boolean append) {
        this.imagePath = imagePath;
        this.imgWidth = imgWidth;
        this.imgHeight = imgHeight;
        this.opacity = opacity;
        this.position = position;
        this.x = x;
        this.y = y;
        this.watermark = watermark;
        this.append = append;
    }
 
    public static PdfImageWatermarkBuilder builder() {
        return new PdfImageWatermarkBuilder();
    }
 
    public String getImagePath() {
        return this.imagePath;
    }
 
    public int getImgWidth() {
        return this.imgWidth;
    }
 
    public int getImgHeight() {
        return this.imgHeight;
    }
 
    public float getOpacity() {
        return this.opacity;
    }
 
    public WatermarkPosition getPosition() {
        return this.position;
    }
 
    public float getX() {
        return this.x;
    }
 
    public float getY() {
        return this.y;
    }
 
    public boolean iswatermark() {
        return this.watermark;
    }
 
    public boolean isAppend() {
        return this.append;
    }
 
    public void setImagePath(String imagePath) {
        this.imagePath = imagePath;
    }
 
    public void setImgWidth(int imgWidth) {
        this.imgWidth = imgWidth;
    }
 
    public void setImgHeight(int imgHeight) {
        this.imgHeight = imgHeight;
    }
 
    public void setOpacity(float opacity) {
        this.opacity = opacity;
    }
 
    public void setPosition(WatermarkPosition position) {
        this.position = position;
    }
 
    public void setX(float x) {
        this.x = x;
    }
 
    public void setY(float y) {
        this.y = y;
    }
 
    public void setwatermark(boolean watermark) {
        this.watermark = watermark;
    }
 
    public void setAppend(boolean append) {
        this.append = append;
    }
 
    public static class PdfImageWatermarkBuilder {
        private String imagePath;
        private int imgWidth;
        private int imgHeight;
        private float opacity;
        private WatermarkPosition position;
        private float x;
        private float y;
        private boolean watermark;
        private boolean append;
 
        PdfImageWatermarkBuilder() {
        }
 
        public PdfImageWatermarkBuilder imagePath(String imagePath) {
            this.imagePath = imagePath;
            return this;
        }
 
        public PdfImageWatermarkBuilder imgWidth(int imgWidth) {
            this.imgWidth = imgWidth;
            return this;
        }
 
        public PdfImageWatermarkBuilder imgHeight(int imgHeight) {
            this.imgHeight = imgHeight;
            return this;
        }
 
        public PdfImageWatermarkBuilder opacity(float opacity) {
            this.opacity = opacity;
            return this;
        }
 
        public PdfImageWatermarkBuilder position(WatermarkPosition position) {
            this.position = position;
            return this;
        }
 
        public PdfImageWatermarkBuilder x(float x) {
            this.x = x;
            return this;
        }
 
        public PdfImageWatermarkBuilder y(float y) {
            this.y = y;
            return this;
        }
 
        public PdfImageWatermarkBuilder watermark(boolean watermark) {
            this.watermark = watermark;
            return this;
        }
 
        public PdfImageWatermarkBuilder append(boolean append) {
            this.append = append;
            return this;
        }
 
        public PdfImageWatermark build() {
            return new PdfImageWatermark(this.imagePath, this.imgWidth, this.imgHeight, this.opacity, this.position, this.x, this.y, this.watermark, this.append);
        }
 
    }
}

PdfUtils.java

package org.springboot.demo.util;
 
 
import org.apache.log4j.Logger;
import org.apache.pdfbox.cos.COSName;
 
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.PDPageContentStream.AppendMode;
import org.apache.pdfbox.pdmodel.PDPageTree;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
 
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import org.apache.pdfbox.pdmodel.graphics.state.PDExtendedGraphicsState;
 
 
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
 
public class PdfUtils {
    private static final Logger logger = Logger.getLogger("PdfUtils.trc");
 
    private PdfUtils() {
    }
    public static void addImageWatermark(String pdfPath, String targetPath, PdfImageWatermark pdfImageWatermark,int page) throws Exception {
        addWatermark(pdfPath, targetPath, pdfImageWatermark,page);
    }
    private static void addWatermark(String pdfPath, String targetPath, PdfImageWatermark pdfImageWatermark,int page) throws Exception {
        try {
            PDDocument doc = PDDocument.load(new File(pdfPath), "h7s3k9");
            doc.setAllSecurityToBeRemoved(true);
            PDImageXObject pdImage = PDImageXObject.createFromFile(pdfImageWatermark.getImagePath(), doc);
            if (pdfImageWatermark.iswatermark()) {//每页加水印
                Iterator iterator = doc.getPages().iterator();
                while(iterator.hasNext()) {
                    PDPage pdpage = (PDPage)iterator.next();
                    add(pdpage, doc, pdfImageWatermark,pdImage);
                }
            }else{//固定某一页加水印
                PDPageTree pages = doc.getPages();
                add(pages.get(page), doc, pdfImageWatermark, pdImage);
            }
            doc.save(targetPath);
            doc.close();
        } catch (IOException e) {
            logger.error("addWatermark error={}", e);
            throw new Exception("addWatermark error", e);
        }
    }
 
    private static void add(PDPage page, PDDocument doc, PdfImageWatermark pdfImageWatermark, PDImageXObject pdImage) throws Exception {
        try {
            PDPageContentStream contentStream = new PDPageContentStream(doc, page, AppendMode.APPEND, true, true);
            PDRectangle mediaBox = page.getMediaBox();
            float pageWidth = mediaBox.getWidth();
            float pageHeight = mediaBox.getHeight();
            PDExtendedGraphicsState pdExtGfxState = new PDExtendedGraphicsState();
            pdExtGfxState.setNonStrokingAlphaConstant(pdfImageWatermark.getOpacity());
            pdExtGfxState.setAlphaSourceFlag(true);
            pdExtGfxState.getCOSObject().setItem(COSName.BM, COSName.MULTIPLY);
            contentStream.setGraphicsStateParameters(pdExtGfxState);
            float x = pdfImageWatermark.getX();
            float y = pdfImageWatermark.getY();
            int imgWidth = pdfImageWatermark.getImgWidth();
            int imgHeight = pdfImageWatermark.getImgHeight();
            if (pdfImageWatermark.getPosition() != null) {
                float offset = 30.0F;
                String value = pdfImageWatermark.getPosition().getValue();
                if (WatermarkPosition.CENTER.getValue().equalsIgnoreCase(value)) {
                    x = (pageWidth - (float)imgWidth) / 2.0F;
                    y = (pageHeight - (float)imgHeight) / 2.0F;
                }
 
                if (WatermarkPosition.TOP.getValue().equalsIgnoreCase(value)) {
                    x = (pageWidth - (float)imgWidth) / 2.0F;
                    y = pageHeight - (float)imgHeight - offset;
                }
 
                if (WatermarkPosition.RIGHT.getValue().equalsIgnoreCase(value)) {
                    x = pageWidth - (float)imgWidth - offset;
                    y = (pageHeight - (float)imgHeight) / 2.0F;
                }
 
                if (WatermarkPosition.BOTTOM.getValue().equalsIgnoreCase(value)) {
                    x = (pageWidth - (float)imgWidth) / 2.0F;
                    y = offset;
                }
 
                if (WatermarkPosition.LEFT.getValue().equalsIgnoreCase(value)) {
                    x = offset;
                    y = (pageHeight - (float)imgHeight) / 2.0F;
                }
 
                if (WatermarkPosition.RIGHT_BOTTOM.getValue().equalsIgnoreCase(value)) {
                    x = pageWidth - (float)imgWidth - offset;
                    y = offset;
                }
 
                if (WatermarkPosition.LEFT_BOTTOM.getValue().equalsIgnoreCase(value)) {
                    x = offset;
                    y = offset;
                }
            }
 
            contentStream.drawImage(pdImage, x, y, (float)imgWidth, (float)imgHeight);
            contentStream.close();
        } catch (IOException e) {
            logger.error("add error={}", e);
            logger.error("add error={}", e);
            throw new Exception("add error", e);
        }
    }
}

3.添加水印

PdfImageUtil.java
package org.springboot.demo.util;
 
import org.springboot.demo.entity.FileDO;
 
public class PdfImageUtil {
    //在PDF插入图片
 
    /**
     *
     * @param fileDO
     * @param filePath
     * @param page 可以指定某一页盖水印
     */
    public static void InsertImage(FileDO fileDO, String filePath, int page){
        String sourcePath = filePath;
        String targetPath = filePath;
        PdfImageWatermark pdfImageWatermark = PdfImageWatermark.builder().imagePath(fileDO.getImgFileName())
                .imgWidth(fileDO.getImgWidth())
                .imgHeight(fileDO.getImgHeight())
                .opacity(fileDO.getOpacity())
                .x(fileDO.getX())
                .y(fileDO.getY())
                .append(true)
                .watermark(fileDO.isWatermark())
                .build();
        try {
            PdfUtils.addImageWatermark(sourcePath,targetPath,pdfImageWatermark,page);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

4.测试类

test.java

 
import org.springboot.demo.entity.FileDO;
import org.springboot.demo.util.PdfImageUtil;
 
public class test {
    public static void main(String args[]){
        String filePath="D:/2.pdf";//PDF文件
        String imgpath="D:/1.png";//图片文件
        FileDO fileDO=new FileDO();
        fileDO.setImgFileName(imgpath);
        fileDO.setImgHeight(300);
        fileDO.setImgWidth(300);
        fileDO.setWatermark(true);
        fileDO.setX(200);
        fileDO.setY(400);
        fileDO.setOpacity(0.8f);
        int page=1;
        //setWatermark(true)会每页都改水印、如果设置为false,则需要指定某一页page添加水印
        PdfImageUtil.InsertImage(fileDO,filePath,page);
    }
}

5.运行结果:

如果觉得我的文章对您有用,请随意赞赏。您的支持将鼓励我继续创作!