首页 > 编程语言 >Java通过itext解析PDF中的关键字得到坐标进行插入印章图片或签名

Java通过itext解析PDF中的关键字得到坐标进行插入印章图片或签名

时间:2023-10-12 11:58:33浏览次数:42  
标签:Java text itextpdf itext PDF pdf import com public

需求

因需提高公司运转效率,提倡去无纸化操作,减少人力等前提;通过系统将审核通过后的pdf文档进行盖电子印章或电子签名等功能;
测试效果如下:

图1

图2

实现思路

因如上图1中,存在动态表格,所以文档的布局是随数据而变的,可能是多页,可能是一页,且内容上下浮动,所以得通过解析文档内容,通过关键字进行计算出关键字的坐标,再通过坐标进行实现电子印章图片的绝对定位;

代码实现

  1. 引入依赖
        <!-- itext5  -->
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itextpdf</artifactId>
            <version>5.5.9</version>
        </dependency>
        <!-- itext支持  -->
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itext-asian</artifactId>
            <version>5.2.0</version>
        </dependency>
  1. PdfUtils定位工具类

import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.parser.PdfReaderContentParser;
import java.io.IOException;

/**
 * Pdf定位工具类
 */
public class PdfUtils
{

    /**
     * @Author lcl
     * @Date 11:24 2023/10/12
     * @Description 用于供外部类调用获取关键字所在PDF文件坐标
     * @param filepath 文件路径
     * @param keyWords 关键词
     * @return float[] 坐标
     */
    public static float[] getKeyWordsByPath(String filepath, String keyWords)
    {
        float[] coordinate = null;
        try
        {
            PdfReader pdfReader = new PdfReader(filepath);
            coordinate = getKeyWords(pdfReader, keyWords);
        } catch (IOException e)
        {
            e.printStackTrace();
        }
        return coordinate;
    }

    /**
     * @Author lcl
     * @Date 11:26 2023/10/12
     * @Description 获取关键字所在PDF坐标
     * @param pdfReader 流
     * @param keyWords 关键词
     * @return float[] 坐标
     */
    public static float[] getKeyWords(PdfReader pdfReader, String keyWords)
    {
        float[] coordinate = null;
        int page = 0;
        try
        {
            int pageNum = pdfReader.getNumberOfPages();
            PdfReaderContentParser pdfReaderContentParser = new PdfReaderContentParser(pdfReader);
            CustomRenderListener renderListener = new CustomRenderListener();
            renderListener.setKeyWord(keyWords);
            for (page = 1; page <= pageNum; page++)
            {
                renderListener.setPage(page);
                pdfReaderContentParser.processContent(page, renderListener);
                coordinate = renderListener.getPcoordinate();
                if (coordinate != null)
                {
                    break;
                }
            }
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        return coordinate;
    }
}
  1. CustomRenderListener定位辅助类
import com.itextpdf.awt.geom.Rectangle2D.Float;
import com.itextpdf.text.pdf.parser.ImageRenderInfo;
import com.itextpdf.text.pdf.parser.RenderListener;
import com.itextpdf.text.pdf.parser.TextRenderInfo;

/**
 * @Author lcl
 * @Date 11:53 2023/10/12
 * @Description pdf关键词帮助类
 */
public class CustomRenderListener implements RenderListener
{

    private float[] pcoordinate = null;

    private String keyWord;

    private int page;

    public int getPage()
    {
        return page;
    }

    public void setPage(int page)
    {
        this.page = page;
    }

    public float[] getPcoordinate()
    {
        return pcoordinate;
    }

    public String getKeyWord()
    {
        return keyWord;
    }

    public void setKeyWord(String keyWord)
    {
        this.keyWord = keyWord;
    }

    @Override
    public void beginTextBlock() {}

    @Override
    public void endTextBlock() {}

    @Override
    public void renderImage(ImageRenderInfo arg0) {}

    @Override
    public void renderText(TextRenderInfo textRenderInfo)
    {
        String text = textRenderInfo.getText();
        if (null != text && text.contains(keyWord)) {
            Float boundingRectange = textRenderInfo.getBaseline().getBoundingRectange();
            pcoordinate = new float[3];
            pcoordinate[0] = boundingRectange.x;
            pcoordinate[1] = boundingRectange.y;
            pcoordinate[2] = page;
        }
    }
}
  1. 测试
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfGState;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import java.io.*;


public class TestUtils
{

    public static void main(String[] args) throws IOException, DocumentException
    {
        // 原文件
        File file = new File("C:\\Users\\Administrator\\Desktop\\JYX_QYZT\\test1.pdf");
        // 处理后的文件
        FileOutputStream outputStream = new     
        FileOutputStream("C:\\Users\\Administrator\\Desktop\\JYX_QYZT\\test2.pdf");
        // 读
        PdfReader reader = new PdfReader(new FileInputStream(file));
        // 获取关键词坐标
        float[] xyz = PdfUtils.getKeyWords(reader,"审核:");
        if (xyz == null)
        {
            return;
        }
        System.out.println("x:"+ xyz[0]);
        System.out.println("y:"+ xyz[1]);
        System.out.println("页码:"+ xyz[2]);
        PdfStamper stamper = new PdfStamper(reader, outputStream);
        // 将印章图片放在pdf文件的第?页
        PdfContentByte over = stamper.getOverContent((int) xyz[2]);
        // 需要插入的图片
        Image contractSealImg = Image.getInstance("http://192.168.8.116:9000/erp/bpm/scms/印章.png");
        // 保存状态
        over.saveState();
        // 图片处理
        PdfGState pdfGState = new PdfGState();
        // 给图片设置透明度,一般不需要
        pdfGState.setFillOpacity(0.8F);
        over.setGState(pdfGState);
        // 设置图片位置
        contractSealImg.setAbsolutePosition(xyz[0], xyz[1]);
        // 设置图片大小
        contractSealImg.scaleAbsolute(100, 100);
        // 将图片添加到pdf文件
        over.addImage(contractSealImg);
        over.restoreState();
        stamper.setFormFlattening(true);
        // 关闭流
        stamper.close();
        reader.close();
        outputStream.close();
    }
}

参考文章:https://www.cnblogs.com/alphajuns/p/12436332.html

标签:Java,text,itextpdf,itext,PDF,pdf,import,com,public
From: https://www.cnblogs.com/lin02/p/itextpdf.html

相关文章

  • 报错解决:java.security.InvalidKeyException: Illegal key size(微信支付v3遇到的问
    前言在使用微信支付v3生成jar包后本地测试没有问题在开发小程序支付功能的时候:本地开发好好的,放在linux服务器上运行时碰到报错原因是因为微信支付256位秘钥加密解密策略 可能会导致某些jdk的版本加密解密出现问题解决首先观察你这个目录下的文件根据文件内容做判断看下......
  • 为什么 Java 中“1000==1000”为false,而”100==100“为true?
    这是一个挺有意思的讨论话题。如果你运行下面的代码:Integera=1000,b=1000;System.out.println(a==b);//1Integerc=100,d=100;System.out.println(c==d);//2你会得到:falsetrue基本知识:我们知道,如果两个引用指向同一个对象,用表示它们......
  • Java 线程池
    目录线程池线程池创建方式通过ThreadPoolExecutor创建线程池ThreadPoolExecutor的总体设计ThreadPoolExecutor的继承关系ThreadPoolExecutor的运行机制ThreadPoolExecutor生命周期管理任务执行机制线程池线程池就是管理一系列线程的资源池。当有任务要处理时,直接从线程池......
  • Java word文本分词器简单使用
    1、引入依赖<dependency><groupId>org.apdplat</groupId><artifactId>word</artifactId><version>1.2</version></dependency>2、使用@OverridepublicList&l......
  • 87基于java的流浪动物领养系统设计与实现(配套lun文,PPT,可参考做毕业设计)
    本章节给大家带来一个基于java流浪动物领养系统设计与实现,可适用于流浪动物救助及领养管理系统,宠物教学、领养宠物、宠物认领、领养申请、动物认领信息,动物申请认领等等;项目背景科学技术日新月异的如今,计算机在生活各个领域都占有重要的作用,尤其在信息管理方面,在这样的大背景......
  • 炫酷转换:Java实现Excel转换为图片的方法
    摘要:本文由葡萄城技术团队原创并首发。转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具、解决方案和服务,赋能开发者。前言在实际开发过程中,经常会有这样的需求:将Excel表格或特定区域转换为图片,以便在其他软件中使用。而在Java开发中,借助于报表插件可以轻松地将工作......
  • 在JavaScript中,最高效的方法来深度克隆一个对象是什么?
    内容来自DOChttps://q.houxu6.top/?s=在JavaScript中,最高效的方法来深度克隆一个对象是什么?将JavaScript对象进行深度克隆的最有效方法是什么?我见过使用obj=eval(uneval(o));,但这是非标准的做法,仅被Firefox支持。我曾尝试过obj=JSON.parse(JSON.stringify(o));,但对效率......
  • java.lang.ClassNotFoundException org.apache.ibatis.io.Resources问题的解决
    问题描述时隔好久,再次使用mybatis框架写管理系统,运行时出现了这个问题;问题解决我看着我也导入了相关的依赖,然后就发现,原来是没有放入到libaray里面,只需要这么做就能搞定啦:打开项目里面的这里:将右边的需要的包双击即可加入进去啦!再次运行就不会报错啦~~......
  • JavaScript Library – YouTube Embedded、YouTube Player API、YouTube Data API
    YouTube EmbedVideo参考: Embedvideos&playlists它和 GoogleMapsEmbed 类似,是通过iframe完成的。<iframewidth="800"style="aspect-ratio:16/9"src="https://www.youtube.com/embed/vEZCoe9GJFk"title="粉色海洋"......
  • java 四种内部类
    四种内部类基本介绍:一个类的内部又完整嵌套了了另一个类结构,被嵌套的类称为内部类属性,方法,构造器,代码块,内部类类的五大成员内部类是学习的难点,同事也是重点,后面看底层源码时,有大量得到内部类1.定义在外部类的局部位置上(比如方法内):局部内部类(有类名)匿名内部类(没有类名......