IText创建加盖公章的pdf文件并生成压缩文件

第一、前言
此前已在文章:Java使用IText根据pdf模板创建pdf文件介绍了Itex的基本使用技巧,本篇以一个案例为基础,主要介绍IText根据pdf模板填充生成pdf文件,并生成压缩文件。

第二、案例
以下面pdf模板为例,生成一个pdf文件,并将其压缩成zip文件。
在这里插入图片描述
在这里插入图片描述
第三、代码实现
1、将pdf模板机公章图片放到resource目录;
在这里插入图片描述
2、为提高效率,在系统启动后将模板加载到redis缓存中,代码如下;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.Objects;
import javax.annotation.PostConstruct;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPoolAbstract;
@Component
public class InitConfig {private static final Logger logger = LoggerFactory.getLogger(InitConfig.class);private final JedisPoolAbstract jedisPool;@Autowiredpublic InitConfig(JedisPoolAbstract jedisPool) {super();this.jedisPool = jedisPool;}@PostConstructpublic void init() {try {Jedis jedis = jedisPool.getResource();final byte[] key="data".getBytes();if (jedis.exists(key)) {jedis.del(key);}InputStream is = this.getClass().getResourceAsStream("/template/data.pdf");jedis.set(key, streamToByteArray(is));final byte[] gongzhangKey="gongzhang".getBytes();if (jedis.exists(gongzhangKey)) {jedis.del(gongzhangKey);}is = this.getClass().getResourceAsStream("/image/gongzhang.png");jedis.set(gongzhangKey, streamToByteArray(is));} catch (Exception e) {logger.error("加载模板异常", e);}}public static byte[] streamToByteArray(InputStream is) throws Exception {ByteArrayOutputStream bos = null;try {bos = new ByteArrayOutputStream();byte[] b = new byte[1024];int len;while ((len = is.read(b)) != -1) {bos.write(b, 0, len);}return bos.toByteArray();} catch (Exception e) {logger.error("初始化模板", e);throw e;} finally {if (Objects.nonNull(bos)) {bos.close();}}}
}

3、操作文件工具类;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Map;
import java.util.Objects;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import com.itextpdf.text.Image;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.pdf.PdfWriter;public final class CommonFileUtil {private final static org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(CommonFileUtil.class);/*** 根据模板生成文件* @param paramMap* @param deskFile* @param template* @param gongZhang* @throws Exception*/public static void create(Map<String, Object> paramMap, File deskFile, final byte[] template, final byte[] gongZhang) throws Exception {PdfReader reader = null;PdfStamper stamp = null;try {reader = new PdfReader(template);stamp = new PdfStamper(reader, new FileOutputStream(deskFile));stamp.setEncryption(null, "lsy2024".getBytes(), PdfWriter.ALLOW_PRINTING, true);//取出报表模板中的所有字段AcroFields form = stamp.getAcroFields();//设置宋体BaseFont song = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);//设置参数for (Map.Entry<String, Object> entry : paramMap.entrySet()) {String key = entry.getKey();form.setFieldProperty(key, "textfont", song, null);form.setField(key, entry.getValue().toString());}//插入公章CommonFileUtil.insertImage(form, stamp, "gongzhang", gongZhang);//保存修改stamp.setFormFlattening(true);} catch (Throwable e) {logger.error("deskFile:{};文件生成失败!", deskFile, e);throw e;} finally {if (Objects.nonNull(stamp)) {stamp.close();}if (Objects.nonNull(reader)) {reader.close();}}}/*** pdf模板插入图片* @param form* @param stamper* @param filedName* @param gongZhang* @throws Exception*/public static void insertImage(AcroFields form, PdfStamper stamper, String filedName, final byte[] gongZhang) throws Exception {final Rectangle signRect = form.getFieldPositions(filedName).get(0).position;float x = signRect.getLeft();float y = signRect.getBottom();Image image = Image.getInstance(gongZhang);// 获取操作的页面PdfContentByte under = stamper.getOverContent(form.getFieldPositions(filedName).get(0).page);// 根据域的大小缩放图片image.scaleToFit(signRect.getWidth(), signRect.getHeight());// 添加图片image.setAbsolutePosition(x, y);under.addImage(image);}/*** 文件压缩* @param sourcePath* @param zipFilePath* @throws Exception*/public static void encryptNoPassword(String sourcePath, String zipFilePath) throws Exception {final long start = System.currentTimeMillis();byte[] buf = new byte[1024];File zipFile = new File(zipFilePath);//zip文件不存在,则创建文件,用于压缩ZipOutputStream zos = null;try {if (!zipFile.exists()) {zipFile.createNewFile();}zos = new ZipOutputStream(new FileOutputStream(zipFile));File file = new File(sourcePath);for (File sourceFile : file.listFiles()) {if (sourceFile == null || !sourceFile.exists()) {continue;}try (FileInputStream fis = new FileInputStream(sourceFile)) {//直接放到压缩包的根目录zos.putNextEntry(new ZipEntry(sourceFile.getName()));int len;while ((len = fis.read(buf)) > 0) {zos.write(buf, 0, len);}zos.closeEntry();}}} catch (Throwable e) {logger.error("sourcePath:{};zipFilePath:{};压缩文件失败!", sourcePath, zipFilePath, e);throw e;} finally {if (zos != null) {zos.close();}}logger.info("sourcePath:{};zipFilePath:{};压缩文件结束!{}", sourcePath, zipFilePath, System.currentTimeMillis() - start);}/*** 清理文件* @param path*/public static void clean(String path) {File rootPath = new File(path);if (rootPath.exists()) {if (rootPath.isDirectory()) {for (File file : rootPath.listFiles()) {clean(file.getPath());}}if (rootPath.isFile() || rootPath.listFiles().length == 0) {rootPath.delete();}}}
}

4、编写一个测试方法;

    public void print() {try {final String name = "张三";final String rootPath = "D:/temp/";File rootFile = new File(rootPath);if (!rootFile.exists()) {rootFile.mkdir();}File destFile = new File(rootPath + name + ".pdf");Map<String, Object> paramMap = new HashMap<String, Object>();paramMap.put("name", name);paramMap.put("birthDate", "2000-01-01");paramMap.put("currentDate", "2024  年  11  月  22  日");CommonFileUtil.create(paramMap, destFile, this.jedisPool.getResource().get("data".getBytes()), this.jedisPool.getResource().get("gongzhang".getBytes()));CommonFileUtil.encryptNoPassword(rootPath, "D:/data.zip");} catch (Exception e) {logger.error("==" + e);}}

5、调用并执行测试方法,将会在D盘创建压缩文件;
在这里插入图片描述
6、解压后如下;
在这里插入图片描述

欢迎大家积极留言交流学习心得!

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

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

相关文章

使用 npm 安装 Electron 作为开发依赖

好的&#xff0c;下面是一个使用 npm pack 和 npm install 命令来打包和安装离线版本的 npm 包的具体示例。我们将以 electron 为例&#xff0c;演示如何在有网络连接的机器上打包 electron&#xff0c;然后在没有网络连接的机器上安装它。 步骤 1: 在有网络连接的机器上打包 …

合法三元数量计算

问题描述 小C、小U 和小R 三个好朋友喜欢做一些数字谜题。这次他们遇到一个问题&#xff0c;给定一个长度为n的数组a&#xff0c;他们想要找出符合特定条件的三元组 (i, j, k)。具体来说&#xff0c;三元组要满足 0 < i < j < k < n&#xff0c;并且 max(a[i], a[…

【AI系统】GPU 架构回顾(从2018年-2024年)

Turing 架构 2018 年 Turing 图灵架构发布&#xff0c;采用 TSMC 12 nm 工艺&#xff0c;总共 18.6 亿个晶体管。在 PC 游戏、专业图形应用程序和深度学习推理方面&#xff0c;效率和性能都取得了重大进步。相比上一代 Volta 架构主要更新了 Tensor Core&#xff08;专门为执行…

【高阶数据结构】图论

> 作者&#xff1a;დ旧言~ > 座右铭&#xff1a;松树千年终是朽&#xff0c;槿花一日自为荣。 > 目标&#xff1a;了解什么是图&#xff0c;并能掌握深度优先遍历和广度优先遍历。 > 毒鸡汤&#xff1a;有些事情&#xff0c;总是不明白&#xff0c;所以我不会坚持…

日期(练习)

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title></title> </head> <body></body> <script>// 定义一个函数&#xff0c;实现格式化日期对象&#xff0c;返回yyyy-MM-dd…

【IDEA】解决总是自动导入全部类(.*)问题

文章目录 问题描述解决方法 我是一名立志把细节说清楚的博主&#xff0c;欢迎【关注】&#x1f389; ~ 原创不易&#xff0c; 如果有帮助 &#xff0c;记得【点赞】【收藏】 哦~ ❥(^_-)~ 如有错误、疑惑&#xff0c;欢迎【评论】指正探讨&#xff0c;我会尽可能第一时间回复…

企业使用知识管理工具与技术的好处(举例说明)

我们都知道“知识就是力量”这句老话&#xff0c;无论是在工作还是个人生活中&#xff0c;我们每一天都越来越认识到这句话的真谛。近年来&#xff0c;不可否认的是&#xff0c;全球范围内我们都在某种程度上缺乏对于许多企业和大型公司至关重要的高端技术技能。 当然&#xf…

机器学习系列-决策树

文章目录 1. 决策树原理决策树的构建流程 2. 案例步骤 1&#xff1a;计算当前节点的熵步骤 2&#xff1a;对每个特征计算分裂后的熵(1) 按“天气”分裂数据集(2) 计算分裂后的加权熵 步骤 3&#xff1a;计算分裂依据信息增益信息增益率GINI系数&#xff08;二叉树&#xff09; …

Android 网络通信(三)OkHttp实现登入

学习笔记 目录 一. 先写XML布局 二、创建 LoginResponse 类 :封装响应数据 目的和作用: 三、创建 MyOkHttp 类 :发送异步请求 代码分析 可能改进的地方 总结 四、LoginActivity 类中实现登录功能 详细分析与注释: 总结: 改进建议: 零、响应数据样例 通过 P…

移动端相关 BFC CSS原子化 ✅

移动端相关 设备宽度&视口 设备宽度是指设备屏幕的实际物理宽度&#xff0c;通常以像素&#xff08;px&#xff09;表示。它是固定的&#xff0c;取决于设备的硬件。不同设备&#xff08;如手机、平板、桌面等&#xff09;有不同的设备宽度。 常被提及的视口可被分为3种…

resnet50,clip,Faiss+Flask简易图文搜索服务

一、实现 文件夹目录结构&#xff1a; templates -----upload.html faiss_app.py 前端代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widt…

爬虫重定向问题解决

一&#xff0c;问题 做爬虫时会遇到强制重定向的链接&#xff0c;此时可以手动获取重定向后的链接 如下图情况 第二个链接是目标要抓取的&#xff0c;但它是第一个链接重定向过去的&#xff0c;第一个链接接口状态也是302 二&#xff0c;解决方法 请求第一个链接&#xff0c…

一个小的可编辑表格问题引起的思考

11.21工作中遇到的问题 预期&#xff1a;当每行获取红包金额的时候若出现错误&#xff0c;右侧当行会出现提示 结果&#xff1a;获取红包金额出现错误&#xff0c;右侧对应行并没有出现错误提示 我发现&#xff0c;当我们设置readonly的时候&#xff0c;其实render函数依旧是…

解决 vxe-table v3.9 + iview 或者 view-design 中使用 Select 后无法选中的问题

官网文档&#xff1a;https://vxetable.cn 在开发 vue 项目中&#xff0c;使用 vxe-table 时&#xff0c;当同时配合 iview 或者 view-design 组件库使用时&#xff0c;发现一个问题&#xff0c;就是在单元格中渲染 Select 时&#xff0c;会导致下拉选项无法被选中&#xff0c…

「Mac玩转仓颉内测版27」基础篇7 - 字符串类型详解

本篇将介绍 Cangjie 中的字符串类型&#xff0c;包括字符串的定义、字面量形式、插值表达、常用操作及应用场景&#xff0c;帮助开发者熟练掌握字符串的使用。 关键词 字符串类型定义字符串字面量插值字符串字符串拼接常用操作 一、字符串类型概述 在 Cangjie 中&#xff0c;…

一种简单高效的RTSP流在线检测方法,不需要再过渡拉流就可以获取设备状态以及对应音视频通道与编码格式

平台如何检测一路RTSP流是否在线&#xff1f; 在之前的流媒体平台方案中&#xff0c;我们都是通过定时RTSP拉流的方式&#xff0c;走一个完整的RTSP流程&#xff1a;包括OPTIONS、DESCRIBE、SETUP、PLAY、RTP收流&#xff0c;这种方式去取流&#xff0c;然后取到流之后进行流解…

Excel中超链接打开文件时报错 “打开此文件的应用程序没有注册“ 的一个解决办法

需要在Excel中快速打开.bas后缀的文件&#xff0c;所以添加了文件超链接&#xff0c;但是在打开文件的时候报错 “打开此文件的应用程序没有注册” 找到文件直接双击是可以正常打开的&#xff0c;说明是哪里有问题&#xff0c;导致Excel不能找到可以打开文件的程序&#xff0c…

高效集成:金蝶盘亏单数据对接管易云

金蝶盘亏单数据集成到管易云的技术实现 在企业日常运营中&#xff0c;数据的高效流转和准确对接是确保业务顺利进行的关键。本文将聚焦于一个具体的系统对接集成案例&#xff1a;如何将金蝶云星空中的盘亏单数据无缝集成到管易云的其他出库模块。 为了实现这一目标&#xff0…

神经网络问题之一:梯度消失(Vanishing Gradient)

梯度消失&#xff08;Vanishing Gradient&#xff09;问题是深度神经网络训练中的一个关键问题&#xff0c;它主要发生在反向传播过程中&#xff0c;导致靠近输入层的权重更新变得非常缓慢甚至几乎停滞&#xff0c;严重影响网络的训练效果和性能。 图1 在深度神经网络中容易出现…

单神经元 PID 解耦控制

单神经元 PID 解耦控制是一种将单神经元自适应控制与解耦控制相结合的方法&#xff0c;适用于多输入多输出&#xff08;MIMO&#xff09;系统。其核心是利用单神经元的自适应能力实现 PID 参数在线调整&#xff0c;同时通过解耦策略减少变量之间的相互影响&#xff0c;提高控制…