Java利用itextpdf实现pdf文件生成

前言

最近公司让写一个数据页面生成pdf的功能,找了一些市面代码感觉都太麻烦,就自己综合性整合了一个便捷的工具类,开发只需简单组装数据直接调用即可快速生成pdf文件。望大家一起学习!!!
代码获取方式:

  1. 资源下载
  2. 后台私信(一键三连哦!!!)

二、前期准备

1、html模版(放置接口所在项目的resourcess/templates/

需要准备一个要看到的pdf模版,利用html代码形式简单输出,其中需要动态填充的地方需要用变量进行填充
比如页面显示:
姓名:韩云中
性别:男

<div>
    姓名:${name}
    性别:${sex}
</div>

2、数据实体

AbstractDocumentVo 必须继承 会有个findPrimaryKey方法需要实现,return一个你这条数据的标识即可
实体字段名称必须与html${}内容一致

public class User extends AbstractDocumentVo {

    private String name;
    
    private String sex;

    @Override
    public String findPrimaryKey() {
        // 数据标识  id或则其它均可
        return this.name;
    }
}

三、代码开发

实现接口

@GetMapping("/testCreatePdf")
public void testCreatePdf(HttpServletResponse response) {

    // 方式一:前端直接给你传递这个对象
    // 方式二:通过前端传递的标识,自行去库中进行数据获取
    // ** 两种方式都需要保证html用到的字段不能存在null 不然报错
    User user = new User();
    user.setName("");
    user.setSex("");
    
    // 生成pdf路径
    PdfDocumentGenerator pdfGenerator = new PdfDocumentGenerator();
    // 生成pdf  
    // 参数一:classpath中templates下对应要用的模版名称 
    // 参数二:模板数据 
    // 参数三:生成pdf名称
    // 参数四:response
    pdfGenerator.generate("overseaAssistance.html", overseaVo, "2.pdf", response);
}

四、结果

得到自己想要的pdf文件
在这里插入图片描述

测试数据

java实体

package com.yxy.aob.controller;

import com.yxy.common.core.utils.file.pdf.AbstractDocumentVo;
import lombok.Data;
import lombok.EqualsAndHashCode;

/**
 * @Description:
 * @Author: Hyz
 * @Date: 2024/10/11 11:22
 * @Version:1.0
 */
@EqualsAndHashCode(callSuper = true)
@Data
public class OverseaVo extends AbstractDocumentVo {

    /**
     * 标识
     */
    private String policyNo;
    /**
     * 投保人姓名
     */
    private String holderName;
    /**
     * 投被保人关系
     */
    private String relation;
    /**
     * 投保人联络地址
     */
    private String holderAdress;
    /**
     * 投保人邮编
     */
    private String holderPostCode;

    /**
     * 被保险人姓名
     */
    private String insuredName;
    /**
     * 被保险人姓名拼音
     */
    private String insuredPingyinName;
    /**
     * 被保险人护照号码
     */
    private String insuredPassportNo;
    /**
     * 被保险人性别
     */
    private String insuredSex;
    /**
     * 被保险人出生日期
     */
    private String insuredBirthday;
    /**
     * 被保险人电话
     */
    private String insuredPhone;

    /**
     * 被保险人证件号码
     */
    private String insuredIDNo;

    /**
     * 前往国家或地区
     */
    private String destination;

    /**
     * 受益人姓名
     */
    private String beneficiaryName;

    /**
     * 备注
     */
    private String remarks;

    /**
     * 保险期间
     */
    private String period;

    /**
     * 境外意外伤害或残疾保额
     */
    private String accidentalSumInsured;

    /**
     * 紧急救援医疗保额
     */
    private String emergencySumInsured;

    /**
     * 附加境外紧急救援医保额
     */
    private String medicalSumInsured;

    /**
     * 总保费
     */
    private String premium;
    /**
     * 签发日期
     */
    private String issueDate;

    /**
     * 省份
     */
    private String branchName;

    /**
     * 合作公司名称
     */
    private String companyName;

    @Override
    public String findPrimaryKey() {
        return this.policyNo;
    }
}

html模版

<html>
<head>
    <title></title>
    <style type="text/css">
       body {
          margin-left: 45px;
          margin-right: 45px;
          font-family: Arial Unicode MS;
          font-size: 10px;
       }

       table {
          margin: auto;
          width: 100%;
          border-collapse: collapse;
          border: 1px solid #444444;
       }

       th,td {
          border: 1px solid #444444;
          font-size: 10px;
          margin-left: 5px;
       }

       .mcContent {
          line-height: 180%;
          padding: 20px;
       }

       .logo {
          text-align: center;
       }

       .title {
          text-align: center;
          font-weight: bold;
          font-size: 20px;
       }

       .notes {
          font-weight: normal;
          margin-left: 5px;
          margin-right: 5px;
          line-height: 18px;
       }

       .text_content {
          margin-left: 5px;
          margin-right: 5px;
          line-height: 18px;
       }

       .sum_insured_first_row {
          width: 20%;
       }

       .sum_insured_span {
          font-size: 10px;
       }

       .special_agreements_div {
          page-break-before: always;
          font-size: 14px;
          margin-top: 20px;
       }

       .special_agreements_div .special_agreements {
          font-size: 18px;
          font-weight: bold;
       }

       .title_right {
          width: 100%;
          margin: 0 auto;
       }

       .title_right p {
          text-align: left;
          margin: 0;
          margin-left: 50%;
          padding: 0;
       }

       @page {
          size: 8.5in 11in;
       @
       bottom-center
       {
          content
          :
                "page "
                counter(
                      page
                )
                " of  "
                counter(
                      pages
                );
       }

       .signature {
          margin: 0 auto;
          clear: both;
          font-size: 16px;
          font-weight: bold;
       }

       .signature_table {
          /*     font-size: 16px; */
          font-weight: bold;
       }

    </style>
</head>
<body>
<div>
    <div class="title">
       测试PDF生成--
       <p>测试单号:${policyNo}</p>
    </div>

    <div class="insurance_info">
       <table class="insurance_info_table" cellpadding="0" cellspacing="0"
             width="100%">
          <tr>
             <td width="20%" colspan="3">投保人<br /> Policyholder
             </td>
             <td width="43%" colspan="3">${holderName}<br /></td>
             <td width="15%">与被保险人关系<br /> Relationship with the Insured
             </td>
             <td >${relation}</td>
          </tr>
          <tr>
             <td width="20%" colspan="3">联络地址<br /> Correspondence Address
             </td>
             <td width="43%" colspan="3">${holderAdress}</td>
             <td width="15%">邮编<br /> Postal Code
             </td>
             <td >${holderPostCode}</td>
          </tr>
          <tr class="td_width1">
             <td width="20%" colspan="3">被保险人姓名<br /> Name of the Insured
             </td>
             <td width="13%">${holderName}</td>
             <td width="10%">(拼音)<br /> (Pinyin)
             </td>
             <td width="18%">${insuredPingyinName}</td>
             <td width="15%">护照号码<br /> Passport No
             </td>
             <td>${insuredPassportNo}</td>
          </tr>
          <tr>
             <td width="5%">性别<br /> Sex
             </td>
             <td width="5%">${insuredSex}</td>
             <td width="10%">出生日期<br /> Date of Birth
             </td>
             <td width="13%">${insuredBirthday}</td>
             <td width="10%">电话<br /> Telephone No.
             </td>
             <td width="18%">${insuredPhone}</td>
             <td width="15%">证件号码 <br />ID No.</td>
             <td >${insuredIDNo}</td>
          </tr>
          <tr>
             <td colspan="3">请详细列明前往国家或地区<br /> Destination
             </td>
             <td colspan="3">${destination}</td>
             <td>受益人姓名<br /> Beneficiary
             </td>
             <td>${beneficiaryName}</td>
          </tr>
          <tr>
             <td class="address_class" colspan="3">备注 <br /> Remarks
             </td>
             <td colspan="5">${remarks}</td>
          </tr>
          <tr>
             <td class="address_class" colspan="3">保险期间 <br /> Insurance
                period
             </td>
             <td colspan="5">${period}</td>
          </tr>
       </table>
    </div>

    <div class="signature">
       <br /> <br />
       <table class="signature_table" style="border: 0; width: 100%;">
          <tr>
             <th
                   style="border: 0; font-size: 12px; font-weight: bold; text-align: left; width: 17%;">总经理签名:
                <br /> <span style="font-size:10px">Authorized Signature</span>
             </th>
             <td
                   style="border: 0; font-size: 12px; font-weight: bold; text-align: left; width: 17%;"></td>
             <th
                   style="border: 0; font-size: 12px; font-weight: bold; text-align: left; width: 17%;">公司签章:
                <br /><span style="font-size:10px">Company Stamp</span>
             </th>
             <td
                   style="border: 0; font-size: 12px; font-weight: bold; text-align: left; width: 17%;"></td>
             <th
                   style="border: 0; font-size: 12px; font-weight: bold; text-align: left; width: 16%;">签发日期:<br />
                <span style="font-size:10px">Issue Date</span>
             </th>
             <td
                   style="border: 0; font-size: 12px; font-weight: bold; text-align: left; width: 16%;">${issueDate}</td>
          </tr>
       </table>
    </div>
    <div class="text_content">
       <br /> 我从来不是那样的人,不能耐心地拾起一地碎片,把它们凑合在一起,然后对自己说,这个修补好了的东西,跟新的完全一样。一样东西破碎了就是破碎了,我宁愿记住它最好时的模样,而不想把它修补好,然后终生看着那些碎了的地方。
    </div>

</div>
</body>
</html>

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

java游戏网站源码

题目&#xff1a;java游戏网站源码 编号B22A390 主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Mysql|大数据|SSM|SpringBoot|Vue|Jsp|MYSQL等)、学习资料、JAVA源码、技术咨询 文末联系获取 感兴趣可以先收藏起来&#xff0c;以防走丢&#xff0c;有任何选题、文档编…

初识C++--C++入门

一、命名空间 在c语言中存在着名字冲突的问题&#xff0c;即不能出现同名&#xff0c;会出现错误。而在c中变量、函数和后⾯要学到的类都是⼤量存在的&#xff0c;这些变量、函数和类的名称将都存在于全局作⽤域中&#xff0c;可能会导致很多冲突。为了解决这个问题&#xff0c…

十三、Python基础语法(字符串str-中)

一、切片 使用下标可以获得字符串中指定的一个字符&#xff0c;使用切片可以获取字符中多个字符。 字符串[start: end: step] start&#xff1a;开始位置的下标 end&#xff1a;结束位置的下标&#xff08;end对应的位置数据取不到&#xff09; step&#xff1a;步长&#…

要在 Git Bash 中使用 `tree` 命令,下载并手动安装 `tree`。

0、git bash 安装 git(安装,常用命令,分支操作,gitee,IDEA集成git,IDEA集成gitee,IDEA集成github,远程仓库操作) 1、下载并手动安装 tree 下载 tree.exe 从 tree for Windows 官方站点 下载 tree 的 Windows 可执行文件。tree for Window&#xff1a;https://gnuwin32.source…

FreeRTOS学习笔记1

结合汇编 ldr r3, pxCurrentTCB ldr r2 R3 value0x20000054,R2 value0x2002B950 pxCurrentTCB 020028950 pxTopOfStsck 0x2002B8FC 解释这些寄存器的值是怎么变化的 1. ldr r3, pxCurrentTCB 这一行指令将 全局变量 pxCurrentTCB 的地址加载到寄存器 r3 中。pxCu…

【论文精读】RELIEF: Reinforcement Learning Empowered Graph Feature Prompt Tuning

RELIEF: Reinforcement Learning Empowered Graph Feature Prompt Tuning 前言AbstractMotivationSolutionRELIEFIncorporating Feature Prompts as MDPAction SpaceState TransitionReward Function Policy Network ArchitectureDiscrete ActorContinuous ActorCritic Overall…

【C++】精妙的哈希算法

&#x1f680;个人主页&#xff1a;小羊 &#x1f680;所属专栏&#xff1a;C 很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~ 目录 一、哈希结构1、哈希概念2、哈希函数3、哈希冲突3.1 闭散列3.2 开散列 4、完整代码 一、哈希结构 1、哈希概念 A…

C# WPF 仿 Android Toast 效果

转载请注明出处: https://blog.csdn.net/hx7013/article/details/142860084 主职Android, 最近需要写一些WPF的程序作为上位机&#xff0c;目前WPF的MessageBox过于臃肿&#xff0c;且想找一个内置的非阻塞的简单提示一直找不到&#xff0c;想到了Android的Toast所以写了这个扩…

低代码可视化-uniapp购物车页面-代码生成器

购物车页面是电子商务网站或应用程序中的一个关键功能页面&#xff0c;它允许用户查看、编辑和管理他们选择加入购物车的商品。下面通过低代码可视化实现一个uniapp购物车页面&#xff0c;把购物车整个事件都集成进去。实现完成后可以保存为页面模板。 收货地址选择 如果尚未…

yolov9目标检测/分割预测报错AttributeError: ‘list‘ object has no attribute ‘device‘常见汇总

这篇文章主要是对yolov9目标检测和目标分割预测测试时的报错&#xff0c;进行解决方案。 在说明解决方案前&#xff0c;严重投诉、吐槽一些博主发的一些文章&#xff0c;压根没用的解决方法&#xff0c;也不知道他们从哪里抄的&#xff0c;误人子弟、浪费时间。 我在解决前&…

JVM 实战篇(一万字)

此笔记来至于 黑马程序员 内存调优 内存溢出和内存泄漏 内存泄漏&#xff08;memory leak&#xff09;&#xff1a;在Java中如果不再使用一个对象&#xff0c;但是该对象依然在 GC ROOT 的引用链上&#xff0c;这个对象就不会被垃圾回收器回收&#xff0c;这种情况就称之为内…

Rust usize类型(用来表示地址的类型)Rust地址与指针的区别(Rust指针)

文章目录 Rust usize类型Rust地址与指针的区别&#xff08;指针有数据类型&#xff0c;而地址只是一个数字&#xff09;指针地址使用场景示例 Rust usize类型 在Rust中&#xff0c;地址通常表示为usize类型&#xff0c;这是因为usize是专门设计用来存储指针大小的无符号整型&a…

vue综合指南(五)

​&#x1f308;个人主页&#xff1a;前端青山 &#x1f525;系列专栏&#xff1a;Vue篇 &#x1f516;人终将被年少不可得之物困其一生 依旧青山,本期给大家带来Vuet篇专栏内容:vue综合指南 目录 81 简述每个周期具体适合哪些场景 82、Vue $forceUpdate的原理 83、vue获取数…

MySQL—关于数据库的CRUD—(增删改查)

文章目录 关于数据库的使用&#xff1a;1. 数据库的背景知识&#xff1a;2. MYSQL数据库软件的使用&#xff08;MYSQL安装的问题在另一篇博客中讲解&#xff09;。&#xff08;1&#xff09;启动MYSQL数据库软件&#xff08;2&#xff09;开始使用数据库程序&#xff1a;1&…

leetcode动态规划(一)-理论基础

本节主要参考&#xff1a;代码随想录 题目分类 动态规划释义 动态规划&#xff0c;英文&#xff1a;Dynamic Programming&#xff0c;简称DP&#xff0c;如果某一问题有很多重叠子问题&#xff0c;使用动态规划是最有效的。 动态规划中每一个状态一定是由上一个状态推导出来…

车辆管理的SpringBoot技术革新

摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了车辆管理系统的开发全过程。通过分析车辆管理系统管理的不足&#xff0c;创建了一个计算机管理车辆管理系统的方案。文章介绍了车辆管理系统的系统分析部分&…

使用 OpenWebUI 一键部署 Mistral-Large-Instruct-2407-AWQ

教程及模型简介 该教程是使用 OpenWebUI 一键部署 Mistral-Large-Instruct-2407-AWQ&#xff0c;相关环境和配置已经搭建完成&#xff0c;只需克隆启动容器即可进行推理体验。 Mistral-Large-Instruct-2407-AWQ 是法国人工智能公司 Mistral AI 发布的新一代旗舰 AI 模型&…

操作系统简介:作业管理

作业管理 一、作业管理1.1 作业控制1.2 作业的状态及其转换1.3 作业控制块和作业后备队列 二、作业调度2.1 调度算法的选择2.2 作业调度算法2.3 作业调度算法性能的衡量指标 三、人机界面 作业&#xff1a;系统为完成一个用户的计算任务&#xff08;或一次事务处理&#xff09;…

RabbitMQ 核心功能详解

引言 在现代分布式系统中&#xff0c;消息队列已经成为一种不可或缺的组件。它不仅能够实现应用之间的解耦&#xff0c;还能提高系统的灵活性和可扩展性。RabbitMQ 是一款基于 AMQP&#xff08;Advanced Message Queuing Protocol&#xff09;协议的消息中间件&#xff0c;以其…

【人工智能】人工智能的10大算法详解(优缺点+实际案例)

人工智能&#xff08;AI&#xff09;是现代科技的重要领域&#xff0c;其中的算法是实现智能的核心。本文将介绍10种常见的人工智能算法&#xff0c;包括它们的原理、训练方法、优缺点及适用场景。 1. 线性回归&#xff08;Linear Regression&#xff09; 模型原理 线性回归…