PDF下载添加水印和访问密码
下载接口
@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 获取用户名,解决中文水印报错bugString 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);}
工具类
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
<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>
相关文章:
PDF下载添加水印和访问密码
下载接口 ApiOperation(value "下载文件-pdf", notes "下载文件pdf版", httpMethod "GET", response WebResult.class)RequestMapping(value "/downloadPdf", method RequestMethod.GET)public void downloadFilePdf(RequestPar…...
基于SSM+MySQL的的新闻发布系统设计与实现
目录 项目简介 项目技术栈 项目运行环境 项目截图 代码截取 源码获取 项目简介 新闻发布系统是一款基于Servletjspjdbc的网站应用程序,旨在提供一个全面且高效的新闻发布平台。该系统主要包括后台管理和前台新闻展示两个平台,涵盖了新闻稿件的撰写…...
记录首次使用yolov8-obb
1.数据格式 之前使用的数据格式是yolov5_obb的数据格式,然后需要转数据格式: 目前的数据只支持四个坐标点标注的数据,参考:If a corner of the rotate rectangle is out of the image range, How to annotate the image? Issu…...
深度学习环境配置:Anaconda 安装和 pip 源
conda是一种通用包管理系统,与pip的使用类似,环境管理则允许用户方便地安装不同版本的python并可以快速切换。 Anaconda则是一个打包的集合,里面预装好了conda、某个版本的python、众多packages、科学计算工具等等,就是把很多常用…...
100 个 NLP 面试问题
100 个 NLP 面试问题 一、 说明 对于技术磨练中,其中一项很酷的技能培训是提问。不知道答案并没有多大的错;错就错在不谷歌这些疑问。本篇就是在面试之前,您将此文档复制给自己,做一个系统的模拟实战。 二、经典NLP问题(共8题&a…...
C# OMRON PLC FINS TCP协议简单测试
FINS(factory interface network service)通信协议是欧姆龙公司开发的用于工业自动化控制网络的指令/响应系统。运用 FINS指令可实现各种网络间的无缝通信,包括用于信息网络的 Etherne(以太网),用于控制网络的Controller Link和SYSMAC LINK。…...
MQTT在linux下服务端和客户端的应用
MQTT(Message Queuing Telemetry Transport)是一种轻量级、开放标准的消息传输协议,设计用于受限设备和低带宽、不稳定网络的通信。 MQTT的一些关键特点和概念: 发布/订阅模型: MQTT采用发布/订阅(Publ…...
韦达定理用处多
文章目录 前言一、一元二次方程中根和系数之间的关系二、韦达定理的数学推导和作用1. 韦达定理的数学推导2. 韦达定理的作用 三、韦达定理的应用举例1. 解题示例12. 解题示例23. 解题示例34. 解题示例45. 解题示例56. 解题示例67. 解题示例7 总结 前言 韦达定理说明了一元n次方…...
Kotlin-类
构造函数 Java final File file new File("file.txt");Kotlin val file File("file.txt")类 Java public final class User { }Kotlin class User公开类 Java public class User { }Kotlin open class User属性类 Java final class User {pri…...
redis基本数据结构介绍
Redis(Remote Dictionary Server)是一个开源的高性能键值对数据库,它支持多种数据结构,包括字符串、哈希、列表、集合、有序集合等。这些数据结构为开发者提供了丰富的数据操作方式,使得Redis在缓存、消息队列、排行榜…...
云数据库RDS云监控
1. 什么是云数据库RDS?它有哪些特点? 云数据库RDS是一种在线关系型数据库服务,它具备的特点包括: 安全可靠:提供了容灾、备份、恢复等高可用性功能,确保数据的安全与可靠。弹性伸缩:用户可以根…...
全自动网页生成系统重构版源码
全自动网页生成系统重构版源码分享,所有模板经过精心审核与修改,完美兼容小屏手机大屏手机,以及各种平板端、电脑端和360浏览器、谷歌浏览器、火狐浏览器等等各大浏览器显示。 为用户使用方便考虑,全自动网页制作系统无需繁琐的注…...
Leetcode—33. 搜索旋转排序数组【中等】
2024每日刷题(110) Leetcode—33. 搜索旋转排序数组 实现代码 class Solution { public:int search(vector<int>& nums, int target) {int n nums.size();int l 0, r n - 1;while(l < r) {int m l (r - l) / 2;if(nums[m] target) …...
vulhub中Apache APISIX Dashboard API权限绕过导致RCE(CVE-2021-45232)
Apache APISIX是一个动态、实时、高性能API网关,而Apache APISIX Dashboard是一个配套的前端面板。 Apache APISIX Dashboard 2.10.1版本前存在两个API/apisix/admin/migrate/export和/apisix/admin/migrate/import,他们没有经过droplet框架的权限验证&…...
JavaSE习题 使用函数求最大值、求最大值方法的重载和求和方法的重载
目录 1 使用函数求最大值2 求最大值方法的重载3 求和方法的重载 1 使用函数求最大值 使用函数求最大值:创建方法求两个数的最大值max2,随后再写一个求3个数的最大值的函数max3。 要求: 在max3这个函数中,调用max2函数ÿ…...
英码科技携手昇腾共建算力底座:推出EA500I超强AI处理能力边缘计算盒子!
在数字经济浪潮中,算力已成为不可或缺的驱动力,为各行各业的数字化转型提供了强大的推动力。面对多元化和供需不平衡的挑战,需要实现从理论架构到软硬件实现的质的飞跃,以满足持续增长的算力需求,华为昇腾在这一方面展…...
蓝桥杯每日一题-----数位dp练习
题目 链接 参考代码 写了两个,一个是很久以前写的,一个是最近刚写的,很久以前写的时候还不会数位dp所以写了比较详细的注释,这两个代码主要是设置了不同的记忆数组,通过这两个代码可以理解记忆数组设置的灵活性。 im…...
JS(react)图片压缩+图片上传
上传dome var fileNodeTakeStock: any createRef();<inputref{fileNodeTakeStock}onChange{showPictureTakeStock}style{{ display: "none" }}id"fileInpBtn"type"file"accept"image/*" //限制上传格式multiple{false}capture&qu…...
WPF DispatcherTimer用法
System.Windows.Threading.DispatcherTimer 类主要用于WPF应用程序中进行周期性任务调度,并且保证这些任务在UI线程上执行。 这对于需要更新界面或与UI元素交互的定时操作非常有用,因为WPF的所有UI操作都必须在主线程(即Dispatcher线程&…...
【网络安全实验】snort实现高级IDS
注:本实验分别使用kali和CentOS6.8进行测试,可惜的是使用kali进行实验过程中遇到了困难,未能完成完整实验,而使用CentOS6.8成功完成了完整实验。 实验中用到的软件: https://download.csdn.net/download/weixin_5255…...
铭豹扩展坞 USB转网口 突然无法识别解决方法
当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...
Ubuntu系统下交叉编译openssl
一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机:Ubuntu 20.04.6 LTSHost:ARM32位交叉编译器:arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...
Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...
macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用
文章目录 问题现象问题原因解决办法 问题现象 macOS启动台(Launchpad)多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显,都是Google家的办公全家桶。这些应用并不是通过独立安装的…...
第25节 Node.js 断言测试
Node.js的assert模块主要用于编写程序的单元测试时使用,通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试,通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...
九天毕昇深度学习平台 | 如何安装库?
pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子: 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...
AI病理诊断七剑下天山,医疗未来触手可及
一、病理诊断困局:刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断",医生需通过显微镜观察组织切片,在细胞迷宫中捕捉癌变信号。某省病理质控报告显示,基层医院误诊率达12%-15%,专家会诊…...
Yolov8 目标检测蒸馏学习记录
yolov8系列模型蒸馏基本流程,代码下载:这里本人提交了一个demo:djdll/Yolov8_Distillation: Yolov8轻量化_蒸馏代码实现 在轻量化模型设计中,**知识蒸馏(Knowledge Distillation)**被广泛应用,作为提升模型…...
初探Service服务发现机制
1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能:服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源…...
vulnyx Blogger writeup
信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面,gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress,说明目标所使用的cms是wordpress,访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...
