Java PDF加水印

自适应文字长度水印

1.效果图

2.代码

2.1.pom

        <!-- PDF文件依赖包 -->
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itextpdf</artifactId>
            <version>5.5.13.1</version>
        </dependency>
        <!-- PDF文件字体 防止中文乱码 -->
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itext-asian</artifactId>
            <version>5.2.0</version>
        </dependency>

2.2.水印工具类(自动调节文字个数)

import cn.hutool.core.date.DateUtil;
import com.itextpdf.text.Element;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.*;

import javax.swing.*;
import java.awt.*;
import java.io.*;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;

import static com.shinkeer.common.utils.SecurityUtils.getUsername;

/**
 * @program: 工具箱
 * @description 水印
 */
public class PdfWatermarkUtil {
    public static void main(String[] args) {
        PdfWatermarkLocal("C:\\Users\\Pictures\\pdf水印测试.pdf", "C:\\Users\\Pictures\\pdf(加).pdf",
                "一二三四五六七八九十十九八七六五四三二一");
    }

    public static void main2(String[] args) throws Exception {
        File file = new File("C:\\Users\\Pictures\\pdf水印测试.pdf");
        InputStream inputStream = file.toURL().openStream();
        InputStream stream = PdfWatermarkTool.addPdfWatermark(inputStream, "这是水印" + DateUtil.now(), 10, 30, 50);
        writeToLocal("C:\\Users\\Pictures\\AAA" + System.currentTimeMillis() + ".pdf", stream);

    }

    /**
     * 将InputStream写入本地文件
     *
     * @param destination 写入本地目录
     * @param input       输入流
     * @throws IOException
     */
    private static void writeToLocal(String destination, InputStream input) throws IOException {
        int index;
        byte[] bytes = new byte[1024];
        FileOutputStream downloadFile = new FileOutputStream(destination);
        while ((index = input.read(bytes)) != -1) {
            downloadFile.write(bytes, 0, index);
            downloadFile.flush();
        }
        downloadFile.close();
        input.close();
    }

    /**
     * 给PDF添加水印
     * 修改为自适应文字长度水印
     *
     * @param inputFile     原文件路径+名称
     * @param outputFile    添加水印后输出文件保存的路径+名称
     * @param waterMarkName 添加水印的内容
     */
    public static void PdfWatermarkLocal(String inputFile, String outputFile, String waterMarkName) {
        try {
            // 切记这里的参数是文件的路径 ,路径必须是双斜杠的如F:\\test.pdf,不能是F:/test.pdf 或者F:\test.pdf
            PdfReader reader = new PdfReader(inputFile);
            PdfStamper stamper = new PdfStamper(reader, Files.newOutputStream(Paths.get(outputFile)));
            BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
            PdfGState gs = new PdfGState();
            gs.setFillOpacity(0.2f);//改透明度
            gs.setStrokeOpacity(0.4f);
            int total = reader.getNumberOfPages() + 1;
            JLabel label = new JLabel();
            label.setText(waterMarkName);
            PdfContentByte under;

            // 可添加多个水印
            Rectangle pageRect = null;
            label.setText(waterMarkName);
            for (int i = 1; i < total; i++) {
                pageRect = reader.getPageSizeWithRotation(i);
                int width1 = (int) pageRect.getWidth();
                int height1 = (int) pageRect.getHeight();
                int fontSize = (width1 + height1) / 80;
                // 间隔距离(参数可调节)
                int interval = fontSize * 2;
                // 文字占用的宽度
                int xWidth = getStrWidth(waterMarkName, fontSize);
                // x,y可以绘制的数量,多加一个补充空白
                int xCanNum = width1 / xWidth + 1;
                int yCanNum = height1 / fontSize + 1;

                // 在内容上方加水印
                under = stamper.getOverContent(i);
                // 在内容下方加水印
                //under = stamper.getUnderContent(i);
                under.saveState();
                under.setGState(gs);
                under.beginText();
                //水印字体和大小
                under.setFontAndSize(base, fontSize);
                // 水印文字成30度角倾斜
                for (int ii = 1; ii <= yCanNum; ii++) {
                    int y = fontSize * ii + interval * ii;
                    for (int jj = 0; jj < xCanNum; jj++) {
                        int x = xWidth * jj + interval * jj;
                        under.showTextAligned(Element.ALIGN_LEFT
                                , waterMarkName, x, y - (fontSize + interval) * jj, 30);
                    }
                }
                // 添加水印文字
                under.endText();
            }
            stamper.close();
            reader.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 给PDF添加水印
     *
     * @param inputStream   输入流
     * @param waterMarkName 添加水印的内容
     * @return OutputStream 输出流
     */
    public static OutputStream PdfWatermarkOut(InputStream inputStream, String waterMarkName) {
        try {
            PdfReader reader = new PdfReader(inputStream);
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            PdfStamper stamper = new PdfStamper(reader, outputStream);
            BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
            PdfGState gs = new PdfGState();
            gs.setFillOpacity(0.2f);//改透明度
            gs.setStrokeOpacity(0.4f);
            int total = reader.getNumberOfPages() + 1;
            JLabel label = new JLabel();
            label.setText(waterMarkName);
            PdfContentByte under;

            // 可添加多个水印
            Rectangle pageRect = null;
            label.setText(waterMarkName);
            for (int i = 1; i < total; i++) {
                pageRect = reader.getPageSizeWithRotation(i);
                int width1 = (int) pageRect.getWidth();
                int height1 = (int) pageRect.getHeight();
                int fontSize = (width1 + height1) / 80;
                // 间隔距离(参数可调节)
                int interval = fontSize * 2;
                // 文字占用的宽度
                int xWidth = getStrWidth(waterMarkName, fontSize);
                // x,y可以绘制的数量,多加一个补充空白
                int xCanNum = width1 / xWidth + 1;
                int yCanNum = height1 / fontSize + 1;

                // 在内容上方加水印
                under = stamper.getOverContent(i);
                // 在内容下方加水印
                //under = stamper.getUnderContent(i);
                under.saveState();
                under.setGState(gs);
                under.beginText();
                //水印字体和大小
                under.setFontAndSize(base, fontSize);
                // 水印文字成30度角倾斜
                for (int ii = 1; ii <= yCanNum; ii++) {
                    int y = fontSize * ii + interval * ii;
                    for (int jj = 0; jj < xCanNum; jj++) {
                        int x = xWidth * jj + interval * jj;
                        under.showTextAligned(Element.ALIGN_LEFT
                                , waterMarkName, x, y - (fontSize + interval) * jj, 30);
                    }
                }
                // 添加水印文字
                under.endText();
            }
            stamper.close();
            reader.close();

            return outputStream;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }


    /**
     * 给PDF添加水印
     *
     * @param inputStream   输入流
     * @param waterMarkName 添加水印的内容
     * @return OutputStream 输出流
     */
    public static InputStream PdfWatermarkInt(InputStream inputStream, String waterMarkName) {
        try {
            PdfReader reader = new PdfReader(inputStream);
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            PdfStamper stamper = new PdfStamper(reader, outputStream);
            BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
            PdfGState gs = new PdfGState();
            gs.setFillOpacity(0.2f);//改透明度
            gs.setStrokeOpacity(0.4f);
            int total = reader.getNumberOfPages() + 1;
            JLabel label = new JLabel();
            label.setText(waterMarkName);
            PdfContentByte under;

            // 可添加多个水印
            Rectangle pageRect = null;
            label.setText(waterMarkName);
            for (int i = 1; i < total; i++) {
                pageRect = reader.getPageSizeWithRotation(i);
                int width1 = (int) pageRect.getWidth();
                int height1 = (int) pageRect.getHeight();
                int fontSize = (width1 + height1) / 80;
                // 间隔距离(参数可调节)
                int interval = fontSize * 2;
                // 文字占用的宽度
                int xWidth = getStrWidth(waterMarkName, fontSize);
                // x,y可以绘制的数量,多加一个补充空白
                int xCanNum = width1 / xWidth + 1;
                int yCanNum = height1 / fontSize + 1;

                // 在内容上方加水印
                under = stamper.getOverContent(i);
                // 在内容下方加水印
                //under = stamper.getUnderContent(i);
                under.saveState();
                under.setGState(gs);
                under.beginText();
                //水印字体和大小
                under.setFontAndSize(base, fontSize);
                // 水印文字成30度角倾斜
                for (int ii = 1; ii <= yCanNum; ii++) {
                    int y = fontSize * ii + interval * ii;
                    for (int jj = 0; jj < xCanNum; jj++) {
                        int x = xWidth * jj + interval * jj;
                        under.showTextAligned(Element.ALIGN_LEFT
                                , waterMarkName, x, y - (fontSize + interval) * jj, 30);
                    }
                }
                // 添加水印文字
                under.endText();
            }
            stamper.close();
            reader.close();

            return new ByteArrayInputStream(outputStream.toByteArray());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取字符串占用的宽度
     * <br>
     *
     * @param str      字符串
     * @param fontSize 文字大小
     * @return 字符串占用的宽度
     */
    public static int getStrWidth(String str, int fontSize) {
        char[] chars = str.toCharArray();
        int fontSize2 = fontSize / 2;

        int width = 0;

        for (char c : chars) {
            int len = String.valueOf(c).getBytes().length;
            // 汉字为3,其余1
            // 可能还有一些特殊字符占用2等等,统统计为汉字
            if (len != 1) {
                width += fontSize;
            } else {
                width += fontSize2;
            }
        }
        return width == 0 ? 1 : width;
    }
}

2.3.水印工具类(写死文字大小个数)

import cn.hutool.core.date.DateUtil;
import com.itextpdf.text.Element;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.*;

import javax.swing.*;
import java.awt.*;
import java.io.*;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;

import static com.shinkeer.common.utils.SecurityUtils.getUsername;

/**
 * @program: 工具箱
 * @description 水印
 * @date 2023/6/6
 */
public class PdfWatermarkUtil {
    public static void main(String[] args) {
        PdfWatermarkLocal("D:\\AAA.pdf", "D:\\BBB.pdf", "这是水印");
    }

    public static void main2(String[] args) throws Exception {
        File file = new File("D:\\AAA.pdf");
        InputStream inputStream = file.toURL().openStream();
        InputStream stream = PdfWatermarkTool.addPdfWatermark(inputStream, "这是水印" + DateUtil.now(), 10, 30, 50);
        writeToLocal("D:\\AAA" + System.currentTimeMillis() + ".pdf", stream);

    }

    /**
     * 将InputStream写入本地文件
     *
     * @param destination 写入本地目录
     * @param input       输入流
     * @throws IOException
     */
    private static void writeToLocal(String destination, InputStream input) throws IOException {
        int index;
        byte[] bytes = new byte[1024];
        FileOutputStream downloadFile = new FileOutputStream(destination);
        while ((index = input.read(bytes)) != -1) {
            downloadFile.write(bytes, 0, index);
            downloadFile.flush();
        }
        downloadFile.close();
        input.close();
    }

    /**
     * 给PDF添加水印
     *
     * @param inputFile     原文件路径+名称
     * @param outputFile    添加水印后输出文件保存的路径+名称
     * @param waterMarkName 添加水印的内容
     */
    public static void PdfWatermarkLocal(String inputFile, String outputFile, String waterMarkName) {
        try {
            // 水印的高和宽(参数可调节)
            int textH = 75;
            int textW = 170;
            // 间隔距离(参数可调节)
            int interval = 30;

            // 切记这里的参数是文件的路径 ,路径必须是双斜杠的如F:\\test.pdf,不能是F:/test.pdf 或者F:\test.pdf
            PdfReader reader = new PdfReader(inputFile);
            PdfStamper stamper = new PdfStamper(reader, Files.newOutputStream(Paths.get(outputFile)));
            BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
            PdfGState gs = new PdfGState();
            gs.setFillOpacity(0.2f);//改透明度
            gs.setStrokeOpacity(0.4f);
            int total = reader.getNumberOfPages() + 1;
            JLabel label = new JLabel();
            label.setText(waterMarkName);
            PdfContentByte under;

            // 可添加多个水印
            Rectangle pageRect = null;
            FontMetrics metrics;
            label.setText(waterMarkName);
            metrics = label.getFontMetrics(label.getFont());
            for (int i = 1; i < total; i++) {
                pageRect = reader.getPageSizeWithRotation(i);
                // 在内容上方加水印
                under = stamper.getOverContent(i);
                // 在内容下方加水印
                //under = stamper.getUnderContent(i);
                under.saveState();
                under.setGState(gs);
                under.beginText();
                under.setFontAndSize(base, 20);
                // 水印文字成30度角倾斜
                for (int height = interval + textH; height < pageRect.getHeight();
                     height = height + textH * 3) {
                    for (int width = interval + textW; width < pageRect.getWidth() + textW;
                         width = width + textW * 2) {
                        under.showTextAligned(Element.ALIGN_LEFT
                                , waterMarkName, width - textW,
                                height - textH, 30);
                    }
                }
                // 添加水印文字
                under.endText();
            }
            stamper.close();
            reader.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 给PDF添加水印
     *
     * @param inputStream   输入流
     * @param waterMarkName 添加水印的内容
     * @return OutputStream 输出流
     */
    public static OutputStream PdfWatermarkOut(InputStream inputStream, String waterMarkName) {
        try {
            // 水印的高和宽(参数可调节)
            int textH = 75;
            int textW = 170;
            // 间隔距离(参数可调节)
            int interval = 30;

            PdfReader reader = new PdfReader(inputStream);
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            PdfStamper stamper = new PdfStamper(reader, outputStream);
            BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
            PdfGState gs = new PdfGState();
            gs.setFillOpacity(0.2f);//改透明度
            gs.setStrokeOpacity(0.4f);
            int total = reader.getNumberOfPages() + 1;
            JLabel label = new JLabel();
            label.setText(waterMarkName);
            PdfContentByte under;

            // 可添加多个水印
            Rectangle pageRect = null;
            FontMetrics metrics;
            label.setText(waterMarkName);
            metrics = label.getFontMetrics(label.getFont());
            for (int i = 1; i < total; i++) {
                pageRect = reader.getPageSizeWithRotation(i);
                // 在内容上方加水印
                under = stamper.getOverContent(i);
                // 在内容下方加水印
                //under = stamper.getUnderContent(i);
                under.saveState();
                under.setGState(gs);
                under.beginText();
                under.setFontAndSize(base, 20);
                // 水印文字成30度角倾斜
                for (int height = interval + textH; height < pageRect.getHeight();
                     height = height + textH * 3) {
                    for (int width = interval + textW; width < pageRect.getWidth() + textW;
                         width = width + textW * 2) {
                        under.showTextAligned(Element.ALIGN_LEFT
                                , waterMarkName, width - textW,
                                height - textH, 30);
                    }
                }
                // 添加水印文字
                under.endText();
            }
            stamper.close();
            reader.close();

            return outputStream;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }


    /**
     * 给PDF添加水印
     *
     * @param inputStream   输入流
     * @param waterMarkName 添加水印的内容
     * @return OutputStream 输出流
     */
    public static InputStream PdfWatermarkInt(InputStream inputStream, String waterMarkName) {
        try {
            // 水印的高和宽(参数可调节)
            int textH = 75;
            int textW = 170;
            // 间隔距离(参数可调节)
            int interval = 30;

            PdfReader reader = new PdfReader(inputStream);
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            PdfStamper stamper = new PdfStamper(reader, outputStream);
            BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
            PdfGState gs = new PdfGState();
            gs.setFillOpacity(0.2f);//改透明度
            gs.setStrokeOpacity(0.4f);
            int total = reader.getNumberOfPages() + 1;
            JLabel label = new JLabel();
            label.setText(waterMarkName);
            PdfContentByte under;

            // 可添加多个水印
            Rectangle pageRect = null;
            FontMetrics metrics;
            label.setText(waterMarkName);
            metrics = label.getFontMetrics(label.getFont());
            for (int i = 1; i < total; i++) {
                pageRect = reader.getPageSizeWithRotation(i);
                // 在内容上方加水印
                under = stamper.getOverContent(i);
                // 在内容下方加水印
                //under = stamper.getUnderContent(i);
                under.saveState();
                under.setGState(gs);
                under.beginText();
                under.setFontAndSize(base, 20);
                // 水印文字成30度角倾斜
                for (int height = interval + textH; height < pageRect.getHeight();
                     height = height + textH * 3) {
                    for (int width = interval + textW; width < pageRect.getWidth() + textW;
                         width = width + textW * 2) {
                        under.showTextAligned(Element.ALIGN_LEFT
                                , waterMarkName, width - textW,
                                height - textH, 30);
                    }
                }
                // 添加水印文字
                under.endText();
            }
            stamper.close();
            reader.close();

            return new ByteArrayInputStream(outputStream.toByteArray());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值