当前位置: 首页 > news >正文

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

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>

相关文章:

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

java实现pdf文件添加水印&#xff0c;下载到浏览器 添加itextpdf依赖 <dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.5.8</version> </dependency>文件下载到浏览器和指定路径 …...

代码随想录算法训练营第四十一天丨 动态规划part04

01背包理论基础 见连接&#xff1a;代码随想录 416. 分割等和子集 思路 01背包问题 背包问题&#xff0c;大家都知道&#xff0c;有N件物品和一个最多能背重量为W 的背包。第i件物品的重量是weight[i]&#xff0c;得到的价值是value[i] 。每件物品只能用一次&#xff0c;求解…...

PyCharm免费安装和新手使用教程

简介 PyCharm是一款由JetBrains公司开发的Python集成开发环境&#xff08;IDE&#xff09;。它提供了一系列强大的功能&#xff0c;包括自动代码完成、语法高亮、自动缩进、代码重构、调试器、测试工具、版本控制工具等&#xff0c;使开发者可以更加高效地开发Python应用程序。…...

使用Python的Scikit-Learn进行决策树建模和可视化:以隐形眼镜数据集为例

决策树是一种强大的机器学习算法&#xff0c;它在数据挖掘和模式识别中被广泛应用。决策树模型可以帮助我们理解数据中的模式和规则&#xff0c;并做出预测。在本文中&#xff0c;我们将介绍如何使用Python的Scikit-Learn库构建决策树模型&#xff0c;并使用Graphviz进行可视化…...

开源软件:释放创新的力量,改变数字世界的游戏规则

在充满活力的技术领域&#xff0c;创新是至高无上的&#xff0c;有一种方法已获得显著的吸引力——开源软件。开源软件凭借其透明、协作和无限可能性的精神&#xff0c;彻底改变了我们开发、共享和定制应用程序的方式。从操作系统到数据分析工具&#xff0c;其影响跨越了多个领…...

【QT】鼠标常用事件

新建项目 加标签控件 当鼠标进去&#xff0c;显示【鼠标进入】&#xff0c;离开时显示【鼠标离开】 将QLable提升成自己的控件&#xff0c;然后再去捕获 添加文件 改继承的类名 提升类 同一个父类&#xff0c;可以提升 效果 现在代码就和Qlabel对应起来了。 在.h中声明&…...

LuatOS-SOC接口文档(air780E)--mlx90640 - 红外测温(MLX90640)

常量# 常量 类型 解释 mlx90640.FPS1HZ number FPS1HZ mlx90640.FPS2HZ number FPS2HZ mlx90640.FPS4HZ number FPS4HZ mlx90640.FPS8HZ number FPS8HZ mlx90640.FPS16HZ number FPS16HZ mlx90640.FPS32HZ number FPS32HZ mlx90640.FPS64HZ number FPS6…...

java连接本地数据库可以简写为///

java连接数据库配置文件写为&#xff1a; server:port: 8091 spring:application:name: user-managerdatasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/user?serverTimezoneAsia/Shanghai&characterEncodingutf-8username: root…...

基于springboot漫画动漫网站

基于springbootvue漫画动漫网站 摘要 基于Spring Boot的漫画动漫网站是一个精彩的项目&#xff0c;它结合了现代Web开发技术和漫画爱好者的热情。这个网站的目标是为用户提供一个便捷的平台&#xff0c;让他们能够欣赏各种漫画和动漫作品&#xff0c;与其他爱好者分享他们的兴趣…...

autoFac 生命周期 试验

1.概述 autoFac的生命周期 序号名称说明1InstancePerDependency每次请求都创建一个新的对象2InstancePerLifetimeScope同一个Lifetime生成的对象是同一个实例3SingleInstance每次都用同一个对象 2.注 InstancePerLifetimeScope 同一个Lifetime生成的对象是同一个实例&#x…...

foreach、for in 和for of的区别?

forEach&#xff0c;for...in 和 for...of 是 JavaScript 中用于遍历数据的三种不同的结构。它们在遍历数组、对象和可迭代对象&#xff08;如 Set 和 Map&#xff09;时非常有用。尽管它们都可以用于循环遍历&#xff0c;但它们之间存在一些重要的区别&#xff1a; forEach&a…...

【Effective C++】条款45: 运用成员函数模板接受所有兼容的类型

假设有如下继承结构: class Top{}; class Middle: public Top{}; class Bottom: public Middle{};public继承意味着is-a关系,所有的基类都是派生类,但反之则不是,例如所有的学生都是人,但不是所有的人都是学生. 派生类到基类的指针可以直接隐式转换 Top* pt1 new Middle; T…...

WSL1 安装 debian xfce 用xrdp 导入远程桌面

凑合能用 晃晃行 晃晃不行 而且比较卡 还经常报崩溃 sudo apt install xfce4 xfce4-goodies xorg dbus-x11 x11-xserver-utils apt install locales -y 安装过完应该会提示设置locales&#xff0c;如果安装完之后想要更改相关设置&#xff0c;可以使用如下命令重新设置loca…...

WPF RelativeSource属性-目标对象类型易错

上一篇转载了RelativeSource的三种用法&#xff0c;其中第二种用法较常见&#xff0c;这里记录一下项目中曾经发生错误的地方&#xff0c;以防自己哪天忘记了&#xff0c;又犯了同样错误—WPF RelativeSource属性-CSDN博客 先回顾一下&#xff1a; 控件关联其父级容器的属性—…...

Java while 和do while 循环

循环是程序中的重要流程结构之一。循环语句能够使程序代码重复执行&#xff0c;适用于需要重复一段代码直到满足特定条件为止的情况。 所有流行的编程语言中都有循环语句。Java 中采用的循环语句与C语言中的循环语句相似&#xff0c;主要有 while、do-while 和 for。 另外 Ja…...

应用软件安全编程--03净化传递给 Runtime.exec() 方法的非受信数据

每个 Java 应用都有一个 Runtime 类的实例&#xff0c; 一般需要使用 shell 时调用它&#xff0c;从而可以在 POSIX 中 使用/bin/sh 或者在Windows 平台中使用cmd.exe。 当参数中包含以空格、双引号或者其他以一/开头 的用来表示分支的字符时&#xff0c;就可能发生参数注入攻…...

uniapp阻止冒泡的方法,点击事件嵌套点击事件,怎么阻止同时触发

uniapp阻止冒泡的方法 当我们遇到点击事件嵌套点击事件的时候&#xff0c;点击里边的事件&#xff0c;外边的也会跟着触发该怎么办&#xff1f; 起初我尝试用了css里的修改z-index属性的方法&#xff0c;把里边的<view>标签放在上边&#xff0c;结果两个事件还是同时触发…...

【云原生基础】了解云原生,什么是云原生?

&#x1f4d1;前言 本文主要讲了云原生的基本概念和原则的文章&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️ &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是青衿&#x1f947; ☁️博客首页&#xff1a;CSDN主页放风讲故事 &#x1f304;每日一句&#x…...

Android.bp探究

有时不知道Android.bp要咋写&#xff0c;特意看了下源码&#xff1a; ./build/soong/androidmk/androidmk/android.go 简单的Android.bp的模板是下面这个样子&#xff1a; [module type] {name: "[name value]",[property1 name]&#xff1a;"[property1 val…...

【LeetCode】415 字符串相加

415. 字符串相加 给定两个字符串形式的非负整数 num1 和num2 &#xff0c;计算它们的和并同样以字符串形式返回。 你不能使用任何內建的用于处理大整数的库&#xff08;比如 BigInteger&#xff09;&#xff0c; 也不能直接将输入的字符串转换为整数形式。 示例 1&#xff1a…...

保姆级教程:用Python脚本一键划分LS-SSDD-v1.0数据集(附近岸/离岸测试集处理)

Python自动化处理LS-SSDD数据集&#xff1a;从混乱到规范的完整指南 当你第一次打开LS-SSDD-v1.0数据集时&#xff0c;面对24,00016,000像素的大图和9000张800800的小图&#xff0c;以及各种划分文件&#xff0c;可能会感到无从下手。这份数据集虽然为SAR图像中的小舰船检测提供…...

比迪丽LoRA部署优化:TensorRT加速后推理速度提升300%实测

比迪丽LoRA部署优化&#xff1a;TensorRT加速后推理速度提升300%实测 1. 引言&#xff1a;当二次元老婆遇上推理加速 如果你玩过AI绘画&#xff0c;尤其是喜欢生成《龙珠》里的角色比迪丽&#xff0c;那你一定知道等待图片生成时的那种心情——看着进度条一点点爬&#xff0c…...

保姆级教程:用Docker Compose和Nginx给内网Nexus仓库上HTTPS(自签证书避坑指南)

内网Nexus私有仓库HTTPS全栈实战&#xff1a;从Docker部署到证书信任闭环 当开发团队规模超过10人时&#xff0c;私有制品仓库就成了刚需。上周帮某金融客户部署内网Nexus时&#xff0c;发现Maven 3.8.1强制HTTPS的策略让很多工程师措手不及——内网没有公网域名&#xff0c;Le…...

ATPG约束C/T/O/DX傻傻分不清?一张图帮你搞定芯片测试中的cell constraint

ATPG约束C/T/O/DX全解析&#xff1a;芯片测试工程师的速查手册 刚接触ATPG工具的新手工程师们&#xff0c;是否曾被手册里那些神秘的字母组合搞得晕头转向&#xff1f;C、T、O、DX...这些看似简单的缩写背后&#xff0c;隐藏着对测试覆盖率的关键影响。本文将用最直观的方式&a…...

OFA图像语义蕴含模型实战:基于Python的英文图文关系判断

OFA图像语义蕴含模型实战&#xff1a;基于Python的英文图文关系判断 用AI看懂图片和文字之间的关系&#xff0c;原来这么简单 你有没有遇到过这样的情况&#xff1a;看到一张图片和一段英文描述&#xff0c;想要快速判断它们是否匹配&#xff1f;比如电商平台需要自动审核商品图…...

效率提升利器:用快马AI生成批量域名健康检查工具,告别手动刷新

效率提升利器&#xff1a;用快马AI生成批量域名健康检查工具&#xff0c;告别手动刷新 作为开发者或运维人员&#xff0c;我们经常需要监控一批服务域名的健康状态。比如最近公司新上线了一批jxx相关的域名&#xff0c;需要定期检查它们的可用性和响应速度。传统的手动刷新浏览…...

DecompilerMC:揭秘Minecraft源码反编译的高效方案

DecompilerMC&#xff1a;揭秘Minecraft源码反编译的高效方案 【免费下载链接】DecompilerMC This repository allows you to decompile any minecraft version that was published after 19w36a without any 3rd party mappings, you just need to execute the script or the …...

3步解锁百度网盘SVIP特权:macOS用户必备的高速下载解决方案

3步解锁百度网盘SVIP特权&#xff1a;macOS用户必备的高速下载解决方案 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘Mac客户端的龟速…...

DAMO-YOLO模型微调指南:自定义数据集训练

DAMO-YOLO模型微调指南&#xff1a;自定义数据集训练 1. 引言 目标检测是计算机视觉领域的核心任务之一&#xff0c;而DAMO-YOLO作为阿里巴巴达摩院推出的高效检测框架&#xff0c;在精度和速度方面都表现出色。但预训练模型往往无法直接满足特定场景的需求&#xff0c;这时候…...

Course17:SGLang 深度优化:Radix 缓存与复杂任务的极致吞吐

SGLang vs vLLMvLLM 的高并发原理&#xff1a;PagedAttention&#xff08;解决 KV Cache 碎片&#xff09;Continuous Batching&#xff08;解决 GPU 空闲&#xff09;推测解码&#xff08;加速 Decode 阶段&#xff09;> vLLM 解决的是 如何让模型跑得快 的问题。Thinking&…...