Java pdfbox 给 PDF 添加文字和图片水印 并旋转45度

POM

XML 复制代码
<dependency>
    <groupId>org.apache.pdfbox</groupId>
    <artifactId>pdfbox</artifactId>
    <version>2.0.27</version>
</dependency>

代码:

java 复制代码
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.image.PDImageXObject;
import org.apache.pdfbox.pdmodel.graphics.state.PDExtendedGraphicsState;
import org.apache.pdfbox.util.Matrix;

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

public class Test1 {


    public static void main(String[] args) {

        // 原始文件路径
        String sourcePath = "D:\\poi\\11.pdf";
        // 去c://windows/font下赋值去
        String fontFilePath = "D:\\poi\\simhei.ttf";
        String waterMarkText = "水印文字";
        // log图片的位置
        String logoFilePath = "D:\\poi\\logo.jpeg";
        // 输出的PDF文件路径
        String pdfFile = "D:\\poi\\11-new" + System.currentTimeMillis() + ".pdf";

        addWaterRemark(sourcePath, pdfFile, fontFilePath, waterMarkText, logoFilePath);
    }

    public static void addWaterRemark(String sourcePath, String pdfFile, String fontFilePath, String waterMarkText, String logoFilePath) {
        try {
            // 读取原始 PDF 文件
            PDDocument doc = PDDocument.load(new File(sourcePath));
            doc.setAllSecurityToBeRemoved(true);

            //必须是ttf字体
            PDFont font = PDType0Font.load(doc, new File(fontFilePath));

            PDImageXObject logoImage = PDImageXObject.createFromFile(logoFilePath, doc);
            float logoImageWidth = logoImage.getWidth();
            float logoImageHeight = logoImage.getHeight();

            float maxX;
            float maxY;
            float tempX;
            float tempY;
            float xStepLength = 300f;
            float yStepLength = 200f;
            float startX = 100f;
            float startY = 100f;
            PDPageContentStream cs;

            // 透明度
            PDExtendedGraphicsState r0 = new PDExtendedGraphicsState();
            r0.setNonStrokingAlphaConstant(0.2f);
            r0.setAlphaSourceFlag(true);
            for (PDPage page : doc.getPages()) {
                maxX = page.getBBox().getUpperRightX();
                maxY = page.getBBox().getUpperRightX();

                cs = new PDPageContentStream(doc, page, PDPageContentStream.AppendMode.APPEND, true, true);
                cs.setGraphicsStateParameters(r0);
                cs.setNonStrokingColor(new Color(200, 200, 200));
                cs.setFont(font, 36f);

                // 添加图片,不能在beginText和endText之间加
                cs.drawImage(logoImage, (maxX - logoImageWidth) / 2, maxY / 2, logoImageWidth * 1.5f, logoImageHeight * 1.5f);

                cs.beginText();
                tempX = startX;
                while (tempX < maxX) {
                    tempY = startY;
                    while (tempY < maxY) {
                        cs.setTextMatrix(Matrix.getRotateInstance(45, tempX, tempY));
                        cs.showText(waterMarkText);
                        tempY += yStepLength;
                    }
                    tempX += xStepLength;
                }
                cs.endText();

                // 关闭流
                cs.close();
            }

            // 保存修改后的 PDF 文件
            doc.save(new File(pdfFile));
            doc.close();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
相关推荐
阿方.9185 分钟前
《数据结构全解析:栈(数组实现)》
java·开发语言·数据结构
YC运维9 分钟前
Ansible题目全解析与答案
java·算法·ansible
程序员清风18 分钟前
贝壳一面:年轻代回收频率太高,如何定位?
java·后端·面试
考虑考虑30 分钟前
Java实现字节转bcd编码
java·后端·java ee
软件开发-NETKF88881 小时前
JSP到Tomcat特详细教程
java·开发语言·tomcat·jsp·项目运行
渣哥1 小时前
为什么 JDK 1.8 要给 HashMap 加红黑树?
java
我登哥MVP1 小时前
Java 网络编程学习笔记
java·网络·学习
大厂码农老A1 小时前
面试官:“聊聊你最复杂的项目?” 为什么90%的候选人第一句就栽了?
java·面试
爱读源码的大都督1 小时前
Java已死?别慌,看我如何用Java手写一个Qwen Code Agent,拯救Java
java·人工智能·后端
lssjzmn1 小时前
性能飙升!Spring异步流式响应终极指南:ResponseBodyEmitter实战与架构思考
java·前端·架构