itext5 盖章 生成二维码 并设置扫码内容及 点击二维码跳转超链接

网上各种收费还说不到重点的自己研究了一下,提供给大家 盖章是抄的 二维码超链接自己写的


import cn.hutool.json.JSONObject;
import com.itextpdf.text.*;
import com.itextpdf.text.Image;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.*;
import com.itextpdf.text.pdf.PdfSignatureAppearance.RenderingMode;
import com.itextpdf.text.pdf.security.BouncyCastleDigest;
import com.itextpdf.text.pdf.security.ExternalDigest;
import com.itextpdf.text.pdf.security.ExternalSignature;
import com.itextpdf.text.pdf.security.MakeSignature;
import com.itextpdf.text.pdf.security.MakeSignature.CryptoStandard;
import com.itextpdf.text.pdf.security.PrivateKeySignature;
import sun.misc.BASE64Decoder;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.MessageDigest;
import java.security.PrivateKey;
import java.security.cert.Certificate;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.List;


   public static void main(String[] args) throws IOException, DocumentException, GeneralSecurityException {
        String size = "{\"pagesizes\":[[1262,892],[1262,892],[1262,892],[1262,892],[1262,892],[1262,892],[1262,892],[1262,892]]}";
        String img = "base64图片";

 System.out.println(sign("D:\\Download\\981502a8a472c9adcfb35f59bf15d0f5.pdf",img,7,300.00F,1165.00F,400.00F,1265.00F,
     "F:\\78910.pdf","F:\\文件管理\\公司\\4693642__sygnew.com.pfx",
     "8KrSWRNu","SHA-1",null,
     "CMS","Test","dd",1,size,"https://www.baidu.com/","https://www.baidu.com/"));


    }


  public static String sign(String src  //需要签章的pdf文件路径
            , String img,int pageNum
            , float x1,float y1,float x2,float y2
            , String dest  			// 签完章的pdf文件路径
            , String ketstore  		//
            , String password  		//
            , String digestAlgorithm  //摘要算法名称,例如SHA-1
            , String provider  // 密钥算法提供者,可以为null
            , String subfilter //数字签名格式,itext有2种
            , String reason  //签名的原因,显示在pdf签名属性中,随便填
            , String location //签名的地点,显示在pdf签名属性中,随便填
            , int signtype//签章类型,1.普通章,2.骑缝章,3.连续章
            , String size  //前端传入pdf尺寸
            , String filedl //短链接地址
            , String linkurl //跳转地址
    )
    //throws GeneralSecurityException, IOException, DocumentException {
    {
        try{
            int isCreateBarcodeQRCode=0;

            //生成二维码
            BarcodeQRCode barcodeQRCode = new BarcodeQRCode(filedl, 66, 66, null);
            Image img2 = barcodeQRCode.getImage();

            //设置二维码
            Rectangle linkLocation=null;
            PdfAnnotation link=null;
            PdfAction action = new PdfAction(linkurl);
            if(signtype==1){
                //获取前端传入pdf尺寸
                JSONObject jsonObject = new JSONObject(size);
                List  listsize=(List)jsonObject.getObj("pagesizes");
                List size1= (List)listsize.get(pageNum-1);
                //获取前台带入pdf尺寸
                Float yy=Float.parseFloat(size1.get(0).toString());
                Float xx=Float.parseFloat(size1.get(1).toString());

                String uuid = UUID.randomUUID().toString();
                String IMG=img;
                if(!img.startsWith("/")){
                    IMG="F:\\"+uuid+".png";
                    if(IMG.startsWith("/var/www/work"))
                        IMG="/var/www/pdf/"+uuid+".png";
                    byte []b= Base64.getDecoder().decode(img);
                    java.io.FileOutputStream out = null;
                    try{
                        out=new java.io.FileOutputStream(IMG);
                        out.write(b,0,b.length);
                        out.close();
                    }catch(Exception e){
                        e.printStackTrace();
                        return e.getMessage();
                    }
                }

                //下边的步骤都是固定的,照着写就行了,没啥要解释的
                // Creating the reader and the stamper,开始pdfreader
                PdfReader reader = new PdfReader(src);

                //获取后台pdf尺寸
                Float  x=Float.parseFloat(reader.getPageSize(pageNum).toString().substring(11).split("x")[0]);
                Float  y=Float.parseFloat(reader.getPageSize(pageNum).toString().split("x")[1].split(" ")[0]);
                //得到比例
                Float XB=x/xx;
                Float YB=y/yy;
                Float x1XB=x1*XB-2.0F;
                Float y1YB=y1*YB-2.0F;
                Float x2XB=x2*XB+2.0F;
                Float y2YB=y2*YB+2.0F;


                //目标文件输出流
                FileOutputStream os = new FileOutputStream(dest);
                //创建签章工具PdfStamper ,最后一个boolean参数
                //false的话,pdf文件只允许被签名一次,多次签名,最后一次有效
                //true的话,pdf可以被追加签名,验签工具可以识别出每次签名之后文档是否被修改
                PdfStamper stamper = PdfStamper.createSignature(reader, os, '\0', null, true);
                //设置二维码尺寸及位置

                Float w3 = img2.getScaledWidth();
                Float h3 = img2.getScaledHeight();


                for (int p = 0; p <reader.getNumberOfPages() ; p++) {
                    x=Float.parseFloat(reader.getPageSize(p+1).toString().substring(11).split("x")[0]);
                    y=Float.parseFloat(reader.getPageSize(p+1).toString().split("x")[1].split(" ")[0]);
                    Float x3 = x-99F;
                    Float y3 = y-63F;
                    //每页都加上
                    img2.setAbsolutePosition(x3, y3);

                    stamper.getOverContent(p+1).addImage(img2);
                    linkLocation = new Rectangle(x3, y3, x3 + w3, y3 + h3);
                    link = PdfAnnotation.createLink(stamper.getWriter(),
                            linkLocation, PdfAnnotation.HIGHLIGHT_INVERT,
                            action);
                    link.setBorder(new PdfBorderArray(0, 0, 0));
                    stamper.addAnnotation(link, p+1);
                }

                // 获取数字签章属性对象,设定数字签章的属性
                PdfSignatureAppearance appearance = stamper.getSignatureAppearance();
                appearance.setReason(reason);
                appearance.setLocation(location);
                //设置签名的位置,页码,签名域名称,多次追加签名的时候,签名预名称不能一样
                //签名的位置,是图章相对于pdf页面的位置坐标,原点为pdf页面左下角
                //四个参数的分别是,图章左下角x,图章左下角y,图章右上角x,图章右上角y
                appearance.setVisibleSignature(new Rectangle(x1XB,y1YB,x2XB,y2YB), pageNum, uuid);// "sig1");
                //读取图章图片,这个image是itext包的image
                Image image = Image.getInstance(IMG);
                appearance.setSignatureGraphic(image);
                appearance.setCertificationLevel(PdfSignatureAppearance.NOT_CERTIFIED);
                //设置图章的显示方式,如下选择的是只显示图章(还有其他的模式,可以图章和签名描述一同显示)
                appearance.setRenderingMode(RenderingMode.GRAPHIC);

                char[]password2=password.toCharArray();
                //读取keystore ,获得私钥和证书链
                KeyStore ks = KeyStore.getInstance("PKCS12");
                ks.load(new FileInputStream(ketstore), password2);
                String alias = (String)ks.aliases().nextElement();
                PrivateKey pk = (PrivateKey) ks.getKey(alias, password2);//签名私钥
                Certificate[] chain = ks.getCertificateChain(alias);//证书链

                CryptoStandard subfilter2=CryptoStandard.CMS;
                if("CADES".equals(subfilter))subfilter2=CryptoStandard.CADES;

                System.out.println( src+":"
                        +":"+ x1+":"+ y1 +":"+ x2+":"+ y2
                        +":"+  dest  			// 签完章的pdf文件路径
                        +":"+  ketstore  		//
                        +":"+  password  	//
                        +":"+  digestAlgorithm  //摘要算法名称,例如SHA-1
                        +":"+  provider  // 密钥算法提供者,可以为null
                        +":"+  subfilter //数字签名格式,itext有2种
                        +":"+  reason  //签名的原因,显示在pdf签名属性中,随便填
                        +":"+  location);
                // 这里的itext提供了2个用于签名的接口,可以自己实现,后边着重说这个实现
                // 摘要算法
                ExternalDigest digest = new BouncyCastleDigest();
                // 签名算法
                ExternalSignature signature = new PrivateKeySignature(pk, digestAlgorithm, null);
                // 调用itext签名方法完成pdf签章
                MakeSignature.signDetached(appearance, digest, signature, chain, null, null, null, 0, subfilter2);
            }


        }catch(Exception e) {
            e.printStackTrace();
            return e.getMessage();
        }catch(Throwable e) {
            e.printStackTrace();
            return e.getMessage();
        }
        return "ok";
    }

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
生成二维码可以使用iText库来实现。iText是一个用于创建和操作PDF文档的Java库,它也提供了生成二维码的功能。 首先,你需要在你的项目中引入iText库。你可以在iText的官方网站上下载最新版本的库文件,并将其添加到你的项目中。 接下来,你可以使用iText的Barcode类来生成二维码。下面是一个使用iText生成二维码的示例代码: ```java import com.itextpdf.barcodes.BarcodeQRCode; import com.itextpdf.text.Document; import com.itextpdf.text.DocumentException; import com.itextpdf.text.pdf.PdfWriter; import java.io.FileNotFoundException; import java.io.FileOutputStream; public class QRCodeGenerator { public static void main(String[] args) { String qrCodeText = "Hello, iText!"; String filePath = "qrcode.pdf"; Document document = new Document(); try { PdfWriter.getInstance(document, new FileOutputStream(filePath)); document.open(); BarcodeQRCode qrCode = new BarcodeQRCode(qrCodeText, 1000, 1000, null); document.add(qrCode.getImage()); document.close(); System.out.println("QR Code generated successfully!"); } catch (DocumentException | FileNotFoundException e) { e.printStackTrace(); } } } ``` 在上面的示例代码中,我们首先定义了要生成二维码的文本内容和输出文件路径。然后,我们创建了一个Document对象,并使用PdfWriter将其与输出文件关联。接下来,我们使用BarcodeQRCode类创建一个二维码对象,并将其添加到文档中。最后,我们关闭文档并输出成功消息。 你可以根据自己的需求修改示例代码中的文本内容二维码大小和输出文件路径。运行代码后,你将在指定的输出文件中找到生成的二维码PDF文件。 请注意,生成二维码的功能是iText库的一部分,你需要确保已正确引入iText库并按照示例代码中的方式使用它。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值