Java基础、中级、高级、架构面试资料

Java 实现 pdf 合同文件自动签章

JAVA herman 60浏览
公告:“业余草”微信公众号提供免费CSDN下载服务(只下Java资源),关注业余草微信公众号,添加作者微信:xttblog2,发送下载链接帮助你免费下载!
本博客日IP超过2000,PV 3000 左右,急需赞助商。
极客时间所有课程通过我的二维码购买后返现24元微信红包,请加博主新的微信号:xttblog2,之前的微信号好友位已满,备注:返现
受密码保护的文章请关注“业余草”公众号,回复关键字“0”获得密码
所有面试题(java、前端、数据库、springboot等)一网打尽,请关注文末小程序
视频教程免费领
腾讯云】1核2G5M轻量应用服务器50元首年,高性价比,助您轻松上云

自动签章的公告、合同文件等形式的文档在公司中有非常多的使用场景。随着电子签章的流行,越来越多的公司,才有这些功能。基于此,本文使用 Java 来实现 pdf 合同文件自动签章。

本文只是一个 demo,若需完成的细节功能,可以加我微信:xmtxtt,送给爱学习研究的网友们。

下面开始正文。

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>

关键字信息查找

package com.xttblog.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.xttblog.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;

}

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

package com.xttblog.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;  
    }
}

效果

实现思路总结

为了实现“pdf盖章”,我们需要按照以下步骤进行操作。

  1. 取原始pdf文件
  2. 读取盖章图片
  3. 在pdf文件中指定位置盖章
  4. 保存新的pdf文件

读取原始pdf文件

首先,我们需要读取原始的pdf文件。我们可以使用Apache PDFBox、itextpdf等库来实现这一步。

// 导入PDFBox库import org.apache.pdfbox.pdmodel.PDDocument;import org.apache.pdfbox.pdmodel.PDPage;// 读取pdf文件PDDocument document = PDDocument.load(new File("original.pdf"));

读取盖章图片

接下来,我们需要读取用于盖章的图片。我们可以使用Java ImageIO库来实现这一步。

// 导入ImageIO库import javax.imageio.ImageIO;import java.awt.image.BufferedImage;// 读取盖章图片BufferedImage stampImage = ImageIO.read(new File("stamp.png"));

在pdf文件中指定位置盖章

现在,我们需要在pdf文件中的指定位置盖章。我们可以使用PDFBox、itextpdf等库来实现这一步。

// 获取pdf页面PDPage page = document.getPage(0);// 在指定位置盖章// 假设在(100, 100)位置盖章page.getContents().add(new PDStamp(stampImage, 100, 100));

保存新的pdf文件

最后,我们需要保存新的pdf文件。我们可以使用PDFBox、itextpdf等库来实现这一步。

// 保存新的pdf文件document.save("stamped.pdf");document.close();

整体来说,都是比较简单的。比较关键的是要找出关键字位置。

业余草公众号

最后,欢迎关注我的个人微信公众号:业余草(yyucao)!可加作者微信号:xttblog2。备注:“1”,添加博主微信拉你进微信群。备注错误不会同意好友申请。再次感谢您的关注!后续有精彩内容会第一时间发给您!原创文章投稿请发送至532009913@qq.com邮箱。商务合作也可添加作者微信进行联系!

本文原文出处:业余草: » Java 实现 pdf 合同文件自动签章