Java 利用pdfbox将图片和成到pdf指定位置
业务背景:用户在手机APP上进行签名,前端将签完名字的图片传入后端,后端合成新的pdf.
废话不多说,上代码:
//控制层代码@PostMapping("/imageToPdf")public Result imageToPdf(@RequestParam("linkName") String name, @RequestParam("file") MultipartFile file) throws IOException {try {String format = LocalDateTimeUtil.format(LocalDateTime.now(), DatePattern.PURE_DATETIME_MS_PATTERN);File f = convertMultipartFileToFile(file);//缩放图片ImgUtil.scale(FileUtil.file(f), FileUtil.file("/hetong/dev/image/" + format + ".png"), 0.06f);// 旋转270度BufferedImage image = (BufferedImage)
//此处利用hutool工具类进行缩放ImgUtil.rotate(ImageIO.read(FileUtil.file("/hetong/dev/image/" + format + ".png")), 270);ImgUtil.write(image, FileUtil.file("/hetong/dev/image/" + format + "_result" + ".png"));String imagePath = "/hetong/dev/image/" + format + "_result" + ".png";String fileUrl = name; // 要下载的文件的HTTPS链接String localFilePath = "/hetong/dev/" + format + ".pdf"; // 下载文件保存到本地的路径和名称//String localFilePath = "D:\\soft\\ceshi\\" + format + ".pdf"; // 下载文件保存到本地的路径和名称downloadFile(fileUrl, localFilePath);String pdfPath = localFilePath;String url = imageToPdfUtil.addImageToPDF(imagePath, pdfPath, format);return new Result(ResultCode.SUCCESS, url);} catch (IOException e) {e.printStackTrace();}return new Result(ResultCode.IMAGE_MERGE_FAILED, "");}//工具类
@Component
public class ImageToPdfUtil {private static Logger logger = LoggerFactory.getLogger(WordUtil.class);@Autowiredprivate UploadManager uploadManager;@Autowiredprivate Auth auth;@Value("${qiniu.bucketName}")private String bucketName;@Value("${qiniu.path}")private String url;/*** 添加图片至pdf指定位置** @param imagePath* @param pdfPath* @throws IOException*/public String addImageToPDF(String imagePath, String pdfPath, String format) throws IOException {// 加载图片PDDocument document = PDDocument.load(new File(pdfPath));PDPage lastPage = document.getPage(document.getNumberOfPages() - 1);PDImageXObject image = PDImageXObject.createFromFile(imagePath, document);// 获取图片宽度和高度float imageWidth = image.getWidth();float imageHeight = image.getHeight();try (PDPageContentStream contentStream = new PDPageContentStream(document, lastPage, PDPageContentStream.AppendMode.APPEND, true, true)) {// 设置图片位置float x = (lastPage.getMediaBox().getWidth() / 2f - imageWidth / 2f) * 0.88f;float y = (lastPage.getMediaBox().getHeight() / 2f - imageHeight / 2f) * 1.5f;// 添加图片到指定位置contentStream.drawImage(image, x, y, imageWidth, imageHeight);}// 保存修改后的 PDFdocument.save(pdfPath);document.close();return uploadQiniu(format);}/*** 上传到七牛云** @param fileName* @return* @throws FileNotFoundException* @throws QiniuException*/public String uploadQiniu(String fileName) throws FileNotFoundException, QiniuException {//这里是上传到服务器路径下的,已经填充完数据的wordFile file = ResourceUtils.getFile("/hetong/dev/" + fileName + ".pdf");//File file = ResourceUtils.getFile("D:\\soft\\ceshi\\" + fileName + ".pdf");//FileInputStream uploadFile = (FileInputStream) file.getInputStream();// 获取文件输入流FileInputStream inputStream = new FileInputStream(file);//这个是已经填充完整的数据后上传至七牛云链接String path = "http://" + upload(inputStream, fileName);logger.info("上传至七牛云的合同路径==path==" + path);return path;}public String upload(FileInputStream file, String fileName) throws QiniuException {String token = auth.uploadToken(bucketName);Response res = uploadManager.put(file, fileName, token, null, null);if (!res.isOK()) {throw new RuntimeException("上传七牛云出错:" + res);}return url + "/" + fileName;}public static void main(String[] args) {try {// 指定原始图片路径File originalImage = new File("D:\\soft\\ceshi\\20230901204201606.png");// 指定压缩后保存的目标路径File compressedImage = new File("D:\\soft\\ceshi\\20230901204201606_result.png");// 压缩和缩放图片Thumbnails.of(originalImage).scale(0.1) // 缩放比例为50%.outputQuality(0.9) // 图片质量为80%.toFile(compressedImage);System.out.println("图片压缩和缩放完成!");} catch (IOException e) {e.printStackTrace();}}/*** MultipartFile 转file** @param multipartFile* @return* @throws IOException*/public static File convertMultipartFileToFile(MultipartFile multipartFile) throws IOException {byte[] fileBytes = multipartFile.getBytes();File tempFile = File.createTempFile("temp", null);try (OutputStream outputStream = new FileOutputStream(tempFile)) {outputStream.write(fileBytes);}return tempFile;}/*** 根号https链接下载文档** @param fileUrl* @param localFilePath* @throws IOException*/public static void downloadFile(String fileUrl, String localFilePath) throws IOException {URL url = new URL(fileUrl);HttpURLConnection connection = (HttpURLConnection) url.openConnection();connection.setRequestMethod("GET");BufferedInputStream inputStream = new BufferedInputStream(connection.getInputStream());FileOutputStream outputStream = new FileOutputStream(localFilePath);byte[] buffer = new byte[1024];int bytesRead;while ((bytesRead = inputStream.read(buffer)) != -1) {outputStream.write(buffer, 0, bytesRead);}outputStream.close();inputStream.close();connection.disconnect();}}
注意:前端传过来的图片必须是透明的,否则合成的时候签名处会有边框
相关文章:
Java 利用pdfbox将图片和成到pdf指定位置
业务背景:用户在手机APP上进行签名,前端将签完名字的图片传入后端,后端合成新的pdf. 废话不多说,上代码: //控制层代码PostMapping("/imageToPdf")public Result imageToPdf(RequestParam("linkName&…...
大数据课程K19——Spark的电影推荐案例推荐系统的冷启动问题
文章作者邮箱:yugongshiye@sina.cn 地址:广东惠州 ▲ 本章节目的 ⚪ 掌握Spark的案例——电影推荐; ⚪ 掌握Spark的模型存储; ⚪ 掌握Spark的模型加载; ⚪ 掌握Spark的推荐系统的冷启动问题; 一、案例——电影推荐 1. 基于用户的推荐 1. 说明 我们现…...

Docker-安装(Linux,Windows)
目录 前言安装版本Docker版本说明前提条件Linux安装使用YUM源部署获取阿里云开源镜像站YUM源文件安装Docker-ce配置Docker Daemon启动文件启动Docker服务并查看已安装版本 使用二进制文件部署 Windows安装实现原理安装步骤基本使用 参考说明 前言 本文主要说明Docker及其相关组…...

若依富文本 html样式 被过滤问题
一.场景 进入页面,富文本编辑框里回显这条新闻内容,如下图, 然后可以在富文本编辑框里对它实现再编辑,编辑之后将html代码提交保存到后台数据库。可以点击详情页进行查看。 出现问题:在提交到后台controller时&#x…...
VS Code 快速消除前置空格和常用快捷键
目录 介绍: 消除前置空格:SHIFTTAB 常用的 VS Code 快捷键 介绍: 在使用 Visual Studio Code (VS Code) 进行代码编辑时,熟练掌握一些快捷键和编辑技巧可以大幅提高开发效率。本文将重点介绍如何使用快捷键 SHIFTTAB 快速消除代…...
【跟小嘉学 Rust 编程】二十五、Rust命令行参数解析库(clap)
系列文章目录 【跟小嘉学 Rust 编程】一、Rust 编程基础 【跟小嘉学 Rust 编程】二、Rust 包管理工具使用 【跟小嘉学 Rust 编程】三、Rust 的基本程序概念 【跟小嘉学 Rust 编程】四、理解 Rust 的所有权概念 【跟小嘉学 Rust 编程】五、使用结构体关联结构化数据 【跟小嘉学…...

gRPC远程进程调用
gRPC远程进程调用 rpc简介golang实现rpc方法一net/rpc库golang实现rpc方法二jsonrpc库grpc和protobuf在一起第一个grpc应用grpc服务的定义和服务的种类grpc stream实例1-服务端单向流grpc stream实例2-客户端单向流grpc stream实例3-双向流grpc整合gin...

什么是继承
提示:继承基础概念 文章目录 一、继承1.1 基础概念1.2 继承作用与继承方式1.2 继承中的隐藏1.3 类中构造、析构在继承方面知识1.4 继承知识拓展 一、继承 1.1 基础概念 继承机制是面向对象程序设计使代码可以复用的最重要的手段,它允许在保持原有类特性…...

QT连接数据库
目录 数据库 数据库基本概念 常用的数据库 SQLite3基础 SQLite特性: QT连接数据库 1.1 QT将数据库分为三个层次 1.2 实现数据库操作的相关方法 sql语句(常用) 1)创建表格 2)删除表格 3)插入记录 …...

navicat访问orcal数据库
1)因为不能直接访问服务器,所以通过中介进行了端口转发; 2)依然不能访问,提示netadmin权限什么错误; 3)下载了一个 PLSQL Developer 13.0.0.1883 版本,自带的instantclient 好像不…...
Linux中查找某路径下,包含某个字符串的所有文件
path表示需要查找的路径,string表示需要包含的字符\字符串 grep -rnw path -e "string"只查找包含特定string的所有.c和.h文件 grep --include\*.{c,h} -rnw -rnw path -e "string" 除去所有.o文件,查找其他文件是否包含特定strin…...
常见信号滤波方法(卡尔曼滤波、滑动平均、异常值剔除)的原理解析与C语言实现
常见信号滤波方法(卡尔曼滤波、滑动平均、异常值剔除)的原理解析与C语言实现 日期作者版本备注2023.09.04Dog TaoV1.0完成文档的初始版本。 文章目录 常见信号滤波方法(卡尔曼滤波、滑动平均、异常值剔除)的原理解析与C语言实现前…...

WebGL模型矩阵
前言:依赖矩阵库 WebGL矩阵变换库_山楂树の的博客-CSDN博客 先平移,后旋转的模型变换: 1.将三角形沿着X轴平移一段距离。 2.在此基础上,旋转三角形。 先写下第1条(平移操作)中的坐标方程式。 等式1&am…...
Flutter:WebSocket封装-实现心跳、重连机制
前言Permalink Flutter简介 Flutter 是 Google推出并开源的移动应用开发框架,主打跨平台、高保真、高性能。开发者可以通过 Dart语言开发 App,一套代码同时运行在 iOS 和 Android平台。 Flutter提供了丰富的组件、接口,开发者可以很快地为 F…...
c语言中:struct timespec
在C语言中,struct timespec 是一个结构体,通常用于处理时间和时间间隔。这个结构体通常包含以下两个成员: tv_sec:这是一个长整型(long),用于存储秒数。它表示时间的整数部分,即秒数…...

Mendix如何实现导出文件
刚刚接触Mendix低代码两周,花了一周在b站看初级视频然后考完初级,第二周开始做个列表查询感觉照葫芦画瓢没啥难度。但最近要求写个导出列表数据,在mendix社区翻了翻,这个功能算是常见的。找了mendix官方提供的Docs磕磕盼盼才实现了…...

在IIS服务器上安装SSL证书(2023配置启用HTTPS部署教程)内容来源SSL市场网
https://www.sslmarket.com.cn/146.html...
如何处理ChatGPT与用户之间的互动和反馈?
处理ChatGPT与用户之间的互动和反馈是关于改进和优化用户体验的关键方面。这涉及到在聊天、对话和交互中建立积极的用户关系,同时利用用户的反馈来不断改进ChatGPT的性能和功能。本文将探讨如何有效地处理ChatGPT与用户之间的互动和反馈,以提供更好的用户…...

微服务-gateway鉴权
文章目录 一、前言二、gateway鉴权1、依赖配置2、编写代码3、GlobalFilter详解3.1、GlobalFilter简介3.2、GlobalFilter自定义执行顺序3.2.1、实现Order接口实现自定义执行顺序 一、前言 网关是介于客户端和服务器端之间的中间层,所有的外部请求都会先经过 网关这一…...

NET7快速开发一个商品管理模块-商品列表开发(一)
商品管理模块,一般包含以下几个模块: 商品列表:这里可以看到所有已发布的商品信息列表。 商品管理:添加商品、编辑商品以及删除商品。 具体功能如下图: 1.商品列表 2.添加商品 3.商品SKU编辑...

SpringBoot-17-MyBatis动态SQL标签之常用标签
文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...
Linux链表操作全解析
Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表?1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...

【网络安全产品大调研系列】2. 体验漏洞扫描
前言 2023 年漏洞扫描服务市场规模预计为 3.06(十亿美元)。漏洞扫描服务市场行业预计将从 2024 年的 3.48(十亿美元)增长到 2032 年的 9.54(十亿美元)。预测期内漏洞扫描服务市场 CAGR(增长率&…...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案
问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...

STM32F4基本定时器使用和原理详解
STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...

cf2117E
原题链接:https://codeforces.com/contest/2117/problem/E 题目背景: 给定两个数组a,b,可以执行多次以下操作:选择 i (1 < i < n - 1),并设置 或,也可以在执行上述操作前执行一次删除任意 和 。求…...
【算法训练营Day07】字符串part1
文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接:344. 反转字符串 双指针法,两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...
C++中string流知识详解和示例
一、概览与类体系 C 提供三种基于内存字符串的流,定义在 <sstream> 中: std::istringstream:输入流,从已有字符串中读取并解析。std::ostringstream:输出流,向内部缓冲区写入内容,最终取…...
根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:
根据万维钢精英日课6的内容,使用AI(2025)可以参考以下方法: 四个洞见 模型已经比人聪明:以ChatGPT o3为代表的AI非常强大,能运用高级理论解释道理、引用最新学术论文,生成对顶尖科学家都有用的…...
浅谈不同二分算法的查找情况
二分算法原理比较简单,但是实际的算法模板却有很多,这一切都源于二分查找问题中的复杂情况和二分算法的边界处理,以下是博主对一些二分算法查找的情况分析。 需要说明的是,以下二分算法都是基于有序序列为升序有序的情况…...