SpringBoot整合PDF动态填充数据并下载

目录

目录

一、准备环境

二、iTextPDF介绍

三、步骤

四、访问查看结果

五、源代码参考


一、准备环境

①下载一个万兴pdf软件

②准备一个pdf 文件

二、iTextPDF介绍

这是一个用于生成PDF文档的Java库,

文档创建与修改:iTextPDF能够从零开始创建PDF文档,也可以读取已有的PDF文件并对其中的内容进行修改,如添加、删除或更新页面内容。

文本与图像插入:可以在PDF文档中插入文本、图片、图表等内容。

表格制作:支持复杂表格的创建和填充,包括单元格合并、样式设定等。

表单填写与交互:支持创建和填充交互式PDF表单,包括文本字段、复选框、列表框等,并且可以对表单域进行读写操作。

数字签名:提供对PDF文档进行数字签名的支持,确保文档的安全性和完整性。

水印与书签:可以添加文档级别的水印和页眉/页脚,以及创建和编辑PDF书签结构。

PDF拆分与合并:iTextPDF可以用来拆分现有的PDF文件或合并多个PDF文档为一个单一文件。

PDF/A合规性:支持生成符合PDF/A标准的文档,这种格式特别适合长期保存和归档。

iTextPDF历经多个版本迭代,最新的iText 7系列采用了全新的API设计,提高了性能和灵活性。同时,iText也提供了针对.NET平台的版本(iTextSharp),以及其他多种语言的绑定,满足不同开发者的需求。

三、步骤

  • 将pdf以万兴pdf形式打开,点击表单,然后点击添加文本域 在下方添加相应的文本域,相当于前端表单的name属性,后端填充数据的时候要调用文本域(文中的name和tel)。

  • 将这个文件保存后复制到此文件夹下

  • 引入依赖
      <dependency><groupId>com.itextpdf</groupId><artifactId>itext7-core</artifactId><version>7.2.5</version><type>pom</type></dependency>
  •  代码
package com.by.controller;import com.itextpdf.forms.PdfAcroForm;
import com.itextpdf.forms.fields.PdfFormField;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.geom.PageSize;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfReader;
import com.itextpdf.kernel.pdf.PdfWriter;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;/*** 控制器类,用于处理PDF模板填充及下载请求*/
@RestController
public class PdfController {/*** 处理GET请求以下载填充了数据的PDF文件* @param response HttpServletResponse对象,用于设置响应头和发送下载文件* @return 响应实体,包含填充好数据的PDF字节流* @throws IOException 如果读取或写入PDF文件时发生异常*/@GetMapping("/download")public ResponseEntity<byte[]> test(HttpServletResponse response) throws IOException {// 设置响应头,指示浏览器以附件形式下载文件,并设置文件名HttpHeaders headers = new HttpHeaders();headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);String downloadFileName = System.currentTimeMillis() + ".pdf";response.setHeader("Content-Disposition", "attachment;filename=" + downloadFileName);/***  准备需要填充到PDF模板中的数据*  其中name和tel为pdf中插入模板的表单数据*/Map<String, String> dataMap = new HashMap<>();dataMap.put("name", "张三");dataMap.put("tel", "17550635678");// 填充数据并生成带数据的PDF字节流byte[] pdfBytes = getPdf(dataMap);// 创建并返回包含填充后PDF字节流的响应实体return new ResponseEntity<>(pdfBytes, headers, HttpStatus.CREATED);}/*** 根据提供的数据填充PDF模板并返回填充后的PDF字节流** @param dataMap 需要填充到PDF模板中的键值对数据* @return 填充好数据的PDF文件字节数组* @throws IOException 如果读取或写入PDF文件时发生异常*/private byte[] getPdf(Map<String, String> dataMap) throws IOException {// 获取PDF模板文件路径String sourcePdf = ResourceUtils.getURL("classpath:").getPath() + "/templates/2.pdf";// 使用PDF阅读器加载模板文件PdfReader pdfReader = new PdfReader(new FileInputStream(sourcePdf));// 创建一个内存输出流用于存储填充好数据的PDF文件ByteArrayOutputStream outputStream = new ByteArrayOutputStream();// 创建PDF文档对象,连接读取器和输出流PdfDocument pdf = new PdfDocument(pdfReader, new PdfWriter(outputStream));// 设置默认页面大小为A4pdf.setDefaultPageSize(PageSize.A4);// 获取PDF表单域对象PdfAcroForm form = PdfAcroForm.getAcroForm(pdf, true);Map<String, PdfFormField> fields = form.getFormFields();// 设置字体,这里使用的是"STSong-Light"字体PdfFont currentFont = PdfFontFactory.createFont("STSong-Light", "UniGB-UCS2-H", PdfFontFactory.EmbeddingStrategy.PREFER_NOT_EMBEDDED);// 遍历待填充的数据,并将其填入对应的表单域dataMap.forEach((key, value) -> {Optional<PdfFormField> formFieldOptional = Optional.ofNullable(fields.get(key));formFieldOptional.ifPresent(formField -> {// 设置字体并替换表单域的值formField.setFont(currentFont).setValue(value);});});// 锁定并合并所有表单域,使其无法再编辑form.flattenFields();// 关闭PDF文档,释放资源pdf.close();// 将填充好的PDF文件转换为字节数组并返回return outputStream.toByteArray();}
}

四、访问查看结果

http://localhost:8080/download

五、源代码参考

https://codeup.aliyun.com/62858d45487c500c27f5aab5/huang-spring-boot-pdf.git

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

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

相关文章

学习Rust的第11天:模块系统

Rust的模块系统可以使用它来管理不断增长的项目&#xff0c;并跟踪 modules 存储在何处。 Rust的模块系统是将代码组织成逻辑片段的有效工具&#xff0c;因此可以实现代码维护和重用。模块支持分层组织、隐私管理和代码封装。Rust为开发人员提供了多功能和可扩展的方法来管理项…

用 Pytorch 训练一个 Transformer模型

昨天说了一下Transformer架构&#xff0c;今天我们来看看怎么 Pytorch 训练一个Transormer模型&#xff0c;真实训练一个模型是个庞大工程&#xff0c;准备数据、准备硬件等等&#xff0c;我只是做一个简单的实现。因为只是做实验&#xff0c;本地用 CPU 也可以运行。 本文包含…

Vue阶段练习:tab栏、进度条、

阶段练习旨在学习完Vue 指令、计算属性、侦听器-CSDN博客后&#xff0c;进行自我检测&#xff0c;每个练习分为效果显示、需求分析、静态代码、完整代码、总结 四个部分&#xff0c;效果显示和准备代码已给出&#xff0c;我们需要完成“完整代码”部分。 练习1&#xff1a;tab栏…

开源大数据集群部署(二十一)Spark on yarn 部署

作者&#xff1a;櫰木 1 spark on yarn安装&#xff08;每个节点&#xff09; cd /root/bigdata/ tar -xzvf spark-3.3.1-bin-hadoop3.tgz -C /opt/ ln -s /opt/spark-3.3.1-bin-hadoop3 /opt/spark chown -R spark:spark /opt/spark-3.3.1-bin-hadoop32 配置环境变量及修改配…

攻防世界---misc---再见李华

1.下载附件是解压之后得到一张图片 2.使用常规方法后没有得到什么信息&#xff0c;接着用winhex分析&#xff0c;发现有压缩包 &#xff0c;里面还有个key.txt 3.接着用kali使用命名foremost进行分离&#xff0c;得到压缩包&#xff0c;里面的key.txt需要密码 4.接着给压缩包暴…

IDEA代码重构

重构 重构的目的&#xff1a; 提高代码的可读性、可维护性、可扩展性和性能。 重命名元素 重命名类 当我们进行重命名操作的时候可以看到第六行存在一个R(rename)&#xff0c;点击后就会弹出所偶有引用&#xff0c;这样可以避免我们在修改后存在遗漏引用处未修改。 我们可以通过…

管理集群工具之LVS

管理集群工具之LVS 集群概念 将很多机器组织在一起&#xff0c;作为一个整体对外提供服务集群在扩展性、性能方面都可以做到很灵活集群分类 负载均衡集群&#xff1a;Load Balance高可用集群&#xff1a;High Availability高性能计算&#xff1a;High Performance Computing …

模拟网关是什么?

模拟网关是一种网络设备&#xff0c;用于在模拟电话系统和数字网络之间进行信号转换。它的主要作用是将模拟语音信号转换为数字格式&#xff0c;使得这些信号能够通过基于IP&#xff08;互联网协议&#xff09;的网络进行传输&#xff0c;从而实现语音通信。这种设备是将传统的…

Python环境找不到解决方法

Python环境找不到 打开设置&#xff1a;Ctrl Alt S 添加Local Interpreter... 打开System Interpreter&#xff0c;找到本地安装的Python.exe路径&#xff0c;然后一路点OK Trust Project 如果打开工程时&#xff0c;出现如下对话框&#xff0c;请勾选 Trust projects in ...&…

项目管理中,项目团队如何高效的协作与沟通?

目 录 一、项目团队高效的协作与沟通&#xff0c;可以通过以下几个方面来实现&#xff1a; 二、如何在项目团队中明确和共享愿景以提高协作效率&#xff1f; 三、有效的沟通策略在项目管理中的应用案例有哪些&#xff1f; 四、建立哪些具体的沟通机制可以提升团队协作效率…

matlab学习003-绘制由差分方程表示的离散系统图像

目录 1&#xff0c;题目 2&#xff0c;使用函数求解差分方程 1&#xff09;基础知识 ①filter函数和impz函数 ②zeros函数 ☀ 2&#xff09;绘制图像 ​☀ 3&#xff09;对应代码 如果连简单的信号都不会的&#xff0c;建议先看如下文章&#x1f447;&#xff0c;之…

互联网大厂ssp面经,数据结构part2

1. 什么是堆和优先队列&#xff1f;它们的特点和应用场景是什么&#xff1f; a. 堆是一种特殊的树形数据结构&#xff0c;具有以下特点&#xff1a;i. 堆是一个完全二叉树&#xff0c;即除了最后一层外&#xff0c;其他层都是满的&#xff0c;并且最后一层的节点都靠左对齐。i…

SEGGER Embedded Studio IDE移植FreeRTOS

SEGGER Embedded Studio IDE移植FreeRTOS 一、简介二、技术路线2.1 获取FreeRTOS源码2.2 将必要的文件复制到工程中2.2.1 移植C文件2.2.2 移植portable文件2.2.3 移植头文件 2.3 创建FreeRTOSConfig.h并进行配置2.3.1 处理中断优先级2.3.2 configASSERT( x )的处理2.3.3 关于系…

linq select 和selectMany的区别

Select 和 SelectMany 都是 LINQ 查询方法&#xff0c;但它们之间有一些区别。 Select 方法用于从集合中选择特定的属性或对集合中的元素进行转换&#xff0c;并返回一个新的集合。例如&#xff1a; var numbers new List<int> { 1, 2, 3, 4, 5 }; var squaredNumbers…

SRS WebRTC Whip 和 Whep 部署体验问题

whip 報錯 404 webrtc推流 小窗口一闪而过&#xff0c;然后查看f12回复404的报错信息 chrome版本&#xff1a; 正在检查更新 版本 123.0.6312.123&#xff08;正式版本&#xff09; &#xff08;64 位&#xff09; centos 7.9 源码安装部署&#xff0c; 代码分支5.0 完全按…

socket通信基础讲解及示例-C

socket通信之C篇 服务端与客户端简介 socket通信服务端与客户端通信模型通信实战server&#xff08;服务端&#xff09;创建client&#xff08;客户端&#xff09;创建 函数详解创建套接字 socket绑定端口bind进入监听状态listen获取客户端连接请求accept接收网络数据read发送数…

每日一题---移除链表元素

文章目录 前言1.题目2.分析思路3.参考代码 前言 Leetcode–-移除链表元素 1.题目 2.分析思路 首先要创建一个新的链表&#xff0c;在定义三个指针&#xff0c;newHead&#xff0c;newTail和pcur&#xff0c;分别代表新链表头&#xff0c;新链表尾以及用于遍历原链表。 其次是…

Rust入门-所有权

一、为什么、是什么、怎么用 1、为什么Rust要提出一个所有权和借用的概念 所有的程序都必须和计算机内存打交道&#xff0c;如何从内存中申请空间来存放程序的运行内容&#xff0c;如何在不需要的时候释放这些空间&#xff0c;成为所有编程语言设计的难点之一。 主要分为三种…

git merge 和 git rebese的区别

git merge 和 git rebese的区别 拉取分支和合并代码会涉及两种选择&#xff0c;git merge 和 git rebase&#xff1a; rebase&#xff1a;变基&#xff0c;会有一个干净的分支&#xff0c;但是对于记录来源不够清楚merge&#xff1a;合并&#xff0c;git 分支看起来比较混乱&…

CentOS 7虚拟机配置静态IP地址(一)

IP地址的配置 以下几个地址需要记住&#xff0c;在配置中使用 &#xff08;1&#xff09;查看MAC地址&#xff08;点击菜单虚拟机-设置-网络适配器-高级-记住MAC地址&#xff09; &#xff08;2&#xff09;查看子网掩码和网关IP&#xff08;点击菜单编辑-虚拟网络编辑器-选择…