Java实现图章或签名插在pdf的固定位置

 更新时间:2023年10月20日 09:52:07   作者:一纸红尘轻似梦  
使用Java技术在word转换成pdf过程中实现将图章或者签名插入在pdf中,并生成带图章或者签名的pdf,来完成某些特定场景的需求,文中有详细的代码示例,需要的朋友可以参考下

提示:以下是本篇文章正文内容,下面案例本人亲自验证过,并已解决该需求

一、引入pom依赖

  • 引入pdf插入图章的依赖包
		 <!--pdf转图片-->
        <dependency>
            <groupId>org.apache.pdfbox</groupId>
            <artifactId>fontbox</artifactId>
            <version>2.0.12</version>
        </dependency>
        <dependency>
            <groupId>org.apache.pdfbox</groupId>
            <artifactId>pdfbox</artifactId>
            <version>2.0.12</version>
        </dependency>

二、编写插入图章或者签名位置的类

  • 创建PdfBoxKeyWordPosition类并继承PDFTextStripper
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;
import org.apache.pdfbox.text.TextPosition;
import java.io.*;
import java.util.ArrayList;
import java.util.List;

public class PdfBoxKeyWordPosition extends PDFTextStripper {

    // 关键字字符数组
    private char[] key;
    // PDF文件路径
    private String pdfPath;
    // 坐标信息集合
    private List<float[]> list = new ArrayList<float[]>();
    // 当前页信息集合
    private List<float[]> pagelist = new ArrayList<float[]>();
    // 有参构造方法
    public PdfBoxKeyWordPosition(String keyWords, String pdfPath) throws IOException {
        super();
        super.setSortByPosition(true);
        this.pdfPath = pdfPath;
        char[] key = new char[keyWords.length()];
        for (int i = 0; i < keyWords.length(); i++) {
            key[i] = keyWords.charAt(i);
        }
        this.key = key;
    }
    public char[] getKey() {
        return key;
    }
    public void setKey(char[] key) {
        this.key = key;
    }
    public String getPdfPath() {
        return pdfPath;
    }
    public void setPdfPath(String pdfPath) {
        this.pdfPath = pdfPath;
    }
    // 获取坐标信息
    public List<float[]> getCoordinate() throws IOException {
        try {
            document = PDDocument.load(new File(pdfPath));
            int pages = document.getNumberOfPages();
            for (int i = 1; i <= pages; i++) {
                pagelist.clear();
                super.setSortByPosition(true);
                super.setStartPage(i);
                super.setEndPage(i);
                Writer dummy = new OutputStreamWriter(new ByteArrayOutputStream());
                super.writeText(document, dummy);
                for (float[] li : pagelist) {
                    li[2] = i;
                }
                list.addAll(pagelist);
            }
            return list;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (document != null) {
                document.close();
            }
        }
        return list;
    }

    // 获取坐标信息
    @Override
    protected void writeString(String string, List<TextPosition> textPositions) throws IOException {
        for (int i = 0; i < textPositions.size(); i++) {
            // text得到pdf这一行中的汉字,同时下面有判断这一行字的长度,防止关键字在文中多次出现
            String text = textPositions.toString().replaceAll("[^\u4E00-\u9FA5]", "");
            String str = textPositions.get(i).getUnicode();
            if (str.equals(key[0] + "")) {
                int count = 0;
                for (int j = 0; j < key.length; j++) {
                    String s = "";
                    try {
                        s = textPositions.get(i + j).getUnicode();
                    } catch (Exception e) {
                        s = "";
                    }
                    if (s.equals(key[j] + "")) {
                        count++;
                    }
                }
                if (count == key.length) {
                    float[] idx = new float[3];
                    // 需要进行一些调整 使得章盖在字体上
                    // X坐标 在这里加上了字体的长度,也可以直接 idx[0] = textPositions.get(i).getX()
                    idx[0] = textPositions.get(i).getX();
                    // Y坐标 在这里减去的字体的长度,也可以直接 idx[1] = textPositions.get(i).getPageHeight()-textPositions.get(i).getY()
                    idx[1] = textPositions.get(i).getPageHeight()-textPositions.get(i).getY();
                    System.out.println("x=" + idx[0] + ",y=" + idx[1]);
                    pagelist.add(idx);
                }
            }
        }
    }
}

三、编写插入图章或者签名位置的方法

/**
     * 说明:将图章插入到pdf上
     * @param pdfPath  pdf的路径:C:\Users\user\11134731700024.pdf
     * @param image  图片路径:C:\Users\user\131123.jpg
     * @throws IOException
     */
  public static void operate(String pdfPath,String image) throws IOException {
        File file = new File(pdfPath);
        PDDocument doc = PDDocument.load(file);
        String keyWords = "插入到pdf的固定字体"; // 修改成你需要插入的位置
        PDImageXObject pdImage = PDImageXObject.createFromFile(image, doc);
        PdfBoxKeyWordPosition pdf = new PdfBoxKeyWordPosition(keyWords, pdfPath);
        PDPageContentStream contentStream = null;
        List<float[]> list = pdf.getCoordinate();
        // 多页pdf的处理
        for (float[] fs : list) {
            PDPage page = doc.getPage((int)fs[2]-1);
            float x = fs[0];
            float y = fs[1];
            contentStream = new PDPageContentStream(doc, page, true, true);
            contentStream.drawImage(pdImage, x-11, y-35,112,112);
            contentStream.close();
        }
        doc.save(pdfPath);
        doc.close();

    }

 	/**
     * 插入签名
     * @param pdfPath  pdf的路径:C:\Users\user\11134731700024.pdf
     * @param keyWords 签名修改成你需要签名的地方(如:传入张三就会盖在张三上)
     * @param image     签名图片 C:\Users\user\131123.jpg
     * @throws IOException
     */
    public static void autograph(String pdfPath, String keyWords, String image) throws IOException {
        File file = new File(pdfPath);
        PDDocument doc = PDDocument.load(file);
        PDImageXObject pdImage = PDImageXObject.createFromFile(image, doc);
        PdfBoxKeyWordPosition pdf = new PdfBoxKeyWordPosition(keyWords, pdfPath);
        PDPageContentStream contentStream = null;
        List<float[]> list = pdf.getCoordinate();
        // 多页pdf的处理
        for (float[] fs : list) {
            PDPage page = doc.getPage((int)fs[2]-1);
            float x = fs[0];
            float y = fs[1];
            contentStream = new PDPageContentStream(doc, page, true, true);
            contentStream.drawImage(pdImage, x+36, y-2,35,20);
            contentStream.close();
        }

        doc.save(pdfPath);
        doc.close();

    }





四、测试两个方法

public static void main(String[] args) throws IOException {
        System.out.println("开始图章插入");
        operate("C:\\Users\\user\\Desktop\\11134731700024.pdf", "C:\\Users\\user\\Desktop\\131123.jpg");
        System.out.println("插入结束");
    System.out.println("开始签名插入");
        autograph("C:\\Users\\user\\Desktop\\11134731700024.pdf","插入签名的位置(pdf上的文字)", "C:\\Users\\user\\123456789\\131123.jpg");
    }
    System.out.println("结束签名插入");

出现坐标插入成功。打开文件就可以看到了

到此这篇关于Java实现图章或签名插在pdf的固定位置的文章就介绍到这了,更多相关Java图章或签名插在pdf内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Spring bean对象实例化实现过程图解

    Spring bean对象实例化实现过程图解

    这篇文章主要介绍了Spring bean对象实例化实现过程图解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-07-07
  • 一文详解Java抽象类到底有多抽象

    一文详解Java抽象类到底有多抽象

    这篇文章主要介绍了一文详解Java抽象类到底有多抽象,抽象方法所在的类必须是抽象类,子类若继承了一个抽象类,就必须覆写父类的所有抽象方法,这里的子类是普通类,是强制要求覆写所有抽象方法,但是如果子类也是一个抽象类,那么就可以不覆写
    2022-06-06
  • java9学习系列之在docker中如何运行java9

    java9学习系列之在docker中如何运行java9

    最近在学习java9,所以将学习中遇到的一些知识点分享给大家,下面这篇文章主要给大家介绍了java9学习系列之在docker中如何运行java9的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下。
    2017-09-09
  • Eclipse的Debug调试技巧大全(总结)

    Eclipse的Debug调试技巧大全(总结)

    这篇文章主要介绍了Eclipse的Debug调试技巧大全(总结),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-12-12
  • jetbrain fleet对标vscode实际操作

    jetbrain fleet对标vscode实际操作

    Gradle是一个基于Apache Ant和Apache Maven概念项目自动化构建开源工具,jetbrain家的fleet(已获得预览权限)直接对标vscode , fleet有望超过vscode吗?今天我们实际操作下
    2021-12-12
  • 微信企业号 根据错误码返回错误信息类封装

    微信企业号 根据错误码返回错误信息类封装

    这篇文章主要介绍了微信企业号 根据错误码返回错误信息类封装的相关资料,需要的朋友可以参考下
    2016-10-10
  • Java多线程实现简易微信发红包的方法实例

    Java多线程实现简易微信发红包的方法实例

    这篇文章主要给大家介绍了关于Java多线程实现简易微信发红包的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01
  • Java动态规划之丑数问题实例讲解

    Java动态规划之丑数问题实例讲解

    这篇文章主要介绍了Java动态规划之丑数问题实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2022-09-09
  • MyBatis 探秘之#{} 与 ${} 参传差异解码(数据库连接池筑牢数据交互根基)

    MyBatis 探秘之#{} 与 ${} 参传差异解码(数据库连接池筑牢数据交互

    本文详细介绍了MyBatis中的`#{}`和`${}`的区别与使用场景,包括预编译SQL和即时SQL的区别、安全性问题,以及如何正确使用数据库连接池来提高性能,感兴趣的朋友一起看看吧
    2024-12-12
  • Spring注解和同步锁不能同步问题解决

    Spring注解和同步锁不能同步问题解决

    这篇文章主要介绍了Spring注解和同步锁不能同步问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-12-12

最新评论