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

打印 上一主题 下一主题

主题 869|帖子 869|积分 2617

使用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  : 就是天生的文件地址
  1. 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 格式
  1. 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:添加依赖:
  1.       
  2.         <dependency>
  3.             <groupId>com.itextpdf</groupId>
  4.             <artifactId>itextpdf</artifactId>
  5.             <version>5.5.10</version>
  6.         </dependency>
  7.         <dependency>
  8.             <groupId>com.itextpdf</groupId>
  9.             <artifactId>itext-asian</artifactId>
  10.             <version>5.2.0</version>
  11.         </dependency>
  12.          <dependency>
  13.             
  14.     <dependency>
  15.       <groupId>org.bouncycastle</groupId>
  16.       <artifactId>bcprov-jdk15on</artifactId>
  17.       <version>1.49</version>
  18.     </dependency>
  19.     <dependency>
  20.       <groupId>org.bouncycastle</groupId>
  21.       <artifactId>bcpkix-jdk15on</artifactId>
  22.       <version>1.49</version>
  23.     </dependency>
复制代码
3.2:盖章功能工具类

功能:
对传入的pdf 文件进行盖章处置惩罚
  1. public class ItextUtil {
  2.     /**
  3.      *
  4.      * 功能: keystory密码
  5.      */
  6.     public static final char[] PASSWORD = "111111".toCharArray();
  7.     /**
  8.      * 单多次签章通用
  9.      *
  10.      * @param src 盖章文件路径
  11.      * @param target 盖章文件输出目标路径
  12.      * @param signatureInfo 盖章实体
  13.      */
  14.     public void sign(String src, String target, SignatureInfo signatureInfo) {
  15.         InputStream inputStream = null;
  16.         FileOutputStream outputStream = null;
  17.         ByteArrayOutputStream result = new ByteArrayOutputStream();
  18.         try {
  19.             inputStream = Files.newInputStream(Paths.get(src));
  20.             ByteArrayOutputStream tempArrayOutputStream = new ByteArrayOutputStream();
  21.             PdfReader reader = new PdfReader(inputStream);
  22.             // 创建签章工具PdfStamper ,最后一个boolean参数是否允许被追加签名
  23.             // false的话,pdf文件只允许被签名一次,多次签名,最后一次有效
  24.             // true的话,pdf可以被追加签名,验签工具可以识别出每次签名之后文档是否被修改
  25.             PdfStamper stamper = PdfStamper.createSignature(reader,
  26.                     tempArrayOutputStream, '\0', null, true);
  27.             // 获取数字签章属性对象
  28.             PdfSignatureAppearance appearance = stamper
  29.                     .getSignatureAppearance();
  30.             appearance.setReason(signatureInfo.getReason());
  31.             appearance.setLocation(signatureInfo.getLocation());
  32.             // 设置签名的位置,页码,签名域名称,多次追加签名的时候,签名预名称不能一样 图片大小受表单域大小影响(过小导致压缩)
  33.             // 签名的位置,是图章相对于pdf页面的位置坐标,原点为pdf页面左下角
  34.             // 四个参数的分别是,图章左下角x,图章左下角y,图章右上角x,图章右上角y
  35.             //四个参数的分别是,图章左下角x,图章左下角y,图章右上角x,图章右上角y
  36.             appearance.setVisibleSignature(new Rectangle(280, 220, 140, 600), 1, "sig1");
  37.             // 读取图章图片
  38.             Image image = Image.getInstance(signatureInfo.getImagePath());
  39.             appearance.setSignatureGraphic(image);
  40.             appearance.setCertificationLevel(signatureInfo
  41.                     .getCertificationLevel());
  42.             // 设置图章的显示方式,如下选择的是只显示图章(还有其他的模式,可以图章和签名描述一同显示)
  43.             appearance.setRenderingMode(signatureInfo.getRenderingMode());
  44.             // 这里的itext提供了2个用于签名的接口,可以自己实现,后边着重说这个实现
  45.             // 摘要算法
  46.             ExternalDigest digest = new BouncyCastleDigest();
  47.             // 签名算法
  48.             ExternalSignature signature = new PrivateKeySignature(
  49.                     signatureInfo.getPk(), signatureInfo.getDigestAlgorithm(),
  50.                     null);
  51.             // 调用itext签名方法完成pdf签章 //数字签名格式,CMS,CADE
  52.             MakeSignature.signDetached(appearance, digest, signature,
  53.                     signatureInfo.getChain(), null, null, null, 0,
  54.                     MakeSignature.CryptoStandard.CADES);
  55.             inputStream = new ByteArrayInputStream(
  56.                     tempArrayOutputStream.toByteArray());
  57.             // 定义输入流为生成的输出流内容,以完成多次签章的过程
  58.             result = tempArrayOutputStream;
  59.             outputStream = new FileOutputStream(new File(target));
  60.             outputStream.write(result.toByteArray());
  61.             outputStream.flush();
  62.         } catch (Exception e) {
  63.             e.printStackTrace();
  64.         } finally {
  65.             try {
  66.                 if (null != outputStream) {
  67.                     outputStream.close();
  68.                 }
  69.                 if (null != inputStream) {
  70.                     inputStream.close();
  71.                 }
  72.                 if (null != result) {
  73.                     result.close();
  74.                 }
  75.             } catch (IOException e) {
  76.                 e.printStackTrace();
  77.             }
  78.         }
  79.     }
  80. }
复制代码
测试代码:
  1. public static void main(String[] args) {
  2.         try {
  3.             ItextUtil app = new ItextUtil();
  4.             // 将证书文件放入指定路径,并读取keystore ,获得私钥和证书链
  5.             String pkPath = "src/main/resources/whj.p12";
  6.             KeyStore ks = KeyStore.getInstance("PKCS12");
  7.             ks.load(Files.newInputStream(Paths.get(pkPath)), PASSWORD);
  8.             String alias = ks.aliases().nextElement();
  9.             PrivateKey pk = (PrivateKey) ks.getKey(alias, PASSWORD);
  10.             // 得到证书链
  11.             Certificate[] chain = ks.getCertificateChain(alias);
  12.             //需要进行签章的pdf
  13.             String path = "C:\\Users\\ASUS\\Desktop\\sq.pdf";
  14.             // 封装签章信息
  15.             SignatureInfo signInfo = new SignatureInfo();
  16.             signInfo.setReason("牛逼");
  17.             signInfo.setLocation("666");
  18.             signInfo.setPk(pk);
  19.             signInfo.setChain(chain);
  20.             signInfo.setCertificationLevel(PdfSignatureAppearance.NOT_CERTIFIED);
  21.             signInfo.setDigestAlgorithm(DigestAlgorithms.SHA1);
  22.             signInfo.setFieldName("demo");
  23.             // 签章图片(网上生成的)
  24.             signInfo.setImagePath("C:\\Users\\ASUS\\Desktop\\字节码\\学习测试30.png");
  25.             signInfo.setRenderingMode(PdfSignatureAppearance.RenderingMode.GRAPHIC);
  26.             //// 值越大,代表向x轴坐标平移 缩小 (反之,值越小,印章会放大)
  27.             signInfo.setRectllx(100);
  28.             //// 值越大,代表向y轴坐标向上平移(大小不变)
  29.             signInfo.setRectlly(200);
  30.             // 值越大   代表向x轴坐标向右平移  (大小不变)
  31.             signInfo.setRecturx(150);
  32.             // 值越大,代表向y轴坐标向上平移(大小不变)
  33.             signInfo.setRectury(150);
  34.             //签章后的pdf路径
  35.             app.sign(path, "C:\\Users\\ASUS\\Desktop\\字节码\\out.pdf", signInfo);
  36.         } catch (Exception e) {
  37.             e.printStackTrace();
  38.         }
  39.     }
复制代码
实现对pdf 进行添加水印

一、添加水印工具类
  1. public class WaterMark {
  2.     /**
  3.      * pdf生成水印
  4.      *
  5.      * @param srcPdfPath       插入前的文件路径
  6.      * @param tarPdfPath       插入后的文件路径
  7.      * @param WaterMarkContent 水印文案
  8.      * @param numberOfPage     每页需要插入的条数
  9.      * @throws Exception
  10.      */
  11.     public static void addWaterMark(String srcPdfPath, String tarPdfPath, String WaterMarkContent, int numberOfPage) throws Exception {
  12.         PdfReader reader = new PdfReader(srcPdfPath);
  13.         PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(tarPdfPath));
  14.         PdfGState gs = new PdfGState();
  15.         //设置字体
  16.         BaseFont font = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
  17.         // 设置透明度
  18.         gs.setFillOpacity(0.4f);
  19.         int total = reader.getNumberOfPages() + 1;
  20.         PdfContentByte content;
  21.         for (int i = 1; i < total; i++) {
  22.             content = stamper.getOverContent(i);
  23.             content.beginText();
  24.             content.setGState(gs);
  25.             //水印颜色
  26.             content.setColorFill(BaseColor.DARK_GRAY);
  27.             //水印字体样式和大小
  28.             content.setFontAndSize(font, 35);
  29.             //插入水印  循环每页插入的条数
  30.             for (int j = 0; j < numberOfPage; j++) {
  31.                 content.showTextAligned(Element.ALIGN_CENTER, WaterMarkContent, 300, 200 * (j + 1), 30);
  32.             }
  33.             content.endText();
  34.         }
  35.         stamper.close();
  36.         reader.close();
  37.         // 删除源文件,这个可以根据自己的需要来是否删除源文件
  38.         boolean b = deleteFile(srcPdfPath);
  39.         System.out.println("PDF水印添加完成!");
  40.     }
  41.     /**
  42.      *
  43.      * 功能: 删除文件
  44.      * @param path  需要删除的文件路径
  45.      * @return {@link boolean}
  46.      * @author luoheng
  47.      */
  48.     public static boolean deleteFile(String path) {
  49.         boolean result = false;
  50.         File file = new File(path);
  51.         if (file.isFile() && file.exists()) {
  52.             int tryCount = 0;
  53.             while (!result && tryCount++ < 10) {
  54.                 System.gc();
  55.                 result = file.delete();
  56.             }
  57.         }
  58.         return result;
  59.     }
  60. }
复制代码
测试代码

我们传入需要加水印的pdf,设置对应的格式,数量,字体,以及对应输出的文件地址
  1. public static void main(String[] args) {
  2.         /**
  3.          * pdf生成水印
  4.          *
  5.          * @param srcPdfPath       需要加印的文件路径
  6.          * @param tarPdfPath       加印后的文件输出路径
  7.          * @param WaterMarkContent 水印文案
  8.          * @param numberOfPage     每页需要插入的条数
  9.          * @throws Exception
  10.          */
  11.         String srcPdfPath = "C:\\Users\\ASUS\\Desktop\\字节码\\out.pdf";
  12.         String tarPdfPath = "C:\\Users\\ASUS\\Desktop\\字节码\\out2.pdf";
  13.         String WaterMarkContent = "程序员小王";
  14.         Integer numberOfPage = 3;
  15.         try {
  16.             // 添加水印
  17.             WaterMark.addWaterMark(srcPdfPath, tarPdfPath, WaterMarkContent, numberOfPage);
  18.         } catch (Exception e) {
  19.             e.printStackTrace();
  20.         }
  21.     }
复制代码
效果图:

如果代码写的有问题,欢迎各人评论交流,进行指点!!!
也盼望各人点个关注哦~~~~~~~~

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

篮之新喜

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表