java实现pdf文件添加水印,下载到浏览器

news2025/2/26 10:00:19

java实现pdf文件添加水印,下载到浏览器

添加itextpdf依赖

<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itextpdf</artifactId>
    <version>5.5.8</version>
</dependency>

文件下载到浏览器和指定路径

根据需求,不需要指定路径可以删除对应的输出流

public void addPDFImageWaterMark(MultipartFile srcFile, MultipartFile imagePath, HttpServletResponse response) {
    String fileName = "test.pdf";
    PdfReader reader = null;
    PdfStamper stamper = null;
    FileInputStream fileInputStream = null;
  	//这个输出流要放入PdfStamper构造方法中,这里也会下载一个文件,不需要的话可以在finally中删除
 		FileOutputStream fileOutputStream = null;
  	//下载到你指定的路径,try里面new的路径,不需要下载到指定路径可以删除
    FileOutputStream fos = null;
    // 设置响应头,指定内容类型和文件名,准备下载到浏览器,下载到指定位置,不需要下载到浏览器可以删除这个输出流
    ServletOutputStream outputStream = null;
    response.setContentType("application/pdf");
    response.setHeader("Content-Disposition", "attachment; filename=" + srcFile.getOriginalFilename());
    try {
        outputStream = response.getOutputStream();
        //如果是路径的话可以使用另一个构造方法reader = new PdfReader(srcPath);
        reader = new PdfReader(srcFile.getBytes());
        fileOutputStream = new FileOutputStream(fileName);
        stamper = new PdfStamper(reader, fileOutputStream);
        //加载图片
        //如果是路径的话可以使用另一个构造方法Image image =Image.getInstance(imagePath);
        Image image = Image.getInstance(imagePath.getBytes());
        //将图片控制大小,适配这个大小
        image.scaleToFit(200, 100);

        PdfGState gs = new PdfGState();
        //gs.setFillOpacity(0.2f);//图片水印透明度
        //gs.setStrokeOpacity(0.4f);//设置笔触字体不透明度
        PdfContentByte content = null;

        int total = reader.getNumberOfPages();//pdf文件页数
        for (int i = 0; i < total; i++) {
            float x = reader.getPageSize(i + 1).getWidth();//页宽度
            float y = reader.getPageSize(i + 1).getHeight();//页高度
            content = stamper.getOverContent(i + 1);
            content.setGState(gs);
            content.beginText();//开始写入

            //每页7行,一行3个
            for (int j=0; j<3; j++) {
                for (int k=0; k<7; k++) {
                    //setAbsolutePosition 方法的参数(输出水印X轴位置,Y轴位置)
                    image.setAbsolutePosition(x/3*j-30, y/7*k-20);
                    content.addImage(image);
                }
            }
            content.endText();//结束写入
        }
        //要先关闭流才能将生成的文件写到指定地方!!!
        stamper.close();
        reader.close();
        //指定这个文件(这里我用的相对路径)
        fileInputStream = new FileInputStream(fileName);
        //创建输出流,下载到指定路径
        fos = new FileOutputStream("test1.pdf");
        byte[] buffer = new byte[1024];
        int bytesRead = 0;
        while ((bytesRead = fileInputStream.read(buffer)) != -1) {
            // 浏览器下载
            outputStream.write(buffer, 0, bytesRead);
            //下载到指定路径
            fos.write(buffer, 0, bytesRead);
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        try {
            //关闭流
            if (stamper != null) {
                stamper.close();
            }
            if (reader != null) {
                reader.close();
            }
            if (fos != null) {
                fos.close();
            }
            if (fileInputStream != null) {
                fileInputStream.close();
            }
            if (fileOutputStream != null) {
                fileOutputStream.close();
            }
            if (outputStream != null) {
                outputStream.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

效果如下:代码中的相对路径在src平级目录下,test.pdf是PdfStamper里面fileOutputStream生成的,test1.pdf是fos生成的

在这里插入图片描述

浏览器下载的如下:

在这里插入图片描述

生成的pdf内容如下(红框里面是pdf原来的内容,可以自己调整代码中注释掉的设置水印透明度来调整)

在这里插入图片描述

提供的前端代码自行测试

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

    <h2>测试PDF添加水印</h2>
    <form method="post" action="http://localhost:8080/addPDFImageWaterMark" enctype="multipart/form-data">
        <label for="srcFile">选择PDF文件:</label>
        <input type="file" name="srcFile" id="srcFile" accept=".pdf" required>
        <br>
        <label for="imagePath">选择水印图片:</label>
        <input type="file" name="imagePath" id="imagePath" accept=".jpg, .png" required>
        <br>
        <button type="submit">添加水印并下载</button>
    </form>

</body>
</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1158648.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

第四章 数据结构与算法——树与二叉树

一、树的定义 ①&#xff1a;树是一种 非线性 的数据结构&#xff0c;它是由 n &#xff08; n>0 &#xff09;个有限结点组成一个具有层次关系的集合。 ②&#xff1a; 把它叫做树是因 为它看起来像一棵倒挂的树&#xff0c;也就是说它是根朝上&#xff0c;而叶朝下的 。 …

BetterDisplay Pro v1.4.15(显示器管理管理软件)

BetterDisplay Pro是一款屏幕显示优化工具&#xff0c;可用于Windows和Mac操作系统。它可以帮助用户调整屏幕的亮度、对比度、色彩等参数&#xff0c;以获得更好的视觉体验。此外&#xff0c;BetterDisplay Pro还提供了一些额外的功能&#xff0c;如屏幕分割、窗口管理、快捷键…

变量的作用域

在javascript中&#xff0c;var定义的变量实际是有作用域的。 1 假设在函数体内声明&#xff0c;但在函数体外不可以使用 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title> </…

HBase理论与实践-基操与实践

基操 启动&#xff1a; ./bin/start-hbase.sh 连接 ./bin/hbase shell help命令 输入 help 然后 <RETURN> 可以看到一列shell命令。这里的帮助很详细&#xff0c;要注意的是表名&#xff0c;行和列需要加引号。 建表&#xff0c;查看表&#xff0c;插入数据&#…

怎么检测开关电源质量的好坏?测试的方法是什么?

开关电源的工作原理 开关电源(简称SMPS)是常见的一种电源供应器&#xff0c;是高频化的电能转换装置&#xff0c;可以将电压透过不同形式的架构转换为用户端所需求的电压或电流。具有体积小、功耗小、效率高、高可靠性的特点&#xff0c;被广泛应用在工业、军工设备、科研设备、…

SHCTF 未出题目复盘

crypto week1 立正 逆序得到 :V Qook at you~ this is flag: EmxhE8tERKAfYAZ6S636dIWuEK46ZK4yRBdNdK4uRKd4 decode it 中间那串像b64 解码解不出什么 猜测还要rotate Emxh 和 flag编码后的前几位比较接近 考虑大写字母需要继续偏移 对大写字母处理完后得到 :Q Look at you…

当贝PadGO闺蜜机?多的是你不知道的玩法

一、当贝PadGO性能强在哪? 1、金属机身 当贝PadGO独有CD型底盘更有设计风格、后扶手设计更稳,且采用全金属的材质更有质感。并且在配色上还有熊猫白和唱片黑两种可以选择。屏幕采用AG磨砂类纸屏,自带纸张柔和效果,防眩光。并且拥有德国莱茵低蓝光、无频闪双重护眼认证,还可以…

食堂系统登录报错

因为数据库没有任何用户数据&#xff0c;所以会报错&#xff0c;需要添加admin用户 D:\env\jdk1.8.0_341\bin\java.exe -XX:TieredStopAtLevel1 -noverify -Dspring.output.ansi.enabledalways -Dcom.sun.management.jmxremote -Dspring.jmx.enabledtrue -Dspring.liveBeansVie…

“知了杯”网络安全竞赛(南充赛区)圆满落幕

为积极响应网络空间安全人才战略&#xff0c;加快攻防兼备网络创新人才培养步伐&#xff0c;实现以赛促学、以赛促教、以赛促用&#xff0c;推动网络空间安全人才培养和产学研用生态发展&#xff0c;成都知了汇智科技有限公司作为产教融合服务型平台机构&#xff0c;在四川省工…

LeetCode----84. 柱状图中最大的矩形

题目 给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。 求在该柱状图中,能够勾勒出来的矩形的最大面积。 示例 1: 输入:heights = [2,1,5,6,2,3] 输出:10 解释:最大的矩形为图中红色区域,面积为 10 示例 2: 输入: heights =…

中期科技:智慧公厕打造智能化城市设施,提升公共厕所管理与服务体验

智慧公厕是利用先进的技术和创新的解决方案来改进公厕的设施和管理。借助物联网、互联网、5G/4G通信、人工智能、大数据、云计算等新兴技术的集成&#xff0c;智慧公厕具备了一系列令人惊叹的应用功能。从监测公厕内部人体活动状态、人体存在状态&#xff0c;到空气质量情况、环…

【LVS实战】03 LVS负载均衡-DR模式实验

本文介绍&#xff0c;如何通过ipvsadm配置负载均衡&#xff0c;并且转发模式为DR直接路由模式 一、网络拓扑 如下图&#xff1a; LVS负载均衡的机器&#xff0c;配置了一个VIP&#xff1a;10.1.0.7 二、前置准备 每台机器关闭防火墙 systemctl stop firewalldRS装好nginx…

01【保姆级】-GO语言特点和安装使用和hello

01-GO语言基本概念和安装使用 一、概念1.1 Go语言的诞生1.2 GO语言的特点&#xff1a; 二、安装go2.1 安装2.2 安装环境变量 三、下载&安装goland3.1 官网下载3.2 下载后&#xff0c;进行安装&#xff1a; 四、编写Hello&#xff08;详解&#xff09; 如何学习&#xff1a;…

AI视频监控汇聚平台EasyCVR增加算法功能小tips

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等&#xff0c;能对外…

【原理】循环水系统【组件介绍】

目录 前言一、工作原理二、主要组件2-1、 保温水箱2-2、 热水泵2-3、 电加热器2-4、 管式换热器2-5、 开关阀、流量阀和调节阀2-6、 冷却塔2-7、 冷水泵 总结 前言 循环水系统是一种用于维持恒定温度或温度范围的工业或建筑设施中的热力控制系统。该系统通过循环水来传递热量&a…

智慧公厕:科技赋予公共卫生新生命,提升城市管理品质

在现代化城市中&#xff0c;公共卫生设施的发展与提升一直是对城市管理者和市民的共同期望。然而&#xff0c;传统的公共厕所常常令人困扰&#xff0c;脏乱臭成为难题。为了解决这一难题&#xff0c;广州中期科技科技有限公司全新升级的智慧公厕整体解决方案&#xff0c;补誉为…

配音软件怎么选择?(简单又实用)

随着短视频、自媒体的普及推广越来越好&#xff0c;想必大家都了解到配音软件的重要性了&#xff0c;用对配音软件&#xff0c;借助AI的力量让我们的作品达到事半功倍是效果&#xff0c;目前市面上有很多不同类型的配音软件&#xff0c;从专业的录音室级别的软件到简单易用的家…

Videos

文章目录 Video ClassificationEarly Fusion, Late Fusion, 3D CNN,Recognizing Actions from Motion 从动作中识别行为接下来介绍新技术回顾一下&#xff1a;非常多的video工作 Video Classification Early Fusion, Late Fusion, 3D CNN, Recognizing Actions from Motion 从…

谷歌浏览器升级http强转https解决

mac电脑有点卡&#xff0c;重启以后&#xff0c;谷歌浏览器默认升级 后续访问公司http网址&#xff0c;自动跳转为https网址&#xff0c;导致进入不了平台 网上找了很多方案都是&#xff0c;地址栏中输入【chrome://net-internals/#hsts】&#xff0c;在最下面的【Delete dom…

软件测试常见1000道面试题(答案+文档)

软件测试面试百题 1、问&#xff1a;你在测试中发现了一个bug&#xff0c;但是开发经理认为这不是一个bug&#xff0c;你应该怎样解决? 首先&#xff0c;将问题提交到缺陷管理库里面进行备案。 然后&#xff0c;要获取判断的依据和标准&#xff1a; 根据需求说明书、产品说…