itextpdf 找出PDF中 文字的坐标

news/2025/1/5 20:47:39/文章来源:https://www.cnblogs.com/vipsoft/p/18651734

目录
  • 添加引用
  • 添加工具类
  • 调用

找到位置,签名的话见:https://www.cnblogs.com/vipsoft/p/18644127

新项目可以尝试一下 iText 7 , 我这边是老项目所以还是继续使用 iText 5,主打够用
iText 5 没有直接提供获取文本精确位置的功能。它只能提取文本内容,而文本位置通常需要通过额外的解析和计算来确定。

思路:在同一行,且一些词是连续的,前后没有空白字符串,即认为是一个词
需要特殊处理:

  • “姓 名:” 中间有空格
  • 读取PDF时,有些肉眼看上去是一行的字,可能会被解析为多个,导致找不到满足条件的关键字

image

添加引用

<itextpdf.version>5.5.13</itextpdf.version>
<itext-asian.version>5.2.0</itext-asian.version><dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>${itextpdf.version}</version>
</dependency>
<!--没有这个的话,添加文字会报错-->
<dependency><groupId>com.itextpdf</groupId><artifactId>itext-asian</artifactId><version>${itext-asian.version}</version>
</dependency>

添加工具类

package com.vipsoft.web;import cn.hutool.core.util.StrUtil;
import com.itextpdf.text.pdf.parser.ImageRenderInfo;
import com.itextpdf.text.pdf.parser.RenderListener;
import com.itextpdf.text.pdf.parser.TextRenderInfo;
import com.itextpdf.awt.geom.Rectangle2D.Float;import java.util.ArrayList;
import java.util.List;public class KeyWordPositionListener implements RenderListener {/*** 用来存储页面上所有的词* - 排除连续空格*/private List<WordItem> allItems = new ArrayList<WordItem>();/*** 搜索关键词*/private String keyWord;/*** 是否是新的词*/private boolean newWord = false;/*** 记录上一个字符 -- 用于判断是否是一组词*/private WordItem prevItem = new WordItem();/*** 已找到的词信息*/private WordItem wordItem;public WordItem getWordItem() {return wordItem;}public void setKeyWord(String keyWord) {this.keyWord = keyWord;}@Overridepublic void beginTextBlock() {// TODO Auto-generated method stub}/*** 方法会在解析文本时被调用,它检查每个文本片段是否包含关键词,并记录其位置。** @param renderInfo*/@Overridepublic void renderText(TextRenderInfo renderInfo) {if (wordItem != null || StrUtil.isEmpty(keyWord)) {return;}// 读取PDF时,有些肉眼看上去是一行的字,可能会被解析为多个,导致找不到满足条件的关键字,这里做了简单的处理// 即如果一些词是连续的,前后没有空白字符串,即认为是一个词String content = renderInfo.getText().trim();Float textRectangle = renderInfo.getBaseline().getBoundingRectange();if (StrUtil.isEmpty(content)) {// 当前扫出来的是空字符串,视新一个新的词即将开始newWord = true;
//            System.out.println("扫出空的,跳过  x=" + textRectangle.getX() + " y=" + textRectangle.getY());return;}if (StrUtil.isEmpty(prevItem.getContent())) {// 这段可以不需要// prevItem 中还没有存内容的,当前文字也视为新的词newWord = true;
//            System.out.println("prevItem 中还没有存内容的,视为新词");}if (StrUtil.isNotEmpty(prevItem.getContent()) && (Math.abs((int) prevItem.getY() - (int) textRectangle.getY()) > 5)) {//Y 正负2内,视为同一行System.out.println("不在同一行:prevItem=" + prevItem.getContent() + " x=" + (int) prevItem.getX() + " y=" + (int) prevItem.getY());System.out.println("不在同一行:content=" + content + " x=" + (int) textRectangle.getX() + " y=" + (int) textRectangle.getY());System.out.println("当前内容和prevItem 不在同一行,视为新词");newWord = true;}if (newWord) {//重置System.out.println("重置 prevItem: " + prevItem.getContent());prevItem = new WordItem();}System.out.println("已扫到字:content=" + content + " x=" + textRectangle.getX() + " y=" + textRectangle.getY());String preContent = StrUtil.isNotEmpty(prevItem.getContent()) ? prevItem.getContent() : "";prevItem.setContent(preContent + content);prevItem.setX(textRectangle.getX());prevItem.setY(textRectangle.getY());if (prevItem.getContent().contains(keyWord)) {//System.out.println("找到了【" + keyWord + "】 " + prevItem.getContent() + " x= " + prevItem.getX() + " y= " + prevItem.getY());wordItem = prevItem;}newWord = false;}@Overridepublic void endTextBlock() {// TODO Auto-generated method stub}@Overridepublic void renderImage(ImageRenderInfo renderInfo) {// TODO Auto-generated method stub}}/*** 存储一个词的信息*/
class WordItem {private String content;private double x;private double y;... getters and setters ...
}

调用

@Test
void searchText() throws Exception {String filepath = "D:\\Report.pdf";String keyWord = "审核医生";int page = 1;PdfReader pdfReader = new PdfReader(filepath);//int pageNum = pdfReader.getNumberOfPages(); //循环没页PDF查找PdfReaderContentParser pdfReaderContentParser = new PdfReaderContentParser(pdfReader);KeyWordPositionListener renderListener = new KeyWordPositionListener();renderListener.setKeyWord(keyWord);pdfReaderContentParser.processContent(page, renderListener);WordItem wordItem = renderListener.getWordItem();if (wordItem == null) {System.out.println("没找到 " + keyWord);return;}System.out.println("找到了【" + keyWord + "】 " + wordItem.getContent() + " x= " + wordItem.getX() + " y= " + wordItem.getY());
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/863804.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Jmeter 进行websocket接口测试

什么是websocket协议? Websocket是基于tcp的一种全双通信协议,客户端与服务器之间通过websocket建立连接后,客户端和服务器之间会长时间保持连接状态(即长连接)。客户端可以向服务器发送数据,服务器也可以主动向客户端推送数据。与http协议不同的是http是tcp的单向通信协…

vscode下载vetur和vue-helper插件之后删除键(backspace)失效

最近我在学习前端的过程中,使用vscode下载的vue的插件:vetur和vue-helper这两个 但随后在写代码的时候发现删除键(backspace)不能使用,其他键都能正常使用,也可以用鼠标选中右键剪切/删除 最后发现是上面的插件会占用backspace按键作为插件的功能键 解决方法 点击左上角—…

使用 C# WPF 根据 SEGY 数据绘制二维地震图

一、引言 在地震勘探领域,SEGY(Society of Exploration Geophysicists Y-data)文件格式是常见的地震数据存储格式。对于地震数据的可视化,通常会将 SEGY 文件中的振幅数据通过图像进行展示,以便进行分析。本文将介绍如何使用 C# WPF 应用程序绘制基于 SEGY 数据的二维地震…

为什么浏览器打开的网页默认是英文显示?

最近在学习的时候遇到的问题,打开一些软件的官网默认都是英文(即使这些网站是国内做的)。 其中一个原因是浏览器的默认设置语言是英文 修改浏览器默认语言 以Google Chrome浏览器为例: 右上角三个点—>设置 左边找到“语言” 将中文置顶

LeetCode 762[二进制表示中质数个计算置位]

LeetCode 762[二进制表示中质数个计算置位]题目 链接 LeetCode 762[二进制表示中质数个计算置位] 详情实例提示题解 思路 两个条件: 1、二进制位为1 2、满足条件1的个数为质数首先 for 循环遍历区间for (int i = left; i < right + 1; i++){int iCount = 0;//二进制位为1的…

[Web Fronted] 前端框架: React

序部分开源项目是基于 Web 前端框架 React 构建的,有必要了解一二。避免一脸懵逼,不知道怎么修改相关代码和配置概述: React React 的简介React 起源于 Facebook 的内部项目因为该公司对市场上所有 JavaScript MVC 框架 都不满意,就决定自己写一套,用来架设 Instagram 的网…

15C++循环结构-while循环(2)——教学

1、while语句的应用; 2、双精度实数double及科学计数法; 3、分数化为小数一、while语句的应用 (第44课 角谷猜想)参考视频1 问题:对于每一个正整数,如果它是奇数,则对它乘3再加1,如果它是偶数,则对它除以2,如此循环,最终都能够得到1,这就是由日本数学家角谷静夫发现的…

Xshell 8 Build 0065中文免安装绿色版

前言 Xshell8是一个非常受欢迎的远程连接管理软件,它的界面简单易懂,用起来特别方便。能支持好多种连接方式,比如SSH1、SSH2、SFTP、TELNET等等,还有串行协议和其他一些高级功能,基本上你想连什么都能满足。而且,它还支持好多种不同的终端类型,比如VT100、VT220、XTERM、…

大语言模型提示技巧(四)-文本概括

文本概括是大语言模型的常用功能之一,我们总结一段文字、一篇文章的主要内容,一篇论文的摘要,甚至一本书的简介都属于文本概括的范畴。文本概括是大语言模型的常用功能之一,我们总结一段文字、一篇文章的主要内容,一篇论文的摘要,甚至一本书的简介都属于文本概括的范畴。…

软件设计师考试知识点

https://www.cnblogs.com/mh20131118/p/11334612.html https://www.cnblogs.com/blog-cjz/p/16005106.html 本人已将笔记、历年真题与解析、备考方法整理压缩至【百度网盘】,需要资源的同学可以通过点击下面云盘链接进行保存下载。链接失效的话请在文章下面评论或私信我,我看…

DVWA靶场Insecure CAPTCHA(不安全验证)漏洞所有级别通关教程及源码审计

Insecure CAPTCHA(不安全验证) Insecure CAPTCHA(不安全验证)漏洞指的是在实现 CAPTCHA(完全自动化公共图灵测试区分计算机和人类)机制时,未能有效保护用户输入的验证信息,从而使得攻击者能够绕过或破解该验证机制。这类漏洞通常出现在网络应用程序中,目的是防止自动化…