PDF下载添加水印和访问密码

下载接口

java 复制代码
@ApiOperation(value = "下载文件-pdf", notes = "下载文件pdf版", httpMethod = "GET", response = WebResult.class)
    @RequestMapping(value = "/downloadPdf", method = RequestMethod.GET)
    public void downloadFilePdf(@RequestParam(name = "id") String id,
                             @RequestParam(name = "fileExt", defaultValue = "", required = false) String fileExt,
                             @RequestParam(name = "fileName", defaultValue = "", required = false) String fileName,
                             @RequestParam(name = "userName", defaultValue = "", required = false) String userName,
                                @RequestParam(name = "key", defaultValue = "", required = false) String key,
                             HttpServletRequest request, HttpServletResponse response) throws Exception {
        String fileId = fileInfoService.getFileIdByMainId(id, fileExt);
        GridFSFile gfsfile = mongoDbFileService.getFSFile(fileId);
        String realFileName = gfsfile.getFilename().replace(",", "");
        if (StrUtil.isEmpty2(fileName)) {
            fileName = realFileName;
        } else {
            fileName = fileName.concat(".").concat(FileUtil.getFileExt(realFileName));
        }
        //处理中文文件名乱码
        if (request.getHeader("User-Agent").toUpperCase().contains("MSIE") ||
                request.getHeader("User-Agent").toUpperCase().contains("TRIDENT")
                || request.getHeader("User-Agent").toUpperCase().contains("EDGE")) {
            fileName = java.net.URLEncoder.encode(fileName, "UTF-8");
        } else {
            //非IE浏览器的处理:
            fileName = new String(fileName.getBytes("UTF-8"), "ISO-8859-1");
        }
        // 通知浏览器进行文件下载
        int lastDotIndex = fileName.lastIndexOf('.');
        String fileNameWithoutExtension = fileName.substring(0, lastDotIndex);
        response.setHeader("Content-Disposition", "attachment;filename=\"" + fileNameWithoutExtension +".pdf" + "\"");

        // 获取pdf文件,并添加水印在返回pdf
        // todo 获取用户名,解决中文水印报错bug
        String watermark = "";
        DateTime date = DateUtil.date();
        String time = DateUtil.format(date, "yyyy-MM-dd");
        watermark = watermark + time+ "" + userName;
        OutputStream out = response.getOutputStream();
        PdfUtil.two(tempPathPdf+id+".pdf",out,key,watermark);
    }

工具类

java 复制代码
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.encryption.AccessPermission;
import org.apache.pdfbox.pdmodel.encryption.StandardProtectionPolicy;
import org.apache.pdfbox.pdmodel.font.PDType0Font;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.apache.pdfbox.util.Matrix;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;

/**
 * @author csb
 * @description: TODO
 * @date 2023/11/20 17:05
 */
public class PdfUtil {

	//加密和加水印
    public static void two (String in, OutputStream out, String password, String watermark) throws IOException {
        // 加载PDF文件
        PDDocument document = PDDocument.load(new File(in));

        // 创建访问权限对象
        AccessPermission accessPermission = new AccessPermission();
        accessPermission.setCanPrint(true);
        accessPermission.setCanModify(false);
        accessPermission.setCanFillInForm(false);
        accessPermission.setCanExtractContent(false);

        // 创建保护策略对象
        StandardProtectionPolicy protectionPolicy = new StandardProtectionPolicy("password", password, accessPermission);

        // 应用保护策略到文档
        document.protect(protectionPolicy);

        //加载本地字体文件,解决中文bug 
        PDType0Font font = PDType0Font.load(document, new File("D:\\11.ttf"));

        // 加水印 遍历每一页
        for (PDPage page : document.getPages()) {
            // 创建内容流以在页面上绘制文本
            PDPageContentStream contentStream = new PDPageContentStream(document, page, PDPageContentStream.AppendMode.APPEND, true);

            // 设置字体、颜色和透明度
            contentStream.setFont(font, 36);
            contentStream.setNonStrokingColor(200, 200, 200); // 灰色
            contentStream.setLineWidth(5);

            // 计算水印位置(居中)
            float pageHeight = page.getMediaBox().getHeight();
            float pageWidth = page.getMediaBox().getWidth();

            // 添加水印文本
            contentStream.beginText();

            for (int h = 10; h < pageHeight; h = h + 300) {
                for (int w = -10; w < pageWidth; w = w + 300) {
                    contentStream.setTextMatrix(Matrix.getRotateInstance(0.4, w, h));
                    contentStream.showText(watermark);
                }
            }
            contentStream.endText();
            contentStream.restoreGraphicsState();

            // 关闭内容流并保存更改
            contentStream.close();
        }

        // 保存加密后的PDF文件
        document.save(out);

        // 关闭文档
        document.close();
        out.close();
    }

    public static void WatermarkPDF(String in) throws IOException {
        // 加载PDF文档
        PDDocument document = PDDocument.load(new File("input.pdf"));

        // 遍历每一页
        for (PDPage page : document.getPages()) {
            // 创建内容流以在页面上绘制文本
            PDPageContentStream contentStream = new PDPageContentStream(document, page, PDPageContentStream.AppendMode.APPEND, true);

            // 设置字体、颜色和透明度
            contentStream.setFont(PDType1Font.HELVETICA_BOLD, 36);
            contentStream.setNonStrokingColor(200, 200, 200); // 灰色
            contentStream.setLineWidth(5);

            // 计算水印位置(居中)
            float x = page.getMediaBox().getWidth() / 2;
            float y = page.getMediaBox().getHeight() / 2;

            // 添加水印文本
            contentStream.beginText();
            contentStream.newLineAtOffset(x, y);
            contentStream.showText("水印");
            contentStream.endText();

            // 关闭内容流并保存更改
            contentStream.close();
        }

        // 保存带有水印的PDF文档
        document.save("output.pdf");

        // 关闭文档
        document.close();
    }

    public static void SetPdfPassword (String in){
        try {
            // 加载PDF文件
            PDDocument document = PDDocument.load(new File(in));

            // 创建访问权限对象
            AccessPermission accessPermission = new AccessPermission();
            accessPermission.setCanPrint(true);
            accessPermission.setCanModify(false);
            accessPermission.setCanFillInForm(false);
            accessPermission.setCanExtractContent(false);

            // 创建保护策略对象
            StandardProtectionPolicy protectionPolicy = new StandardProtectionPolicy("password", "123456", accessPermission);

            // 应用保护策略到文档
            document.protect(protectionPolicy);

//            // 保存加密后的PDF文件
            document.save("D:\\test\\pdf\\2.pdf");

            // 关闭文档
            document.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

maven

xml 复制代码
<dependency>
    <groupId>org.apache.pdfbox</groupId>
    <artifactId>pdfbox</artifactId>
    <version>2.0.6</version>
</dependency>

<dependency>
    <groupId>com.artofsolving</groupId>
    <artifactId>jodconverter</artifactId>
    <version>2.2.1</version>
</dependency>
相关推荐
晨曦_子画1 分钟前
编程语言之战:AI 之后的 Kotlin 与 Java
android·java·开发语言·人工智能·kotlin
南宫生24 分钟前
贪心算法习题其三【力扣】【算法学习day.20】
java·数据结构·学习·算法·leetcode·贪心算法
Heavydrink37 分钟前
HTTP动词与状态码
java
ktkiko1140 分钟前
Java中的远程方法调用——RPC详解
java·开发语言·rpc
计算机-秋大田1 小时前
基于Spring Boot的船舶监造系统的设计与实现,LW+源码+讲解
java·论文阅读·spring boot·后端·vue
神里大人1 小时前
idea、pycharm等软件的文件名红色怎么变绿色
java·pycharm·intellij-idea
一个处女座的程序猿1 小时前
LLMs之PDF:zeroX(一款PDF到Markdown 的视觉模型转换工具)的简介、安装和使用方法、案例应用之详细攻略
pdf·markdown·zerox
Dxy12393102161 小时前
python下载pdf
数据库·python·pdf
周亚鑫1 小时前
vue3 pdf base64转成文件流打开
前端·javascript·pdf
小冉在学习1 小时前
day53 图论章节刷题Part05(并查集理论基础、寻找存在的路径)
java·算法·图论