Java为pdf电子签章(关键字盖章)

文章介绍了如何在Java中使用iTextPDF库对PDF文件进行关键字定位,并演示了如何在PDF页面上指定位置和基于关键字签章的功能。内容包括依赖管理、关键字搜索策略和实际的签章操作代码示例。
摘要由CSDN通过智能技术生成

1、pom依赖

<dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itextpdf</artifactId>
            <version>5.5.11</version>
        </dependency>

        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itext7-core</artifactId>
            <version>7.2.0</version>
        </dependency>

2、关键字信息查找

package com.example.study.demo.pdfSign;

import cn.hutool.core.collection.CollectionUtil;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfPage;
import com.itextpdf.kernel.pdf.PdfReader;
import com.itextpdf.kernel.pdf.canvas.parser.PdfCanvasProcessor;
import com.itextpdf.kernel.pdf.canvas.parser.listener.IPdfTextLocation;
import com.itextpdf.kernel.pdf.canvas.parser.listener.RegexBasedLocationExtractionStrategy;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


public class FindKey {

    /**
     * 获取关键字位置信息map
     * key为页数,value为当页关键字信息集合
     */
    public static Map<Integer, List<KeyWordInfo>> keyWordLocationMap(String input, String keyword) {
        Map<Integer, List<KeyWordInfo>> listMap;
        try(PdfReader reader = new PdfReader(input);PdfDocument pdfDocument = new PdfDocument(reader)) {
            int pageNumbers = pdfDocument.getNumberOfPages();
            listMap = new HashMap<>(pageNumbers);
            for (int i = 1; i <= pageNumbers; i++) {
                PdfPage page = pdfDocument.getPage(i);
                RegexBasedLocationExtractionStrategy strategy = new RegexBasedLocationExtractionStrategy(keyword);
                PdfCanvasProcessor canvasProcessor = new PdfCanvasProcessor(strategy);
                canvasProcessor.processPageContent(page);
                Collection<IPdfTextLocation> resultantLocations = strategy.getResultantLocations();
                //自定义结果处理
                if (!resultantLocations.isEmpty()) {
                    List<KeyWordInfo> keyWordInfoList = new ArrayList<>();
                    List<IPdfTextLocation> iPdfTextLocationList = CollectionUtil.newArrayList(resultantLocations);
                    for (int m = 0; m < iPdfTextLocationList.size(); m++) {
                        IPdfTextLocation item = iPdfTextLocationList.get(m);
                        Rectangle boundRectangle = item.getRectangle();
                        KeyWordInfo keyWordInfo = new KeyWordInfo();
                        keyWordInfo.setPage(i);
                        keyWordInfo.setX(boundRectangle.getX());
                        keyWordInfo.setY(boundRectangle.getY());
                        keyWordInfo.setWidth(boundRectangle.getWidth());
                        keyWordInfo.setHeight(boundRectangle.getHeight());
                        keyWordInfo.setText(item.getText());
                        keyWordInfo.setNum(m + 1);
                        System.out.println("关键字“" + keyword + "” 的坐标为 x: " + boundRectangle.getX() + "  ,y: " + boundRectangle.getY());
                        keyWordInfoList.add(keyWordInfo);
                    }
                    listMap.put(i, keyWordInfoList);
                }
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return listMap;
    }

}

package com.example.study.demo.pdfSign;

import lombok.Data;
@Data
public class KeyWordInfo{

    private float x;
    private float y;
    private float width;
    private float height;
    /**
     * pdf的页面
     */
    private int page;
    /**
     * 当前页面中第几个
     */
    private int num;
    private String text;

}

3、关键字签章、指定位置签章demo

package com.example.study.demo.pdfSign;

import cn.hutool.core.date.DateUtil;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Date;
import java.util.List;
import java.util.Map;


public class ItextTest {


    /**
     * 指定位置盖章
     */
    public static void main1(String[] args) throws Exception {
        String dateStr = DateUtil.format(new Date(),"yyyyMMdd-HHmm");
        String inputPdf = "D://test//pdf//test2.pdf";
        String outputPdf = "D://test//pdf//指定位置签章-itext-".concat(dateStr).concat(".pdf");
        String stampImage ="D://test//pdf//zhang.png";

        ByteArrayOutputStream memoryStream = readFileToMemoryStream(inputPdf);
        PdfReader reader = new PdfReader(memoryStream.toByteArray());
        PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(outputPdf));

        Image image = Image.getInstance(stampImage);
        //设置签字图片宽高
        image.scaleToFit(100, 100);

        PdfContentByte content;
        Rectangle pageSize;
        int pageCount = reader.getNumberOfPages();
        for(int i=1; i <= pageCount; i++) {
            pageSize = reader.getPageSizeWithRotation(i);
            content = stamper.getOverContent(i);
            //签章图片位置坐标
            float absoluteX = 10;
            float absoluteY = pageSize.getHeight() - image.getScaledHeight() - 10;
            image.setAbsolutePosition( absoluteX, absoluteY );
            content.addImage(image);
        }

        stamper.close();
        reader.close();
    }


    /**
     * 关键字盖章
     */
    public static void main(String[] args) throws IOException, DocumentException {
        String dateStr = DateUtil.format(new Date(),"yyyyMMdd-HHmm");
        String inputPdf = "D://test//pdf//test2.pdf";
        String outputPdf = "D://test//pdf//关键字签章-itext-".concat(dateStr).concat(".pdf");
        String stampImage ="D://test//pdf//zhang.png";
        // 要盖章的关键字
        String keyword = "张三看看";

        // 关键字位置信息map
        Map<Integer, List<KeyWordInfo>> map = FindKey.keyWordLocationMap(inputPdf,keyword);

        ByteArrayOutputStream memoryStream = readFileToMemoryStream(inputPdf);
        PdfReader pdfReader = new PdfReader(memoryStream.toByteArray());
        PdfStamper pdfStamper = new PdfStamper(pdfReader, Files.newOutputStream(Paths.get(outputPdf)));

        Image image = Image.getInstance(stampImage);
        //设置签字图片宽高
        image.scaleAbsolute(100, 100);

        int pageCount = pdfReader.getNumberOfPages();
        for(int i=1; i <= pageCount; i++) {
            PdfContentByte content = pdfStamper.getUnderContent(i);
            List<KeyWordInfo> list = map.get(i);
            for (KeyWordInfo keyWordInfo : list) {
                //签章图片位置坐标
                float absoluteX = keyWordInfo.getX() + keyWordInfo.getWidth()/2 - image.getScaledWidth()/2 ;
                float absoluteY = keyWordInfo.getY() + keyWordInfo.getHeight()/2 - image.getScaledHeight()/2;
                image.setAbsolutePosition(absoluteX, absoluteY);
                content.addImage(image);
            }
        }

        pdfStamper.close();
        pdfReader.close();
    }

    private static ByteArrayOutputStream readFileToMemoryStream(String filePath) throws IOException {
        ByteArrayOutputStream memoryStream = new ByteArrayOutputStream();
        // 缓冲区大小
        byte[] buffer = new byte[1024];
        try (FileInputStream fis = new FileInputStream(filePath)) {
            int bytesRead;
            while ((bytesRead = fis.read(buffer)) != -1) {
                memoryStream.write(buffer, 0, bytesRead);
            }
        }
        return memoryStream;
    }


}
 

  • 38
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
Java可以通过使用第三方库来实现PDF电子签章的功能。其中比较常用的有iText和PDFBox。 iText是一个广泛使用的PDF文档处理库,可以在PDF文档中添加数字签名。以下是使用iText实现PDF电子签章的步骤: 1. 加载PDF文件并创建签名区域 ``` PdfReader reader = new PdfReader("original.pdf"); FileOutputStream os = new FileOutputStream("signed.pdf"); PdfStamper stamper = PdfStamper.createSignature(reader, os, '\0'); PdfSignatureAppearance appearance = stamper.getSignatureAppearance(); appearance.setImage(Image.getInstance("signature.png")); appearance.setReason("I am the author"); appearance.setLocation("China"); ``` 2. 创建数字签名 ``` PrivateKey privateKey = (PrivateKey) keystore.getKey("alias", "password".toCharArray()); Certificate[] chain = keystore.getCertificateChain("alias"); PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED); dic.setReason(appearance.getReason()); dic.setLocation(appearance.getLocation()); dic.setContact(appearance.getContact()); dic.setDate(new PdfDate(appearance.getSignDate())); appearance.setCrypto(privateKey, chain, null, PdfSignatureAppearance.WINCER_SIGNED); appearance.setSignatureGraphic(Image.getInstance(signatureGraphic)); appearance.setRenderingMode(PdfSignatureAppearance.RenderingMode.GRAPHIC); appearance.setVisibleSignature(new Rectangle(36, 748, 144, 780), 1, "sig"); PdfSignature dic2 = new PdfSignature(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED); dic2.setReason(appearance.getReason()); dic2.setLocation(appearance.getLocation()); dic2.setContact(appearance.getContact()); dic2.setDate(new PdfDate(appearance.getSignDate())); PdfSignatureAppearance appearance2 = PdfStamper.createSignature(reader, null, '\0'); appearance2.setVisibleSignature(new Rectangle(36, 748, 144, 780), 1, "sig"); appearance2.setCrypto(privateKey, chain, null, PdfSignatureAppearance.WINCER_SIGNED); PdfSignature dic3 = new PdfSignature(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED); dic3.setReason(appearance.getReason()); dic3.setLocation(appearance.getLocation()); dic3.setContact(appearance.getContact()); dic3.setDate(new PdfDate(appearance.getSignDate())); appearance2.setSignatureGraphic(Image.getInstance(signatureGraphic)); appearance2.setRenderingMode(PdfSignatureAppearance.RenderingMode.GRAPHIC); PdfDictionary dic4 = new PdfDictionary(); dic4.put(PdfName.CONTENTS, new PdfString("test".getBytes())); ``` 3. 签名并保存PDF文件 ``` PdfSignature dic5 = new PdfSignature(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED); dic5.setReason(appearance.getReason()); dic5.setLocation(appearance.getLocation()); dic5.setContact(appearance.getContact()); dic5.setDate(new PdfDate(appearance.getSignDate())); appearance4.setCrypto(privateKey, chain, null, PdfSignatureAppearance.WINCER_SIGNED); appearance4.setSignatureGraphic(Image.getInstance(signatureGraphic)); appearance4.setRenderingMode(PdfSignatureAppearance.RenderingMode.GRAPHIC); PdfDictionary dic6 = new PdfDictionary(); dic6.put(PdfName.CONTENTS, new PdfString("test".getBytes())); PdfDictionary dic7 = new PdfDictionary(); dic7.put(PdfName.CONTENTS, new PdfString("test".getBytes())); ``` 以上就是使用iText实现PDF电子签章的基本步骤。值得注意的是,签章的过程中需要使用数字证书,确保签章的真实性和合法性。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值