Java使用pdf模板生成pdf文件

news2024/11/16 17:59:43

文章目录

  • 前言
  • 如何生成pdf文件
    • 1. 制作pdf模板
    • 2. 填充pdf模板生成文件

前言

有时候,业务中我们需要使用pdf模板生成一份pdf文件。如何生成pdf文件?
如下,我们把左侧的模板生成为右侧的填充文件。

在这里插入图片描述

如何生成pdf文件

1. 制作pdf模板

(1)首先创建一份template.docx文件,另存为template.pdf
在这里插入图片描述
(2) 打开pdf阅读器,点击 创建>> 表单 >> 从文件,选择刚刚的template.pdf文件

这里使用的福昕PDF编辑器阅读器,其它能编辑pdf的软件亦可(Adobe Acrobat DC)

在这里插入图片描述
(3) 选择表单>>文本域,双击待填充的位置,填写名称,最后保存得到pdf的模板。

在这里插入图片描述
在这里插入图片描述

2. 填充pdf模板生成文件

  1. 导入依赖
<dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itextpdf</artifactId>
            <version>5.5.13</version>
        </dependency>
  1. 测试用例填充word模板
package com.it2.pdfdemo;

import com.itextpdf.text.BadElementException;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.*;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 使用pdf模板生成pdf文件
 */
@SpringBootTest
@Slf4j
class PdfdemoApplicationTests {

    @Test
    void testPdf() {
        String inputFileName = "D:\\test\\template6.pdf";//模板
        String outputFileName = "D:\\test\\template6_out.pdf";//生成文件

        // 填充表单的数据(文本)
        Map<String, Object> data = new HashMap<String, Object>();
        data.put("name", "王多余");
        data.put("birthday", "2001-12-23");
        data.put("sex", "男");
        data.put("address", "北京市朝阳区和平路101号");
        data.put("phone", "13600000000");

        // 填充表单的数据(图片)
        Map<String, String> picData = new HashMap<>();
        picData.put("pic", "D:\\test\\dog.png");

        OutputStream os = null;
        PdfStamper ps = null;
        PdfReader reader = null;
        try {
            // 1 获取文件的输出流
            os = new FileOutputStream(new File(outputFileName));
            // 2 读取pdf模板
            reader = new PdfReader(inputFileName);
            // 3 根据表单生成一个新的pdf
            ps = new PdfStamper(reader, os);
            // 4 获取pdf表单
            AcroFields form = ps.getAcroFields();
            // 5 给表单添加中文字体
            BaseFont bf = BaseFont.createFont("Font/SIMYOU.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
            form.addSubstitutionFont(bf);

            // 6遍历data赋值到form
            for (String key : data.keySet()) {
                form.setField(key, data.get(key).toString());
            }
            ps.setFormFlattening(true);

            // 7 填充图片到form
            PdfStamper stamper = ps;
            picData.forEach((fieldName, imgSrc) -> {
                try {
                    List<AcroFields.FieldPosition> fieldPositions = form.getFieldPositions(fieldName);
                    for (AcroFields.FieldPosition fieldPosition : fieldPositions) {
                        // 通过域名获取所在页和坐标,左下角为起点
                        int pageno = fieldPosition.page;
                        Rectangle signrect = fieldPosition.position;
                        float x = signrect.getLeft();
                        float width = signrect.getWidth();
                        float y = signrect.getBottom();
                        // 读图片
                        Image image = Image.getInstance(imgSrc);
                        float img_width = image.getWidth();
                        // 获取操作的页面
                        PdfContentByte under = stamper.getOverContent(pageno);
                        // 图片的大小
                        image.scaleToFit(signrect.getWidth(), signrect.getHeight());
                        // 添加图片
                        image.setAbsolutePosition(x, y);
                        under.addImage(image);
                    }
                } catch (BadElementException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (DocumentException e) {
                    e.printStackTrace();
                }
            });

            log.info("生成pdf成功:{}", outputFileName);
        } catch (Exception e) {
            log.error("生成pdf失败:{}", outputFileName);
            e.printStackTrace();
        } finally {
            try {
                ps.close();
                reader.close();
                os.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

}
  1. 引入字体文件(示例为 SIMYOU.TTF),存在位置resources\Font目录下,demo使用的字体文件为简体幼圆常规

提示:由于部分字体存在可能的商业侵权问题,如您在商业使用,建议使用非侵权字体,或者事先已获取所使用的字体授权

在这里插入图片描述
在这里插入图片描述

  1. 运行测试用例结果
    在这里插入图片描述

在这里插入图片描述

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

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

相关文章

【Linux】C++项目实战-UDP服务器

目录 UDP通信函数解析代码举例 广播函数解析代码举例 橙色 UDP通信 函数解析 #include <sys/types.h> #include <sys/socket.h> ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);- 参…

避雷器在线测试仪

一、产品概述 KDYZ-306氧化锌避雷器带电测试仪是用于检测氧化锌避雷器电气性能的专用仪器&#xff0c;该仪器适用于各种电压等级的氧化锌避雷器的带电或停电检测&#xff0c;从而及时发现设备内部绝缘受潮及阀片老化等危险缺陷。 仪器操作简单、使用方便&#xff0c;测量全过…

创建固定大小的文件(window 和 UBUNTU)

1、Windows Windows提供了一个强大的文件系统管理工具&#xff1a;fsutil.exe 例&#xff0c;在D盘上创建一个空文件file.txt&#xff0c;文件大小10k字节 fsutil file createnew D:\file.txt 1000 2、Ubuntu Ubuntu创建一个指定大小的文件用全零填充这个文件&#xff0c;例…

vue3 elementplus table合并

table表格下方合并写法&#xff1a; 1&#xff1a;单行合并 &#xff08;1&#xff09;在标签中加入属性 :summary-method"getSummaries":show-summary"true"<el-table:data"data"id"tableRef"ref"tableRef"row-key"…

CentOS Stream 10 计划已启动,即将进入初始化阶段

导读 但初始化的 CentOS Stream 10 暂时不会对外开放&#xff0c;也不会有太多活跃信息。从 Fedora 周期的规律来看&#xff0c;至少还有六个月的时间&#xff0c;CentOS Stream 10 才会正式启动开发流程&#xff0c;接受来自外部的贡献。周五的公告指出&#xff1a;你会看到 C…

智能优化算法改进策略之局部搜索算子(二)—模式搜索(以正余弦算法和灰狼算法为研究对象)

一、改进点基本介绍&#xff1a; 在目前多数的改进智能优化算法文献中&#xff0c;局部搜索算子的形式多种多样。它们主要被用来增强算法的局部开发能力&#xff0c;进而提升它们在优化问题特别在单峰问题上的收敛性能。作为一种高效的直接搜索法&#xff0c;模式搜索目前已被…

freemarker 使用word模板赋值

1. 引包<dependency><groupId>org.freemarker</groupId><artifactId>freemarker</artifactId><version>2.3.28</version></dependency>word文档工具类import freemarker.template.Configuration; import freemarker.template.…

将List转化为String 以逗号隔开

一.前言 在我们日常开发中, 在前后端交互的时候 , 会遇到多个id或其他字段存放到一个字段中, 这时我们会遇到一个List(集合)---->String(单个字段), 这时我们要进行操作数据, 使得我们的数据可以保存到数据库中 . 二.解决方法 2.1 利用StringBurilder或StringBuffer pub…

【git】idea怎么去替换git的地址

git 打开git地址添加或者修改git地址 打开git地址 右击->git->repository->remotes 添加或者修改git地址

​BCC Art Looks:BCC+Color Infrared

BCCColor Infrared 彩色红外 Effect Presets & Docs 效果预设和文档 Mocha Mask and Track Mocha 蒙版和跟踪 Mocha Mask... Mocha 蒙版... Pixel Chooser / Mocha 像素选择器 / Mocha PixelChooser - 像素选择器 View Mask / Matte - 查看蒙版/遮罩 Intensity - 强度 Ma…

java基础(并发编程)-线程状态转换

一、线程的状态 情况1 情况2 情况3 情况4 情况5 情况6 情况7 情况8 情况9 RUNNABLE <-->BLOCKED t 线程用synchronized(obj)获取了对象锁时如果竞争CPU时间片失败&#xff0c;线程的状态从RUNNABLE -->BLOCKED持obj锁线程的同步代码块执行完毕&#xff0c;会…

系统架构设计师考试备考精简版(23年)!

关于23年新教材 2023 年系统架构设计师教材已经更新到第二版&#xff0c;新教材移除了 UML 和 设计模式章节&#xff0c;加入了架构设计理论与实践部分&#xff0c;对于大家来说好消息是 UML 和设计模式不用再去看了。坏消息是案例、论文难度应该会加大。这是因为新版本下篇加…

2023年黑马重磅推出接口自动化测试项目

随着测试行业的蓬勃发展&#xff0c;对从业者的要求越来越高&#xff0c;自动化测试已经成为软件测试中一个重要组成部分&#xff0c;广泛应用于各行各业。甚至&#xff0c;在圈子中还流传着这样一句话&#xff1a;学好测试自动化&#xff0c;年薪30万不在话下&#xff01; 今…

【重试】Java 中的 7 种重试机制

随着互联网的发展项目中的业务功能越来越复杂&#xff0c;有一些基础服务我们不可避免的会去调用一些第三方的接口或者公司内其他项目中提供的服务&#xff0c;但是远程服务的健壮性和网络稳定性都是不可控因素。在测试阶段可能没有什么异常情况&#xff0c;但上线后可能会出现…

漏洞分析|死磕Jenkins漏洞回显与利用效果

0x01 背景 近期我们发起了一个Goby漏洞挑战赛的活动&#xff0c;在活动期间收到了大量的反馈信息&#xff0c;延伸出一系列在编写POC漏洞检测与利用中考虑场景不全的问题&#xff0c;我们针对发现的各种场景用市面上常见的工具进行了一些列的对比工作&#xff0c;发现市面上工…

前端-vue-对打包的静态文件进行压缩

通过 npm run build 打包时候&#xff0c;会发现静态文件很大&#xff0c;放在nginx服务中访问页面会很慢&#xff0c;所以可在打包过程中对静态文件再压缩。 对js、css、html等文件进行压缩&#xff1a; 安装插件 “compression-webpack-plugin” 。(我本地版本&#xff1a;…

leecode-字符串解码-栈

题目 题目链接 分析 用两个栈存储数字、字符串的情况 如果遇到[&#xff0c;就入栈&#xff0c;遇到]就按照数字把字符串出栈&#xff0c;并构造出新的字符串赋给res。 一步步内部解码。 代码 class Solution { public:string decodeString(string s) {stack<int> …

【自监督论文阅读 4】BYOL

文章目录 一、摘要二、引言三、相关工作四、方法4.1 BYOL的描述4.2 Intuitions on BYOL’s behavior&#xff08;BYOL行为的直觉&#xff09;4.3 实验细节 五、实验评估5.1 Linear evaluation on ImageNet&#xff08;ImageNet上的线性评估&#xff09;5.2 Semi-supervised tra…

宝塔面板 - 如何通过宝塔面板设置服务器禁止 Ping?

问题描述 在介绍如何通过宝塔面板设置服务器禁止ping之前&#xff0c;我们先来简单了解一下什么是ping。 Ping 可用于测试网络上IP系统的可用性&#xff0c;也可用于通过监控往返时间和数据包丢失&#xff0c;来测试网络连接的质量。ping 也可以用于识别网络子网&#xff0c;…

数字孪生和GIS结合将为智慧园区带来什么样的改变?

数字孪生和地理信息系统&#xff08;GIS&#xff09;是当今智慧园区发展中的两个重要技术&#xff0c;它们的结合将为智慧园区带来根本性的改变和巨大的发展机遇。这种结合将深刻影响园区的规划、建设、运营和管理&#xff0c;为人们创造更智能、高效、可持续的生活环境。 首先…