itext对pdf文件进行多钱张及多页图片签章

最近在用itext实现对pdf进行图片签章,单页多个签章资料很多,没什么问题;但是在不多次操作pdf文件的情况下,对多页的pdf每页进行签章碰到困难,查找各种资料都没找到好的解决方案,后面分析itext的源码得以解决,不多bb,直接上代码

private static void signs(String src  //需要签章的pdf文件路径
            , String dest  // 签完章的pdf文件路径
            , Certificate[] chain //证书链
            , PrivateKey pk //签名私钥
            , String digestAlgorithm  //摘要算法名称,例如SHA-1
            , String provider  // 密钥算法提供者,可以为null
            , CryptoStandard subfilter //数字签名格式,itext有2种
            , String reason  //签名的原因,显示在pdf签名属性中,随便填
            , String location //签名的地点,显示在pdf签名属性中,随便填
            ,String designer,String collactor,String auditor,String approver)
            throws GeneralSecurityException, IOException, DocumentException {
		String str[] = new String[4];
		str[0] = designer;
		str[1] = collactor;
		str[2] = auditor;
		str[3] = approver;
		
		String imagePath = "";
		InputStream inputStream = null;
		FileOutputStream outputStream = null;
		ByteArrayOutputStream result = new ByteArrayOutputStream();
		ByteArrayOutputStream tempArrayOutputStream = null;
		try {
			inputStream = new FileInputStream(src);
			int pages = 1;//这里先要默认设置pdf的页数为1 因为new PdfReader(inputStream)不能在这里初始化
		
			
			for (int i = 0; i < 4; i++) {//这个循环是解决每页的多个图章
				float posWidth=0;
				float posHeight=0;
				float stampWidth=100;
				float stampHeight=100;
				//处理参数
				if(i==0) {//设计
					posWidth=532;
					posHeight=530;
					stampWidth = 35;
					stampHeight = 18;
					imagePath = designer;
				}
				
				if(i==1) {//校审
					posWidth=430;
					posHeight=530;
					stampWidth = 35;
					stampHeight = 18;
					imagePath = collactor;
				}
				
				if(i==2) {//组审
					posWidth=532;
					posHeight=548;
					stampWidth = 35;
					stampHeight = 18;
					imagePath = auditor;
				}
				
				if(i==3) {//审定
					posWidth=430;
					posHeight=548;
					stampWidth = 35;
					stampHeight = 18;
					imagePath = approver;
				}
		        for(int j=1;j<=pages;j++) {//这个循环解决多页签章
		        	tempArrayOutputStream = new ByteArrayOutputStream();
			        PdfReader reader = new PdfReader(inputStream);
			        if(j==1) pages = reader.getNumberOfPages();//这里需要取下pdf的总页数
		        	//创建签章工具PdfStamper ,最后一个boolean参数是否允许被追加签名
			        PdfStamper stamper = PdfStamper.createSignature(reader, tempArrayOutputStream, '\0', null, true);
			        // 获取数字签章属性对象
			        PdfSignatureAppearance appearance = stamper.getSignatureAppearance();
		        	appearance.isPreClosed();
			        appearance.setReason(reason);
			        appearance.setLocation(location);
		        	//设置签名的签名域名称,多次追加签名的时候,签名预名称不能一样,图片大小受表单域大小影响(过小导致压缩)
			        appearance.setVisibleSignature(new Rectangle(posWidth, posHeight, posWidth+stampWidth, posHeight+stampHeight), j, DateUtils.getDateTotalYMDHMS()+(int)((Math.random()*9+1)*10000));
	                
			        //读取图章图片
			        Image image = Image.getInstance(imagePath);
			        appearance.setSignatureGraphic(image);
			        appearance.setCertificationLevel(PdfSignatureAppearance.NOT_CERTIFIED);
			        //设置图章的显示方式,如下选择的是只显示图章(还有其他的模式,可以图章和签名描述一同显示)
			        appearance.setRenderingMode(RenderingMode.GRAPHIC);
			        // 摘要算法
			        ExternalDigest digest = new BouncyCastleDigest();
			        // 签名算法
			        ExternalSignature signature = new PrivateKeySignature(pk, digestAlgorithm, null);
			        // 调用itext签名方法完成pdf签章
			        MakeSignature.signDetached(appearance, digest, signature, chain, null, null, null, 0, subfilter);
			        //定义输入流为生成的输出流内容,以完成多次签章的过程
			        inputStream = new ByteArrayInputStream(tempArrayOutputStream.toByteArray());
			        result = tempArrayOutputStream;
		        }  
		    }
		    outputStream = new FileOutputStream(new File(dest));
		    outputStream.write(result.toByteArray());
		    outputStream.flush();
		}catch(Exception e) {
			e.printStackTrace();
		} finally {
		    try {
		    	if(null!=tempArrayOutputStream){
		        	tempArrayOutputStream.close();
		        }
		        if(null!=outputStream){
		            outputStream.close();
		        }
		        if(null!=inputStream){
		            inputStream.close();
		        }
		        if(null!=result){
		            result.close();
		        }
		    } catch (IOException e) {
		        e.printStackTrace();
		    }
		}
	}

 

你可能感兴趣的:(itext对pdf文件进行多钱张及多页图片签章)