当前位置: 首页 > news >正文

java导出pdf文件

java导出pdf,前端下载

    • 1、制作pdf模板
    • 2、获取pdf导出中文需要的文件
    • 3、实现
    • 4、前端发起请求并生成下载链接

使用注意点
因为原来制作的pdf表单内容过于复杂,下面代码只包含前两行的操作。
本次操作需要前端向后端发起请求,后端返回数据给前端用于下载,所以没有在本地进行保存。
第 1 步制作pdf模板需要的pdf编辑软件基本上都需要钱,可以去买一个
第 2 步获取的pdf导出的中文需要的文件,如果pdf输出的内容有中文就需要去弄一下这个文件,在代码中用于读取设置中文字体

包含内容
1、导出pdf
2、设置斜体水印

1、制作pdf模板

先将需要的pdf模板通过word制作出来,然后导出为pdf
先准备一个pdf
使用Adobe Acrobat DC 打开并制作模板(其他pdf编辑软件也可以)
在这里插入图片描述
选择打开前面导出的pdf模板
在这里插入图片描述
点击准备表单
在这里插入图片描述
点击之后,可以针对没一个位置进行编辑,选中双击就可以进行编辑了,要注意,每个位置的名字都需要是唯一的
在这里插入图片描述
全部赋值后保存即可

2、获取pdf导出中文需要的文件

获取中文字体需要的文件
在这里插入图片描述
在电脑这个路径下选择下载一个就行
在这里插入图片描述

3、实现

pom依赖

<dependency><groupId>com.itextpdf</groupId><artifactId>itext7-core</artifactId><version>7.2.3</version><type>pom</type>
</dependency><dependency><groupId>org.apache.pdfbox</groupId><artifactId>pdfbox</artifactId><version>2.0.24</version>
</dependency>

controller接口

    @GetMapping("/exportPDF/{applyId}")public ResponseEntity<byte[]> exportPDF(@PathVariable("applyId") String applyId, HttpServletResponse response) throws IOException,ParseException,Exception {byte[] res = applyService.exportPDF(applyId);HttpHeaders headers = new HttpHeaders();headers.add("Content-Disposition", "attachment; filename=filled_form.pdf");headers.add("Content-Type", "application/pdf");return ResponseEntity.ok().headers(headers).body(res);}

service具体实现

	public static byte[] exportPDF1() throws Exception {String inputTemplateName = "template";try {pdfBytes = null;Map<String, String> map = new HashMap<>();SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");// map预填数据,用于后面读取输出到pdf文件上map.put("department-1", "研发中心");map.put("submitDate-1", sdf.format(new Date()));map.put("submitPerson-1", "张三");map.put("travelPerson-1", "李四");map.put("receivePerson-1","王五");// 设置中文字体PdfFont chineseFont = PdfFontFactory.createFont("src/main/resources/file/simsun.ttc,0");// 模板路径String templatePath = "src\\main\\resources\\file\\" + inputTemplateName + ".pdf";// 重点,这一个关联了reader 和 writerByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();// 读取文件FileInputStream pdfInputStream = new FileInputStream(new File(templatePath));// 定义 reader 和writerPdfReader reader = new PdfReader(pdfInputStream);PdfWriter writer = new PdfWriter(byteArrayOutputStream,new WriterProperties().setStandardEncryption(null,null,EncryptionConstants.ALLOW_PRINTING, // 允许打印EncryptionConstants.ENCRYPTION_AES_128 // 加密方式));// 根据 reader 和writer 创建 PdfDocumentPdfDocument pdfDocument = new PdfDocument(reader,writer);// 下面是给文件添加水印,不需要的可以直接删掉// 获取 pdf 模板页数int numberOfPages = pdfDocument.getNumberOfPages();// 遍历每一页并添加水印for (int i = 1; i <= numberOfPages; i++) {PdfPage page = pdfDocument.getPage(i);// 获取页面尺寸(在这里我没有用)int pageWidth = (int) Math.floor(page.getPageSize().getWidth());int pageHeight = (int) Math.floor(page.getPageSize().getHeight());// 创建一个 PdfCanvas 对象PdfCanvas canvas = new PdfCanvas(page);// 保存当前坐标系状态canvas.saveState();// 水印内容旋转double angle = Math.toRadians(45);double cos = Math.cos(angle);double sin = Math.sin(angle);canvas.concatMatrix(cos, sin, -sin, cos, 0, 0);// 设置水印的字体和透明度canvas.setFontAndSize(PdfFontFactory.createFont(), 20);canvas.setFillColorRgb(0.75f, 0.75f, 0.75f);  // 灰色canvas.setLineWidth(2);// 正常应该根据获取到的页面尺寸进行 x y 轴的遍历并// 但是我这边没有铺满,就自己设置了遍历的范围for (int x = -90; x < 2000; x += 300) {for (int y = -190; y < 2000; y += 200) {// 绘制水印文字canvas.beginText();canvas.setTextMatrix(x, y);  // 设置水印位置canvas.showText("Watermark Text this is just a test");  // 水印文字内容canvas.endText();}}// 恢复坐标系状态canvas.restoreState();}// form 可以理解为把pdf文件看做一个form表单,以key value键值对保存PdfAcroForm form = PdfAcroForm.getAcroForm(pdfDocument, true);// 遍历上面预填的 map 并将值根据 key 赋值到formfor (Map.Entry<String, String> entry : map.entrySet()) {form.getField(entry.getKey()).setValue(entry.getValue());form.getField(entry.getKey()).setFont(chineseFont).setFontSize(8);}pdfDocument.close();// 返回文件流pdfBytes = byteArrayOutputStream.toByteArray();return pdfBytes;} catch (Exception e) {e.printStackTrace();}finally {return pdfBytes;}}

4、前端发起请求并生成下载链接

	exportPdf(applyId) {exportPDF(applyId).then(res => {// 创建一个 Blob 对象,指定类型为 PDF 文件const blob = new Blob([res.data], { type: 'application/pdf' });// 创建一个 URL 对象,指向 Blob 数据const url = URL.createObjectURL(blob);// 创建一个下载链接const link = document.createElement('a');link.href = url;link.download = 'generated_with_form.pdf'; // 设置下载文件名// 模拟点击下载链接link.click();// 下载完成后释放 URL 对象URL.revokeObjectURL(url);})},

相关文章:

java导出pdf文件

java导出pdf&#xff0c;前端下载 1、制作pdf模板2、获取pdf导出中文需要的文件3、实现4、前端发起请求并生成下载链接 使用注意点 因为原来制作的pdf表单内容过于复杂&#xff0c;下面代码只包含前两行的操作。 本次操作需要前端向后端发起请求&#xff0c;后端返回数据给前端…...

【MySQL学习笔记】MySQL视图View

视图View 1、视图的基础语法2、检查选项3、视图的更新4、视图的作用 视图&#xff08;View&#xff09;是一种虚拟存在的表。视图中的数据并不在数据库中实际存在&#xff0c;行和列数据来自定义视图的查询中使用的表&#xff0c;并且是在使用视图时动态生成的。 通俗的讲&…...

从玩具到工业控制--51单片机的跨界传奇【2】

咱们在上一篇博客里面讲解了什么是单片机《单片机入门》&#xff0c;让大家对单片机有了初步的了解。我们今天继续讲解一些有关单片机的知识&#xff0c;顺便也讲解一下我们单片机用到的C语言知识。如果你对C语言还不太了解的话&#xff0c;可以看看博主的C语言专栏哟&#xff…...

【Redis】初识Redis

目录 Redis简介 Redis在内存中存储数据 Redis数据库中的应用 Redis缓存中的应用 Redis消息中间件 尾言 Redis简介 如下是Redis官网中&#xff0c;对Redis的一段描述 在这段描述中&#xff0c;我们提取如下关键要点&#xff1a; Redis主要用于在内存中存储数据Redis可…...

docker虚拟机平台未启用问题

在终端中输入如下代码&#xff0c;重启电脑即可 Enable-WindowsOptionalFeature -Online -FeatureName VirtualMachinePlatform 对于Docker Desktop - Unexpected WSL error问题 参考链接 解决WSL2与docker冲突问题...

《零基础Go语言算法实战》【题目 2-22】Go 调度器优先调度问题

《零基础Go语言算法实战》 【题目 2-22】Go 调度器优先调度问题 下面代码的输出是什么&#xff1f;请说明原因。 package main import ( "fmt" "runtime" "sync" ) func main() { runtime.GOMAXPROCS(1) wg : sync.WaitGroup{} wg.Add(10)…...

关于使用FastGPT 摸索的QA

近期在通过fastGPT&#xff0c;创建一些基于特定业务场景的、相对复杂的Agent智能体应用。 工作流在AI模型的基础上&#xff0c;可以定义业务逻辑&#xff0c;满足输出对话之外的需求。 在最近3个月来的摸索和实践中&#xff0c;一些基于经验的小问题点&#xff08;自己也常常…...

关于H5复制ios没有效果

问题场景&#xff1a;今天遇到这样一个问题&#xff0c;需要从后端接口获取到的值进行复制&#xff0c;且不能提现调用获取值&#xff0c;因为是一个数据列表&#xff0c;每个列表元素需要当场点击调用接口获取值进行复制&#xff0c;本来以为很简单的一个需求&#xff0c;当做…...

【STM32-学习笔记-3-】TIM定时器

文章目录 TIM定时器Ⅰ、TIM定时器函数Ⅱ、TIM_TimeBaseInitTypeDef结构体参数①、TIM_ClockDivision②、TIM_CounterMode③、TIM_Period④、TIM_Prescaler⑤、TIM_RepetitionCounter Ⅱ、定时器配置Ⅲ、定时器外部中断NVIC配置 TIM定时器 Ⅰ、TIM定时器函数 // 将定时器寄存器…...

EMS专题 | 守护数据安全:数据中心和服务器机房环境温湿度监测

您需要服务器机房温度监测解决方案吗&#xff1f; 服务器机房是企业中用于存储、管理和维护服务器及其相关组件的设施。服务器机房通常位于数据中心内&#xff0c;是一个专门设计的物理环境&#xff0c;旨在确保服务器的稳定运行和数据的安全性。服务器机房主要起到存储和管理数…...

Vue JavaScript 小写数字金额转换成大写汉字(附编程思路)

一、编程思路&#xff08;本案例只考虑9999万亿以内的数字转换&#xff0c;相信这个金额对于人民币来说已经足够庞大了&#xff0c;超过此数值的金额不保证转换汉字的准确性&#xff0c;且最多精确到小数点后四位&#xff09;&#xff1a; 1、将示例&#xff08;不管是…...

【自动化测试】—— Appium安装配置保姆教程(图文详解)

目录 一. 环境准备 二. JDK安装 1. 下载JDK 2. 安装JDK 3. 配置环境 4. 验证安装 三. Android SDK安装 1. 下载Android SDK 2. 安装Android SDK 3. 安装工具 4. 配置环境 5. 验证安装 四. NodeJS安装 1. 下载NodeJS 2. 安装NodeJS 3. 验证安装 4. 安装淘宝镜像…...

贪心算法详细讲解(沉淀中)

文章目录 1. 什么是贪心算法&#xff1f;&#xff08;贪婪鼠目寸光&#xff09;经典例题1.1.1 找零问题1.1.2最小路径和1.1.3 背包问题 2.贪心算法的特点2.1 证明例1 3.学习贪心的方向心得体会 1. 什么是贪心算法&#xff1f;&#xff08;贪婪鼠目寸光&#xff09; 贪心策略&a…...

RabbitMQ中有哪几种交换机类型?

大家好&#xff0c;我是锋哥。今天分享关于【RabbitMQ中有哪几种交换机类型&#xff1f;】面试题。希望对大家有帮助&#xff1b; RabbitMQ中有哪几种交换机类型&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 在RabbitMQ中&#xff0c;交换机&#xf…...

STM32特殊功能引脚详解文章·STM32特殊功能引脚能当作GPIO使用嘛详解!!!

目录 STM32特殊功能引脚 使用STM32特殊功能引脚函数 禁止搬运&#xff0c;仅供学习&#xff0c;编写不易&#xff0c;感谢理解&#xff01;&#xff01;&#xff01; STM32特殊功能引脚 本篇详解文章仅以STM32F103C8T6芯片来讲解&#xff0c;STM32芯片除了普通的GPIO引脚以外…...

Qt QComboBox的QSS美化

美化效果 QSS设置 /*QComboBox风格设置*/ QComboBox#comboBox_1 { border:2px solid #f3f3f3;/*设置边框线宽*/ background-color:rgb(237, 242, 255);/*背景颜色*/ border-radius:5px;/*圆角*/ padding: 1px 2px 1px 2px;/*针对组合框中的文本内容*/ min-width:2em;/*组合框…...

计算机视觉算法实战——实时车辆检测和分类(主页有相关源码)

✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连✨ ​ ​​​​​​​​​​​​​​​​​​ 1. 领域介绍✨✨ 实时车辆检测和分类是计算机视觉中的一个重要应用领域&#xff0c;旨在从视频流或…...

what?ngify 比 axios 更好用,更强大?

文章目录 前言一、什么是ngify&#xff1f;二、npm安装三、发起请求3.1 获取 JSON 数据3.2 获取其他类型的数据3.3 改变服务器状态3.4 设置 URL 参数3.5 设置请求标头3.6 与服务器响应事件交互3.7 接收原始进度事件3.8 处理请求失败3.9 Http Observables 四、更换 HTTP 请求实现…...

安装虚拟机VMware遇到的问题

问题1&#xff1a;进入如下界面&#xff0c;不知道如何操作 解决办法 键盘⬇️&#xff0c;选择“Reset the system”回车 问题2&#xff1a;系统存放位置我给放在了VMware安装目录&#xff0c;具体D:\software\VMware\Windows安装不行 解决办法&#xff1a;D:\software\virt…...

通过ESP32和INMP441麦克风模块实现音频数据传递

在现代物联网&#xff08;IoT&#xff09;项目中&#xff0c;音频数据的采集与传输成为了一个热门的应用领域。通过结合ESP32开发板和INMP441麦克风模块&#xff0c;我们可以实现一个低成本、高效率的音频数据传输系统。本文将详细介绍如何使用这两种硬件组件来构建和测试音频传…...

管理学院权限管理系统开发总结

文章目录 &#x1f393; 管理学院权限管理系统开发总结 - 现代化Web应用实践之路&#x1f4dd; 项目概述&#x1f3d7;️ 技术架构设计后端技术栈前端技术栈 &#x1f4a1; 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 &#x1f5c4;️ 数据库设…...

深度学习水论文:mamba+图像增强

&#x1f9c0;当前视觉领域对高效长序列建模需求激增&#xff0c;对Mamba图像增强这方向的研究自然也逐渐火热。原因在于其高效长程建模&#xff0c;以及动态计算优势&#xff0c;在图像质量提升和细节恢复方面有难以替代的作用。 &#x1f9c0;因此短时间内&#xff0c;就有不…...

C#学习第29天:表达式树(Expression Trees)

目录 什么是表达式树&#xff1f; 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持&#xff1a; 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...

Go语言多线程问题

打印零与奇偶数&#xff08;leetcode 1116&#xff09; 方法1&#xff1a;使用互斥锁和条件变量 package mainimport ("fmt""sync" )type ZeroEvenOdd struct {n intzeroMutex sync.MutexevenMutex sync.MutexoddMutex sync.Mutexcurrent int…...

BLEU评分:机器翻译质量评估的黄金标准

BLEU评分&#xff1a;机器翻译质量评估的黄金标准 1. 引言 在自然语言处理(NLP)领域&#xff0c;衡量一个机器翻译模型的性能至关重要。BLEU (Bilingual Evaluation Understudy) 作为一种自动化评估指标&#xff0c;自2002年由IBM的Kishore Papineni等人提出以来&#xff0c;…...

django blank 与 null的区别

1.blank blank控制表单验证时是否允许字段为空 2.null null控制数据库层面是否为空 但是&#xff0c;要注意以下几点&#xff1a; Django的表单验证与null无关&#xff1a;null参数控制的是数据库层面字段是否可以为NULL&#xff0c;而blank参数控制的是Django表单验证时字…...

用鸿蒙HarmonyOS5实现中国象棋小游戏的过程

下面是一个基于鸿蒙OS (HarmonyOS) 的中国象棋小游戏的实现代码。这个实现使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chinesechess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├──…...

C++_哈希表

本篇文章是对C学习的哈希表部分的学习分享 相信一定会对你有所帮助~ 那咱们废话不多说&#xff0c;直接开始吧&#xff01; 一、基础概念 1. 哈希核心思想&#xff1a; 哈希函数的作用&#xff1a;通过此函数建立一个Key与存储位置之间的映射关系。理想目标&#xff1a;实现…...

QT开发技术【ffmpeg + QAudioOutput】音乐播放器

一、 介绍 使用ffmpeg 4.2.2 在数字化浪潮席卷全球的当下&#xff0c;音视频内容犹如璀璨繁星&#xff0c;点亮了人们的生活与工作。从短视频平台上令人捧腹的搞笑视频&#xff0c;到在线课堂中知识渊博的专家授课&#xff0c;再到影视平台上扣人心弦的高清大片&#xff0c;音…...

游戏开发中常见的战斗数值英文缩写对照表

游戏开发中常见的战斗数值英文缩写对照表 基础属性&#xff08;Basic Attributes&#xff09; 缩写英文全称中文释义常见使用场景HPHit Points / Health Points生命值角色生存状态MPMana Points / Magic Points魔法值技能释放资源SPStamina Points体力值动作消耗资源APAction…...