使用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电子公章工具类的更多相关文章

  1. iReport报表生成html,pdf,xls,word工具类

    package com.report; import java.io.ByteArrayOutputStream;import java.io.File;import java.io.InputStr ...

  2. Java借助itext pdf生成固定格式pdf的模板工具类

    这里是标题区域 这里是副标题1: 副标题的内容 这里是副标题2: 这里是副标题2的内容 这里是副标题3: 这里是副标题3的内容 序号 表头1 复合表头 表头2 子表头1 子表头2 子表头3 1 居左内 ...

  3. 【转载】 C#工具类:使用iTextSharp操作PDF文档

    iTextSharp是一个用于操作PDF文件的组件DLL程序,在C#程序中可以引用iTextSharp组件,用于开发与PDF文件相关的报表等功能,利用iTextSharp组件提供出来的方法接口,我们可 ...

  4. Java 借助poi操作PDF工具类

    ​ 一直以来说写一个关于Java操作PDF的工具类,也没有时间去写,今天抽空写一个简单的工具类,拥有PDF中 换行,字体大小,字体设置,字体颜色,首行缩进,居中,居左,居右,增加新一页等功能,如果需要 ...

  5. 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 ...

  6. [PDFBox]后台操作pdf的工具类

    PDFBox是Apache下的一个操作pdf的类库.其也提供了一个命令行的工具,也提供了java调用的第三方类库. 下载地址:https://pdfbox.apache.org/ 下面的实验基于JDK ...

  7. itext之pdf导出添加水印Java工具类

    import java.io.IOException; import com.itextpdf.text.Document; import com.itextpdf.text.DocumentExce ...

  8. java img图片转pdf 工具类

    package com.elitel.hljhr.comm.web.main.controller; import java.io.File; import java.io.FileNotFoundE ...

  9. 基于Itextpdf合成PDF

    原创:转载需注明原创地址 https://www.cnblogs.com/fanerwei222/p/12023314.html 开发过程中有用到PDF合成, 记录一下合成的方法和代码. 使用工具 : ...

  10. Android—关于自定义对话框的工具类

    开发中有很多地方会用到自定义对话框,为了避免不必要的城府代码,在此总结出一个工具类. 弹出对话框的地方很多,但是都大同小异,不同无非就是提示内容或者图片不同,下面这个类是将提示内容和图片放到了自定义函 ...

随机推荐

  1. 物联网浏览器(IoTBrowser)-使用深度学习开发防浸水远程报警

    一.起因 新房子买在2楼,反水概率较大,加上无良开发商的劣质材料,就我所在楼栋已经发生几起反水事件,而且是高层反水,有几户重复出现反水,原因是管道中间有一个钢筋 :( 二.解决方案 1.水浸传感器+W ...

  2. axiso封装

    import axios from 'axios';import {Message } from 'element-ui'//element-ui提示框组件import config from './ ...

  3. 第九課-Channel Study For Caller Client Api

    1.浏览Mirth Connect开放Client API 2.启动Vs2019,编程测试Client Api的调用 开启你在宇宙第一IDE下熟悉的.net之旅吧!

  4. Koordinator 0.6:企业级容器调度系统解决方案,引入 CPU 精细编排、资源预留与全新的重调度框架

    简介: 经过社区多位成员的贡献,Koordinator 0.6 版本正式发布.相较于上一个版本 0.5,新版本进一步完善了 CPU 精细化编排能力,更好的兼容原生用法:支持了资源预留的能力(Reser ...

  5. 参与 Apache 顶级开源项目的 N 种方式,Apache Dubbo Samples SIG 成立!

    简介: 一说到参与开源项目贡献,一般大家的反应都是代码级别的贡献,总觉得我的代码被社区合并了,我才算一个贡献者,这是一个常见的错误认知.其实,在一个开源社区中有非常多的角色是 non-code con ...

  6. 微信不再提供小程序打开App?借助H5为App引流的方式你必须知道!

    简介: 2021年5月14日App开发者领域发布了一条重要消息:微信开放平台为了提升用户体验,将于2021年5月20日(后来延期到2021年5月27日)起不再提供"小程序打开App技术服务& ...

  7. [GPT] ./ssh/known_hosts 是什么

      ~/.ssh/known_hosts 是一个SSH客户端用来存储已知的远程主机的公钥的文件,这些公钥用于验证连接到远程主机时它们是否为真实可信的主机. 当你首次通过SSH连接到一个新的远程主机时, ...

  8. [Cloud] From Borg to Kubernetes

    Borg System Architect: Kubernetes System Architect: Link:https://www.cnblogs.com/farwish/p/12751861. ...

  9. [Tools] Kali Linux 高清屏扩大系统字体、BurpSuite、OpenVAS

    系统检索 Setting Manager,Appearance -> Settings,选择 Window Scaling:2x Terminal fonts: linux terminal 快 ...

  10. 原生js写悬浮广告效果

    网上抄的,改成vue写法失败,下一篇是自己写的vue版本的 <html> <head> <meta http-equiv="Content-Type" ...