使用itextPDF实现PDF电子公章工具类
使用itextPDF实现PDF电子公章工具类
一、制作公章
在线网站:印章生成器 - Kalvin在线工具 (kalvinbg.cn)
然后对公章进行下载保存

盖章图片:

二、生成数字签名
2.1: java工具keytool生成p12数字证书文件
Keytool是用于管理和证书的工具,位于%JAVA_HOME%/bin目录。
使用JDK的keytool工具
- keytool在jdk的bin目录下

2.2:启动黑窗命令

2.3:生成数字文件
D:\keystore\server.keystore : 就是生成的文件地址
keytool -genkeypair -alias whj -keypass 111111 -storepass 111111 -dname “C=CN,ST=SD,L=QD,O=haier,OU=dev,CN=haier.com” -keyalg RSA -keysize 2048 -validity 3650 -keystore D:\keystore\server.keystore
2.4:转换为p12格式,在命令行输入
注意:这里的路径和上面的路径要保持一直,不能就转不了P12 格式
keytool -importkeystore -srckeystore D:\keystore\server.keystore -destkeystore D:\keystore\whj.p12 -srcalias whj -destalias serverkey -srcstoretype jks -deststoretype pkcs12 -srcstorepass 111111 -deststorepass 111111 -noprompt

三、代码部分
3.1:添加依赖:
<!-- itextpdf依赖 -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.10</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
<dependency>
<!-- 摘要算法 -->
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.49</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>
<version>1.49</version>
</dependency>
3.2:盖章功能工具类
功能:
对传入的pdf 文件进行盖章处理
public class ItextUtil {
/**
*
* 功能: keystory密码
*/
public static final char[] PASSWORD = "111111".toCharArray();
/**
* 单多次签章通用
*
* @param src 盖章文件路径
* @param target 盖章文件输出目标路径
* @param signatureInfo 盖章实体
*/
public void sign(String src, String target, SignatureInfo signatureInfo) {
InputStream inputStream = null;
FileOutputStream outputStream = null;
ByteArrayOutputStream result = new ByteArrayOutputStream();
try {
inputStream = Files.newInputStream(Paths.get(src));
ByteArrayOutputStream tempArrayOutputStream = new ByteArrayOutputStream();
PdfReader reader = new PdfReader(inputStream);
// 创建签章工具PdfStamper ,最后一个boolean参数是否允许被追加签名
// false的话,pdf文件只允许被签名一次,多次签名,最后一次有效
// true的话,pdf可以被追加签名,验签工具可以识别出每次签名之后文档是否被修改
PdfStamper stamper = PdfStamper.createSignature(reader,
tempArrayOutputStream, '\0', null, true);
// 获取数字签章属性对象
PdfSignatureAppearance appearance = stamper
.getSignatureAppearance();
appearance.setReason(signatureInfo.getReason());
appearance.setLocation(signatureInfo.getLocation());
// 设置签名的位置,页码,签名域名称,多次追加签名的时候,签名预名称不能一样 图片大小受表单域大小影响(过小导致压缩)
// 签名的位置,是图章相对于pdf页面的位置坐标,原点为pdf页面左下角
// 四个参数的分别是,图章左下角x,图章左下角y,图章右上角x,图章右上角y
//四个参数的分别是,图章左下角x,图章左下角y,图章右上角x,图章右上角y
appearance.setVisibleSignature(new Rectangle(280, 220, 140, 600), 1, "sig1");
// 读取图章图片
Image image = Image.getInstance(signatureInfo.getImagePath());
appearance.setSignatureGraphic(image);
appearance.setCertificationLevel(signatureInfo
.getCertificationLevel());
// 设置图章的显示方式,如下选择的是只显示图章(还有其他的模式,可以图章和签名描述一同显示)
appearance.setRenderingMode(signatureInfo.getRenderingMode());
// 这里的itext提供了2个用于签名的接口,可以自己实现,后边着重说这个实现
// 摘要算法
ExternalDigest digest = new BouncyCastleDigest();
// 签名算法
ExternalSignature signature = new PrivateKeySignature(
signatureInfo.getPk(), signatureInfo.getDigestAlgorithm(),
null);
// 调用itext签名方法完成pdf签章 //数字签名格式,CMS,CADE
MakeSignature.signDetached(appearance, digest, signature,
signatureInfo.getChain(), null, null, null, 0,
MakeSignature.CryptoStandard.CADES);
inputStream = new ByteArrayInputStream(
tempArrayOutputStream.toByteArray());
// 定义输入流为生成的输出流内容,以完成多次签章的过程
result = tempArrayOutputStream;
outputStream = new FileOutputStream(new File(target));
outputStream.write(result.toByteArray());
outputStream.flush();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (null != outputStream) {
outputStream.close();
}
if (null != inputStream) {
inputStream.close();
}
if (null != result) {
result.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
测试代码:
public static void main(String[] args) {
try {
ItextUtil app = new ItextUtil();
// 将证书文件放入指定路径,并读取keystore ,获得私钥和证书链
String pkPath = "src/main/resources/whj.p12";
KeyStore ks = KeyStore.getInstance("PKCS12");
ks.load(Files.newInputStream(Paths.get(pkPath)), PASSWORD);
String alias = ks.aliases().nextElement();
PrivateKey pk = (PrivateKey) ks.getKey(alias, PASSWORD);
// 得到证书链
Certificate[] chain = ks.getCertificateChain(alias);
//需要进行签章的pdf
String path = "C:\\Users\\ASUS\\Desktop\\sq.pdf";
// 封装签章信息
SignatureInfo signInfo = new SignatureInfo();
signInfo.setReason("牛逼");
signInfo.setLocation("666");
signInfo.setPk(pk);
signInfo.setChain(chain);
signInfo.setCertificationLevel(PdfSignatureAppearance.NOT_CERTIFIED);
signInfo.setDigestAlgorithm(DigestAlgorithms.SHA1);
signInfo.setFieldName("demo");
// 签章图片(网上生成的)
signInfo.setImagePath("C:\\Users\\ASUS\\Desktop\\字节码\\学习测试30.png");
signInfo.setRenderingMode(PdfSignatureAppearance.RenderingMode.GRAPHIC);
//// 值越大,代表向x轴坐标平移 缩小 (反之,值越小,印章会放大)
signInfo.setRectllx(100);
//// 值越大,代表向y轴坐标向上平移(大小不变)
signInfo.setRectlly(200);
// 值越大 代表向x轴坐标向右平移 (大小不变)
signInfo.setRecturx(150);
// 值越大,代表向y轴坐标向上平移(大小不变)
signInfo.setRectury(150);
//签章后的pdf路径
app.sign(path, "C:\\Users\\ASUS\\Desktop\\字节码\\out.pdf", signInfo);
} catch (Exception e) {
e.printStackTrace();
}
}
实现对pdf 进行添加水印
一、添加水印工具类
public class WaterMark {
/**
* pdf生成水印
*
* @param srcPdfPath 插入前的文件路径
* @param tarPdfPath 插入后的文件路径
* @param WaterMarkContent 水印文案
* @param numberOfPage 每页需要插入的条数
* @throws Exception
*/
public static void addWaterMark(String srcPdfPath, String tarPdfPath, String WaterMarkContent, int numberOfPage) throws Exception {
PdfReader reader = new PdfReader(srcPdfPath);
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(tarPdfPath));
PdfGState gs = new PdfGState();
//设置字体
BaseFont font = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
// 设置透明度
gs.setFillOpacity(0.4f);
int total = reader.getNumberOfPages() + 1;
PdfContentByte content;
for (int i = 1; i < total; i++) {
content = stamper.getOverContent(i);
content.beginText();
content.setGState(gs);
//水印颜色
content.setColorFill(BaseColor.DARK_GRAY);
//水印字体样式和大小
content.setFontAndSize(font, 35);
//插入水印 循环每页插入的条数
for (int j = 0; j < numberOfPage; j++) {
content.showTextAligned(Element.ALIGN_CENTER, WaterMarkContent, 300, 200 * (j + 1), 30);
}
content.endText();
}
stamper.close();
reader.close();
// 删除源文件,这个可以根据自己的需要来是否删除源文件
boolean b = deleteFile(srcPdfPath);
System.out.println("PDF水印添加完成!");
}
/**
*
* 功能: 删除文件
* @param path 需要删除的文件路径
* @return {@link boolean}
* @author luoheng
*/
public static boolean deleteFile(String path) {
boolean result = false;
File file = new File(path);
if (file.isFile() && file.exists()) {
int tryCount = 0;
while (!result && tryCount++ < 10) {
System.gc();
result = file.delete();
}
}
return result;
}
}
测试代码
我们传入需要加水印的pdf,设置对应的格式,数量,字体,以及对应输出的文件地址
public static void main(String[] args) {
/**
* pdf生成水印
*
* @param srcPdfPath 需要加印的文件路径
* @param tarPdfPath 加印后的文件输出路径
* @param WaterMarkContent 水印文案
* @param numberOfPage 每页需要插入的条数
* @throws Exception
*/
String srcPdfPath = "C:\\Users\\ASUS\\Desktop\\字节码\\out.pdf";
String tarPdfPath = "C:\\Users\\ASUS\\Desktop\\字节码\\out2.pdf";
String WaterMarkContent = "程序员小王";
Integer numberOfPage = 3;
try {
// 添加水印
WaterMark.addWaterMark(srcPdfPath, tarPdfPath, WaterMarkContent, numberOfPage);
} catch (Exception e) {
e.printStackTrace();
}
}
效果图:

如果代码写的有问题,欢迎大家评论交流,进行指点!!!
也希望大家点个关注哦~~~~~~~~
使用itextPDF实现PDF电子公章工具类的更多相关文章
- iReport报表生成html,pdf,xls,word工具类
package com.report; import java.io.ByteArrayOutputStream;import java.io.File;import java.io.InputStr ...
- Java借助itext pdf生成固定格式pdf的模板工具类
这里是标题区域 这里是副标题1: 副标题的内容 这里是副标题2: 这里是副标题2的内容 这里是副标题3: 这里是副标题3的内容 序号 表头1 复合表头 表头2 子表头1 子表头2 子表头3 1 居左内 ...
- 【转载】 C#工具类:使用iTextSharp操作PDF文档
iTextSharp是一个用于操作PDF文件的组件DLL程序,在C#程序中可以引用iTextSharp组件,用于开发与PDF文件相关的报表等功能,利用iTextSharp组件提供出来的方法接口,我们可 ...
- Java 借助poi操作PDF工具类
一直以来说写一个关于Java操作PDF的工具类,也没有时间去写,今天抽空写一个简单的工具类,拥有PDF中 换行,字体大小,字体设置,字体颜色,首行缩进,居中,居左,居右,增加新一页等功能,如果需要 ...
- Jacob工具类使用文件互转服务 word转html html转excel word转pdf excel转pdf ppt转pdf
前提条件 必须安装MS office 1.jdk使用jdk1.8 2.jacob.dll放在..\jdk1.8\jre\bin目录下 3.eclipse的jre版本要和jdk一致,window-&g ...
- [PDFBox]后台操作pdf的工具类
PDFBox是Apache下的一个操作pdf的类库.其也提供了一个命令行的工具,也提供了java调用的第三方类库. 下载地址:https://pdfbox.apache.org/ 下面的实验基于JDK ...
- itext之pdf导出添加水印Java工具类
import java.io.IOException; import com.itextpdf.text.Document; import com.itextpdf.text.DocumentExce ...
- java img图片转pdf 工具类
package com.elitel.hljhr.comm.web.main.controller; import java.io.File; import java.io.FileNotFoundE ...
- 基于Itextpdf合成PDF
原创:转载需注明原创地址 https://www.cnblogs.com/fanerwei222/p/12023314.html 开发过程中有用到PDF合成, 记录一下合成的方法和代码. 使用工具 : ...
- Android—关于自定义对话框的工具类
开发中有很多地方会用到自定义对话框,为了避免不必要的城府代码,在此总结出一个工具类. 弹出对话框的地方很多,但是都大同小异,不同无非就是提示内容或者图片不同,下面这个类是将提示内容和图片放到了自定义函 ...
随机推荐
- 力扣217(java&python)-存在重复元素(简单)
题目: 给你一个整数数组 nums .如果任一值在数组中出现 至少两次 ,返回 true :如果数组中每个元素互不相同,返回 false . 示例 1: 输入:nums = [1,2,3,1]输出:t ...
- 力扣172(java)-阶乘后的零(中等)
题目: 给定一个整数 n ,返回 n! 结果中尾随零的数量. 提示 n! = n * (n - 1) * (n - 2) * ... * 3 * 2 * 1 示例 1: 输入:n = 3输出:0解释: ...
- 阿里云云原生加速器企业硬之城携手阿里云 Serverless 应用引擎(SAE)打造低代码平台
简介: 作为入选阿里云首期云原生加速器的企业,硬之城此前也获得了阿里云首批产品生态集成认证,通过云原生加速器项目携手阿里云共建更加丰富的云原生产业生态圈,加速云原生落地. 作者 | 陈泽涛(硬之城产品 ...
- 手把手教你PolarDB-X中的表设计——用户表
简介: 本系列旨在描述一个具体的业务场景,给出建表的例子,帮助大家更好的使用PolarDB-X.本期的主题是:用户表. 本系列旨在描述一个具体的业务场景,给出建表的例子,帮助大家更好的使用PolarD ...
- 阿里云EMR Remote Shuffle Service在小米的实践
简介:阿里云EMR自2020年推出Remote Shuffle Service(RSS)以来,帮助了诸多客户解决Spark作业的性能.稳定性问题,并使得存算分离架构得以实施,与此同时RSS也在跟合作 ...
- 技术干货| 阿里云基于Hudi构建Lakehouse实践探索「内附干货PPT下载渠道」
简介: 阿里云高级技术专家王烨(萌豆)在Apache Hudi 与 Apache Pulsar 联合 Meetup 杭州站上的演讲整理稿件,本议题介绍了阿里云如何使用 Hudi 和 OSS 对象存储 ...
- [Linux] 日志管理: 日志轮替 logrotate
日志轮替包含了 "日志切割" 和 "删除旧的保留新的" 功能. 后缀 xx.1 xx.2 这种规则的一般出现的也比较多,目的系统是防止日志被覆盖. 查看详细配置 ...
- dotnet C# 反射扫描程序集所有类型会不会触发类型静态构造函数
在 dotnet 里面,有很多框架都喜欢扫描程序集进行初始化逻辑,在扫描程序集的所有类型的时候,相当于碰到所有类型.而某个类型的静态构造函数将会在某个类型被使用之前被 CLR 调用,那么扫描类型是否会 ...
- 2018-2-13-win10-uwp-自定义控件-SplitViewItem
title author date CreateTime categories win10 uwp 自定义控件 SplitViewItem lindexi 2018-2-13 17:23:3 +080 ...
- 数据转换2-无人机航拍倾斜摄影转换成OSGB格式
首先软件的下载和安装参考下面链接 http://www.xue51.com/soft/53013.html 0.首先打开软件,要打开2个哦. 打数据处理开后台 ContextCapture Engin ...