Java实现对PDF、纵向、横向页面添加自定义水印功能
Java实现对PDF、纵向、横向页面添加自定义水印
- 效果图 -- 纵向 页面PDF
- 使用到JAR Maven依赖版本
- 效果图 -- 横向页面PDF
效果图 – 纵向 页面PDF
代码如下:
使用到JAR Maven依赖版本
<dependency><groupId>org.apache.pdfbox</groupId><artifactId>pdfbox</artifactId><version>2.0.27</version></dependency>
--------------------------------------------------------------------------------建议复制测试 --------------------------------------------------------------------------------
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.apache.pdfbox.pdmodel.graphics.state.PDExtendedGraphicsState;
import org.apache.pdfbox.util.Matrix;import java.io.FileInputStream;
import java.io.InputStream;
import java.util.UUID;/*** Java 对PDF 纵向 页面天添加自定义水印*/public class PDFWatermark {public static void main(String[] args) {try {// 输入PDF文件InputStream inputStream = new FileInputStream("W:\\pdf\\77777.pdf"); //需要更换文件地址// 读取PDF文档PDDocument document = PDDocument.load(inputStream);// 自定义水印内容String watermarkText = "lemenpan 2024-05-28 14:23:35 88888888888";// 遍历每一页for (PDPage page : document.getPages()) {// 获取页面宽高float pageWidth = page.getMediaBox().getWidth();float pageHeight = page.getMediaBox().getHeight();// 检查页面是否为纵向if (pageHeight > pageWidth) {// 开始添加水印PDPageContentStream contentStream = new PDPageContentStream(document, page, PDPageContentStream.AppendMode.APPEND, true, true);// 设置水印透明度PDExtendedGraphicsState graphicsState = new PDExtendedGraphicsState();graphicsState.setNonStrokingAlphaConstant(0.5f);contentStream.setGraphicsStateParameters(graphicsState);// 设置水印字体和大小float fontSize = 41.0f;contentStream.setFont(PDType1Font.HELVETICA_BOLD, fontSize);// 设置水印颜色contentStream.setNonStrokingColor(200, 200, 200);// 设置旋转角度,以页面中心为原点contentStream.transform(Matrix.getRotateInstance(Math.toRadians(55), pageWidth / 2, pageHeight / 2));// 计算水印位置(居中)float x = -fontSize * watermarkText.length() / 4; // 基于字符长度和字体大小的估计float y = -fontSize / 4; // 基于字体大小的估计// 添加水印文本contentStream.beginText();contentStream.newLineAtOffset(-400, -30);contentStream.showText(watermarkText);contentStream.endText();// 关闭内容流contentStream.close();}}UUID uuid = UUID.randomUUID();// 保存带有水印的PDFdocument.save("W:\\pdf\\" + uuid.toString() + ".pdf"); //需要更换文件地址// 关闭文档document.close();} catch (Exception e) {e.printStackTrace();}}
}
效果图 – 横向页面PDF
代码如下:
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.apache.pdfbox.pdmodel.graphics.state.PDExtendedGraphicsState;
import org.apache.pdfbox.util.Matrix;import java.io.FileInputStream;
import java.io.InputStream;
import java.util.UUID;/*** Java 对PDF 横向 页面天添加自定义水印*/public class PDFWatermark11HangXiang {public static void main(String[] args) {try {// 输入PDF文件InputStream inputStream = new FileInputStream("W:\\pdf\\88888.pdf"); //需要更换文件地址// 读取PDF文档PDDocument document = PDDocument.load(inputStream);// 自定义水印内容String watermarkText = "lemenpan 2024-05-28 14:23:35 88888888888";// 遍历每一页for (PDPage page : document.getPages()) {// 获取页面宽高float pageWidth = page.getMediaBox().getWidth();float pageHeight = page.getMediaBox().getHeight();// 检查页面是否为横向if (pageWidth > pageHeight) {// 开始添加水印PDPageContentStream contentStream = new PDPageContentStream(document, page, PDPageContentStream.AppendMode.APPEND, true, true);// 设置水印透明度PDExtendedGraphicsState graphicsState = new PDExtendedGraphicsState();graphicsState.setNonStrokingAlphaConstant(0.5f);contentStream.setGraphicsStateParameters(graphicsState);// 设置水印字体和大小contentStream.setFont(PDType1Font.HELVETICA_BOLD, 50);// 设置水印颜色contentStream.setNonStrokingColor(200, 200, 200);// 计算水印位置(居中)float fontSize = 50.0f;float stringWidth = PDType1Font.HELVETICA_BOLD.getStringWidth(watermarkText) / 1000 * fontSize;float x = (pageWidth - stringWidth) / 2;float y = (pageHeight - fontSize) / 2;// 设置旋转角度contentStream.transform(Matrix.getRotateInstance(Math.toRadians(35), pageWidth / 2, pageHeight / 2));// 添加水印文本contentStream.beginText();contentStream.newLineAtOffset(-420,-40 ); //调节 水印内容位置 ,为 X 、Y 坐标。contentStream.showText(watermarkText);contentStream.endText();// 关闭内容流contentStream.close();}}UUID uuid = UUID.randomUUID();// 保存带有水印的PDFdocument.save("W:\\pdf\\" + uuid.toString() + ".pdf"); //需要更换文件地址// 关闭文档document.close();} catch (Exception e) {e.printStackTrace();}}
}
相关文章:

Java实现对PDF、纵向、横向页面添加自定义水印功能
Java实现对PDF、纵向、横向页面添加自定义水印 效果图 -- 纵向 页面PDF使用到JAR Maven依赖版本效果图 -- 横向页面PDF 效果图 – 纵向 页面PDF 代码如下: 使用到JAR Maven依赖版本 <dependency><groupId>org.apache.pdfbox</groupId><artifa…...

设计模式15——享元模式
写文章的初心主要是用来帮助自己快速的回忆这个模式该怎么用,主要是下面的UML图可以起到大作用,在你学习过一遍以后可能会遗忘,忘记了不要紧,只要看一眼UML图就能想起来了。同时也请大家多多指教。 享元模式(Flyweigh…...

多模态中的模态有哪些
“多模态”这个名字中的“模态”(modality),指的是不同的数据类型或信息源。在多模态大模型中,常见的模态包括: 文本模态: 包括自然语言文本、语音识别文本等。 图像模态: 指图像数据ÿ…...
Java练习题(八)
36.关于抽象类叙述正确的是? (B ) A.抽象类不能实现接口 B.抽象类必须有“abstract class”修饰 C.抽象类必须包含抽象方法 D.抽象类也有类的特性,可以被实例化 37.以下说法错误的是(C) A.数组是一个对象 B.数组不是一种原…...

Linux文本文件管理003
★排序、去重、统计★ 1)排序 sort -n按照数值排序 -r降序排列 2)去重 uniq 过滤相邻、重复的行 -c 对重复行计数 3)统计 wc 统计文件中的字节数、单词数、行数 -l 显示行数 今天通过使用grep、awk、cut指令和上面几个选项提取文本文件…...
uniapp Androud 离线打包升级APK,覆盖安装不更新问题
Android 打包时在assets/data/dcloud_control.xml文件中,如果配置debug"true" syncDebug"true",则consle打印有效,不然没有打印数据 <hbuilder debug"true" syncDebug"true"> <apps> …...

【算法实战】每日一题:设计一个算法,用最少数量的矩形覆盖一系列宽度为d、高度为w的矩形,且使用矩形不能超出边界
题目 设计一个算法,用最少数量的矩形覆盖一系列宽度为d、高度为w的矩形建筑物侧墙,且矩形不能超出边界。 核心思路 考虑这种结构 前面递增后面一个与前面的某个高度一致,这时候考虑最下面的覆盖(即都是从最下面向上覆盖&#…...

外贸仓库管理软件:海外仓效率大幅度提升、避免劳动力积压
随着外贸业务的不断发展,如何高效管理外贸仓库,确保货物顺利流转,订单顺利处理,就变得非常重要。 现在通常的解决方案都是通过引入外贸仓库管理软件,也就是我们常说的海外仓WMS系统来解决。 今天我们就系统的探讨一下…...
6.8 LIBBPF API(七,bpf_core_read.h 函数,定义,枚举)
一,函数 void * bpf_rdonly_cast (const void *obj, __u32 btf_id) __ksym __weak 二,定义 __CORE_RELO(src, field, info) __builtin_preserve_field_info((src)->field,BPF_FIELD_##info) __CORE_BITFIELD_PROBE_READ(dst, src, fld) bpf_probe_read_kernel( \ (v…...

电脑卸载linux安装windows后每次开机都出现grub
原因分析 这是因为电脑硬盘中还存在linux系统的引导程序,并且启动顺序还在windows之前,有时候通过bios根本找不到它的存在,以至于每次windows开机出现grub之后都要输入exit退出linux的引导之后才能使得电脑进入windows,这个有时会…...

总结 HTTPS 的加密流程
一、前言 http是为了解决http存在的问题而在http基础上加入了SSL/TSL,在HTTP/2中TCP三次握手后会进入SSL/TSL握手,当SSL/TSL建立链接后,才会进行报文的传输。 二、HTTPS的混合加密 我们先来认识密钥: 密钥是用于加密和解密数据…...

Spring的FactoryBean多例问题
关于spring bean,我们了解的最多的还是单例,而多例bean,除了平时我们自己new的那些多实例外(但不属于IOC管理了),几乎很少能用到,而在spring 层面,FactoryBean刚好是多例的一个体现,…...

[nextjs]推荐几个很好看的模板网站
最近在做网站,折腾了 vue 框架,然后发现了 nextjs 框架,感觉这个做出来的网站配色很好看,然后又开始研究这个 网站配色好看是因为用的 tailwindcss,找网站过程中,发现了几个很好看的模板网站,在这里推荐下,或许你也能用得上 推荐第一个网站是: https://tailspark.co/ 有组件,也…...

《当微服务遇上Ribbon:一场负载均衡的华丽舞会》
在微服务的厨房里,如何确保每一道服务都恰到好处?揭秘Spring Cloud Ribbon如何像大厨一样精心调配资源,让负载均衡变得像烹饪艺术一样简单! 文章目录 Spring Cloud Ribbon 详解1. 引言微服务架构中的负载均衡需求Spring Cloud Rib…...

简单随机数据算法
文章目录 一,需求概述二,实现代码三、测试代码四、测试结果五、源码传送六、效果演示 一,需求概述 系统启动时,读取一组图片数据,通过接口返回给前台,要求: 图片随机相邻图片不重复 二&#…...
js画思维导图代码2
这段代码是一个使用Vue.js和D3.js构建的树形图组件。它是一个Vue组件,用于创建和显示一个交互式的树形结构图。下面是对这段代码的简要分析: 模板部分 (<template>): 定义了组件的HTML结构,包括一个隐藏的提示框(#tooltip)和一个用于显…...

使用 Flask 实现异步请求处理
文章目录 为什么需要异步请求处理?在 Flask 中实现异步请求处理使用 Flask-Cors 扩展 总结 在开发 Web 应用程序时,异步请求处理是提高性能和并发能力的重要方法之一。Flask 是一个轻量级的 Web 框架,它提供了易于使用的工具来实现异步请求处…...

关于c++的通过cin.get()维持黑框的思考
1.前言 由于本科没有学过c语言,研究生阶段接触c上手有点困难,今天遇到关于通过cin.get()来让黑框维持的原因。 2.思考 cin.get()维持黑框不消失的原因一言蔽之就是等待输入。等待键盘的输入内容并回车(一般是回车)后cin.get()才…...
fastadmin接口输出图片 自动拼接网站URL
先自定义常量 1.文件接口路径 修改核心文件 application\common\controller\Api.php/*** 构造方法* access public* param Request $request Request 对象*/public function __construct(Request $request null){$this->request is_null($request) ? Request::instance…...

VMware Workstation 不可恢复错误:(vmui) 错误代码0xc0000094
软件版本 vmware 17 错误情况 VMware Workstation 不可恢复错误:(vmui) Exception 0xc0000094 has occurred. 问题原因 VMware升级到17.0后,将虚拟机环境的【硬件兼容性】升级至Workstation 17.X后,无法修改设备参数。 解决办法 打开需…...
Python|GIF 解析与构建(5):手搓截屏和帧率控制
目录 Python|GIF 解析与构建(5):手搓截屏和帧率控制 一、引言 二、技术实现:手搓截屏模块 2.1 核心原理 2.2 代码解析:ScreenshotData类 2.2.1 截图函数:capture_screen 三、技术实现&…...

Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动
一、前言说明 在2011版本的gb28181协议中,拉取视频流只要求udp方式,从2016开始要求新增支持tcp被动和tcp主动两种方式,udp理论上会丢包的,所以实际使用过程可能会出现画面花屏的情况,而tcp肯定不丢包,起码…...

Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件
今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议&…...

令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍
文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结: 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析: 实际业务去理解体会统一注…...

NFT模式:数字资产确权与链游经济系统构建
NFT模式:数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新:构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议:基于LayerZero协议实现以太坊、Solana等公链资产互通,通过零知…...

sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!
简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求,并检查收到的响应。它以以下模式之一…...
Go 并发编程基础:通道(Channel)的使用
在 Go 中,Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式,用于在多个 Goroutine 之间传递数据,从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...
【JavaSE】多线程基础学习笔记
多线程基础 -线程相关概念 程序(Program) 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序,比如我们使用QQ,就启动了一个进程,操作系统就会为该进程分配内存…...
【Android】Android 开发 ADB 常用指令
查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...
十九、【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建
【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建 前言准备工作第一部分:回顾 Django 内置的 `User` 模型第二部分:设计并创建 `Role` 和 `UserProfile` 模型第三部分:创建 Serializers第四部分:创建 ViewSets第五部分:注册 API 路由第六部分:后端初步测…...