Java实现图片保存到pdf的某个位置

Java实现图片保存到pdf的某个位置

1、依赖–maven
        <dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.5.13</version></dependency>
2、上代码
package com.hxlinks.hxiot.controller;import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfImportedPage;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;import java.awt.geom.Point2D;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.Base64;@Controller
public class PdfApiController {@PostMapping("/api/save-image-to-pdf")public ResponseEntity<String> saveImageToPdf(@RequestBody JsonNode jsonNode) {try {// 解析前端传来的JSON数据int pageNumber = jsonNode.get("pageNumber").asInt();Point2D.Float position = new Point2D.Float(jsonNode.get("imagePosition").get("x").floatValue(), jsonNode.get("imagePosition").get("y").floatValue());String base64Image = jsonNode.get("base64Image").toString();// 将Base64编码的图片转换为字节数组byte[] imageBytes = Base64.getDecoder().decode(base64Image.split(",")[1]);// 假设有一个默认的PDF文件路径File originalPdf = new File("D:\\templateFilePath\\测试.pdf");File tempPdf = File.createTempFile("temp", ".pdf");// 使用iText处理PDFinsertImageIntoPdf(originalPdf, tempPdf, pageNumber, position, imageBytes);// 下载处理后的PDF到D盘downloadPdf(tempPdf, "modified_pdf_page_" + pageNumber + ".pdf");return ResponseEntity.ok("图片已成功添加到PDF并保存到D盘。");} catch (IOException | DocumentException e) {e.printStackTrace();return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("处理PDF时出错。");}}private void insertImageIntoPdf(File originalPdf, File tempPdf, int pageNumber, Point2D.Float position, byte[] imageBytes) throws IOException, DocumentException {PdfReader reader = new PdfReader(new FileInputStream(originalPdf));PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(tempPdf));PdfContentByte canvas = stamper.getOverContent(pageNumber);Image img = Image.getInstance(imageBytes);img.setAbsolutePosition(position.x, position.y);img.scaleToFit(100, 100); // 示例:调整图片大小,根据需要调整canvas.addImage(img);stamper.close();reader.close();}private void downloadPdf(File tempPdf, String fileName) throws IOException {Path sourcePath = tempPdf.toPath();Path targetDir = Paths.get("D:/");Path targetPath = targetDir.resolve(System.currentTimeMillis() + ".pdf");// 检查目标文件是否已存在,根据需求决定是否覆盖或提示错误if (Files.exists(targetPath)) {// 这里可以根据实际情况选择抛出异常、覆盖文件或修改文件名throw new IOException("目标文件已存在:" + targetPath);// 或者// Files.delete(targetPath); // 如果决定覆盖,则先删除原有文件}// 确保目标目录存在Files.createDirectories(targetDir);// 执行移动操作Files.move(sourcePath, targetPath, StandardCopyOption.REPLACE_EXISTING); // REPLACE_EXISTING 用于允许覆盖已存在的文件}}
3、jsonNode参数,根据需要调整
{"pageNumber":2,//pdf页码数"base64Image":"data:image/png;base64,i...................",//base64"imagePosition":{//在pdf中的坐标,左下角为(0,0)"x":100,"y":0},"imageSize":{//在pdf中的图片大小"width":100,"height":100}
}

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

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

相关文章

【OCPP】ocpp1.6协议第3.16章节Metering Data介绍及翻译

目录 3.16. Metering Data计量数据-概述 计量数据的目的 关键功能 消息类型 MeterValues 消息格式 使用场景 计量数据的准确性和可靠性 总结 3.16. Metering Data计量数据-译文 3.16.1. Charging Session Meter Values 3.16.2. Clock-Aligned Meter Values 3.16.3.…

【JavaScript】call、apply、bind的区别和应用

历史小剧场 其实在大多数时间里&#xff0c;除去超人、蝙蝠侠等不可抗力出来维护正义外&#xff0c;邪是经常胜正的。所谓好人、善人、老实人常常被整得凄惨无比&#xff0c;比如于谦、岳飞等&#xff0c;都是死后很多年才翻身平反。 只有岁月的沧桑&#xff0c;才能淘尽一切污…

【Vue】自动导入组件

1. 下载插件 npm install unplugin-vue-components 2. 修改vite.config.js import { fileURLToPath, URL } from node:urlimport { defineConfig } from vite import vue from vitejs/plugin-vue import Components from unplugin-vue-components/vite // 按需加载自定义组件/…

C#中的事件聚合器实现方法

概述&#xff1a;_对象之间的关系_是使代码库难以理解和难以维护的原因。为了更好地理解它&#xff0c;我们求助于马丁福勒&#xff08;Martin Fowler&#xff09;&#xff1a;事件聚合器是间接的简单元素。在最简单的形式中&#xff0c;您可以让它注册到您感兴趣的所有源对象&…

MapStruct与BeanUtils处理对象属性复制场景对比

MapStruct是什么&#xff1f; MapStruct is a code generator that greatly simplifies the implementation of mappings between Java bean types based on a convention over configuration approach. The generated mapping code uses plain method invocations and thus is…

elastich运维

Elastichsearch是一种高度可扩展的开源全文搜索和分析引擎&#xff0c;可以用来实现快速、高效的数据检索。 集群规划与部署&#xff1a;首先需要根据业务需求规划Elastichsearch集群的节点数量和角色&#xff08;如主节点、副本节点、协调节点等&#xff09;。在部署时&#x…

赎金信-力扣

这道题想到的解法是使用一个哈希表来存储magazine里每个字符出现的次数&#xff0c;然后遍历ransomNote&#xff0c;出现对应的字母则哈希表中对应的值减一&#xff0c;当查找不到某个字符&#xff0c;或者某个字符的值小于0时&#xff0c;则返回false。代码如下&#xff1a; …

ORACLE中递归遍历

--查询全部资源信息 select * from urm_class_info --向上遍历树&#xff0c;找到路径直到根节点&#xff0c;指定的是parentid select distinct classid, parentid, namefrom urm_class_infostart with parentid cmdb0000000000000017 connect by prior parentid classid …

配置Spring Security的身份验证

配置Spring Security的身份验证 在我们登录Spring Security之前&#xff0c;我们将向您展示如何配置Spring Security的身份验证。我们将通过创建一些用户来验证并为它们生成身份验证。在这篇文章中&#xff0c;我们将学习Spring Security的流程是配置Spring Security中的身份验…

代码随想录算法训练营第二十一天 | 530.二叉搜索树的最小绝对差、501.二叉搜索树中的众数、236. 二叉树的最近公共祖先

530.二叉搜索树的最小绝对差 题目链接&#xff1a;https://leetcode.cn/problems/minimum-absolute-difference-in-bst/ 文档讲解&#xff1a;https://programmercarl.com/0530.%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91%E7%9A%84%E6%9C%80%E5%B0%8F%E7%BB%9D%E5%AF%B9%E…

VMware Workstation 不可恢复错误:(vmui) 错误代码0xc0000094

软件版本 vmware 17 错误情况 VMware Workstation 不可恢复错误&#xff1a;(vmui) Exception 0xc0000094 has occurred. 问题原因 VMware升级到17.0后&#xff0c;将虚拟机环境的【硬件兼容性】升级至Workstation 17.X后&#xff0c;无法修改设备参数。 解决办法 打开需…

企业营收分析难?搞定收入认领月底不加班!

在当今日益激烈的市场竞争中&#xff0c;企业的营收分析不仅是衡量经营成果的关键指标&#xff0c;更是指导企业未来发展的重要依据。然而&#xff0c;对于许多企业来说&#xff0c;营收分析的过程往往繁琐且耗时&#xff0c;尤其是月底结账时&#xff0c;大量的数据和复杂的计…

【Numpy】NumPy基础入门:创建和管理多维数组

NumPy基础入门&#xff1a;创建和管理多维数组 简介 NumPy&#xff08;Numerical Python的简称&#xff09;是Python语言的一个基础科学计算库&#xff0c;广泛应用于数据分析、机器学习、科学计算和工程领域。NumPy的核心是其强大的N维数组对象ndarray&#xff0c;它为Pytho…

医疗图像处理2023:Transformers in medical imaging: A survey

医学成像中的transformer:综述 目录 一、介绍 贡献与安排 二、CNN和Transformer 1.CNN 2.ViT 三、Transformer应用于各个领域 1.图像分割 1&#xff09;器官特异性 ①2D ②3D 2&#xff09;多器官类别 ①纯transformer ②混合架构 单尺度 多尺度 3&#xff09;…

fyne表单布局

fyne表单布局 layout.FormLayout就像一个 2 列网格布局 。 package mainimport ("image/color""fyne.io/fyne/v2/app""fyne.io/fyne/v2/canvas""fyne.io/fyne/v2/container""fyne.io/fyne/v2/layout" )func main() {myApp…

electron 如何升级版本

electron-updater使用指南 基础 检测是否最新版 autoUpdater.checkForUpdates() 下载最新版 autoUpdater.downloadUpdate() 项目使用 update.js const { ipcMain } require(electron) const { autoUpdater } require(electron-updater) const path require("pa…

Wpf 使用 Prism 实战开发Day27

首页汇总和数据动态显示 一.创建首页数据汇总数据接口 汇总&#xff1a;待办事项的总数已完成&#xff1a;待办事项里面有多少条完成的待办完成比例&#xff1a;已完成和汇总之间的比例备忘录&#xff1a;显示备忘录的总数待办事项&#xff1a;显示待办事项未完成的集合备忘录&…

②单细胞学习-组间及样本细胞比例分析

目录 数据读入 每个样本各细胞比例 两个组间细胞比例 亚组间细胞比例差异分析&#xff08;循环&#xff09; 单个细胞类型亚新间比例差异 ①单细胞学习-数据读取、降维和分群-CSDN博客 比较各个样本间的各类细胞比例或者亚组之间的细胞比例差异 ①数据读入 #各样本细胞…

三、Ollama导入大模型(.Net8+SemanticKernel+Ollama)本地运行自己的大模型

Ollama导入大模型 一、导入Ollama大模型1、使用run命令2、使用Modelfile方式 二、导入自定义大模型&#xff08;Ollama官网以外的大模型&#xff09;三、使用OpenWebUI导入大模型 Ollama可以导入官方提供的大模型&#xff0c;也可以导入huggingface上的自定义大模型&#xff08…

【加密与解密(第四版)】第十四章笔记

第十四章 漏洞分析技术 14.1 软件漏洞原理 缓冲区溢出漏洞&#xff1a;栈溢出 堆溢出、整型溢出&#xff08;存储溢出、计算溢出、符号问题&#xff09; UAF&#xff08;Use-After-Free&#xff09;漏洞 14.2 ShellCode 功能模块&#xff1a;下载执行、捆绑、反弹shell 14.3 …