使用itextPDF实现PDF电子公章工具类

itextpdf,pdf · 浏览次数 : 0

小编点评

本文介绍了一种使用itextPDF实现的PDF电子公章工具类,包括在线网站制作公章、下载并保存盖章图片以及生成数字签名等功能。 1. **在线网站印章生成器(Kalvin)**: - 提供在线服务,用户可上传公章图片。 - 生成数字证书文件(.p12格式),并保存至本地文件夹。 - 用户可将此.p12文件用于其他文档的盖章。 2. **数字签名生成与保存**: - 使用keytool工具生成Java KeyStore文件,包含私钥和证书链。 - keytool工具支持自动生成数字签名,并保存为p12格式。 - 代码部分包含依赖添加和盖章功能工具类的实现。 3. **盖章功能工具类(ItextUtil)**: - 实现了对传入PDF进行盖章处理的功能。 - 提供了签名信息的封装类,用于传递签名所需信息。 - 包含一个对外提供盖章功能的静态方法,接受源PDF、目标PDF和应用签名信息的参数。 - 示例代码展示了如何将签章应用于特定PDF文件。 总的来说,文章展示了一个利用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电子公章工具类相似的内容:

使用itextPDF实现PDF电子公章工具类

使用itextPDF实现PDF电子公章工具类 一、制作公章 在线网站:印章生成器 - Kalvin在线工具 (kalvinbg.cn) 然后对公章进行下载保存 盖章图片: 二、生成数字签名 2.1: java工具keytool生成p12数字证书文件 Keytool是用于管理和证书的工具,位于%JAV

使用EF 连接 数据库 SQLserver、MySql 实现 CodeFirst

1.新建项目,下载Nuget安装包 创建项目需要注意几点,如果是基于 .net framework 的项目 需要选择 相应版本的 EF, 如果是跨平台则选择EF Core版本。 我这里选择的是 .net framework 版本。红框里面是 实现EF Code First 需要的包。 对应的版本:

使用explain优化慢查询的业务场景分析

问:你最害怕的事情是什么? 答:搓澡 问:为什么? 答:因为有些人一旦错过,就不在了 Explain 这个词在不同的上下文中有不同的含义。在数据库查询优化的上下文中,"EXPLAIN" 是一个常用的 SQL 命令,用于显示 SQL 查询的执行计划。执行计划是数据库如何执行查询的一个详细描述,包括它将

使用Github Action来辅助项目管理

Github action 是一个Github官方提供的非常流行且速度集成 持续集成和持续交付(CI/CD)的工具。它允许你在GitHub仓库中自动化、定制和执行你的软件开发工作流。你可以发现、创建和分享用于执行任何你想要的工作的操作,包括CI/CD,并在完全定制的工作流中组合操作。 持续集成需要做

使用 GPU 进行 Lightmap 烘焙 - 简单 demo

作者:i_dovelemon 日期:2024-06-16 主题:Lightmap, PathTracer, Compute Shader 引言 一直以来,我都对离线 bake lightmap 操作很着迷。一方面,这个方案历久弥新,虽然很古老,但是一直在实际项目中都有使用;另一方面,它能够产生非常高

使用 Spring 实现控制反转和依赖注入

使用 Spring 实现控制反转和依赖注入 概述 在本文中,我们将介绍IoC(控制反转)和DI(依赖注入)的概念,以及如何在Spring框架中实现它们。 什么是控制反转? 控制反转是软件工程中的一个原则,它将对象或程序的某些部分的控制权转移给容器或框架。我们最常在面向对象编程的上下文中使用它。 与传

使用Kubesec检查YAML文件安全

使用Kubesec检查YAML文件安全,YAML文件是Kubernetes配置的主要载体,因此,检查YAML文件的安全性对于确保Kubernetes集群的安全至关重要,Kubesec简介,使用Kubesec检查YAML文件安全,kubesec scan podyamlsafe.yaml

使用Microsoft.SemanticKernel基于本地运行的Ollama大语言模型实现Agent调用函数

大语言模型的发展日新月异,记得在去年这个时候,函数调用还是gpt-4的专属。到今年本地运行的大模型无论是推理能力还是文本的输出质量都已经非常接近gpt-4了。而在去年gpt-4尚未发布函数调用时,智能体框架的开发者们依赖构建精巧的提示词实现了gpt-3.5的函数调用。目前在本机运行的大模型,基于这一

使用 TensorRT C++ API 调用GPU加速部署 YOLOv10 实现 500FPS 推理速度——快到飞起!!

NVIDIA ® TensorRT ™ 是一款用于高性能深度学习推理的 SDK,包含深度学习推理优化器和运行时,可为推理应用程序提供低延迟和高吞吐量。YOLOv10是清华大学研究人员近期提出的一种实时目标检测方法,通过消除NMS、优化模型架构和引入创新模块等策略,在保持高精度的同时显著降低了计算开销...

Flutter 借助SearchDelegate实现搜索页面,实现搜索建议、搜索结果,解决IOS拼音问题

使用Flutter自带的SearchDelegate组件实现搜索界面,通过魔改实现如下效果:搜素建议、搜索结果,支持刷新和加载更多,解决IOS中文输入拼音问题。