新网站做seo优化步骤/免费智能seo收录工具
前言
临时接到一个紧急需要处理的事项。业务侧一个同事有几千个PDF文件需要整理:需要从文件中的指定位置获取对应的编号和地址。
要的急,工作量大。所以就问到技术部有没有好的解决方案。
问技术的话就只能写个demo跑下了。
解决办法
1. 研究下PDF文档,找出解决方案
PDF的文档看起来比较简单,因为只是需要读取两个坐标位置的文本内容,而且位置相对固定。所以就直接用java的第三方库pdfbox来操作PDF文档。
2. 找个能操作PDF的第三方库pdfbox。
- 先下载pdfbox的jar包。
官网介绍 - pdfbox能干啥:
-
pdfbox是Apache软件基金会的一个开源项目,它提供API和工具来处理PDF文档。
-
pdfbox是Apache PDFBox的Java版本,它提供了一个类库,用于读取,写入,转换和创建PDF文档。
-
pdfbox支持处理各种PDF特性,如文本,字体,图像,表单字段,注释,书签,页面布局等。
-
pdfbox还提供了对加密和数字签名PDF文档的支持,以及对PDF文档的提取和合并。
-
pdfbox还提供了对PDF文档的验证,签名验证,加密验证和数字签名的支持。
-
PDFBox是一个用于处理PDF文档的Java库。它提供了一组功能强大的API,可以用于创建、修改和提取PDF文档的内容。PDFBox可以用于各种用途,包括生成PDF文档、提取文本和图像、合并和拆分PDF文件、添加水印和书签等。
-
PDFBox支持处理各种PDF特性,如文本、字体、图像、表单字段、注释、书签、页面布局等。它还提供了对加密和数字签名PDF文档的支持,以及对PDF文档的高级操作,如提取文本位置信息、提取图像和字体等。
-
3. maven加载包
pdfbox有三个大的版本,每个版本差异较大,这个时候如果要引入的时候,要主要版本了,否则demo就有可能跑不起来。作为新时代的青年,肯定要与时俱进。3.0肯定是要用上的。
3. 先验证下第三方库是否可行
下载jar包后,直接用java代码跑下demo。 demo读取pdf文档内容并输出文本数据到控制台
import org.apache.pdfbox.pdmodel.PDDocument;import org.apache.pdfbox.text.PDFTextStripper;import java.io.File;import java.io.IOException;public class PDFBoxDemo {public static void main(String[] args) throws IOException {PDDocument document = PDDocument.load(new File("D:\\pdf\\test.pdf"));PDFTextStripper stripper = new PDFTextStripper();String text = stripper.getText(document);System.out.println(text);document.close();}}
发现demo跑起来后,报错。
原因是因为demo是2.0的版本,而当前的jar包是3.0的版本。PDDocument.load这个修改为Loader.load就OK了。
接下来,就是如何获取到指定坐标位置的文本内容。
4. 确认文本在PDF文档中的坐标位置。
确认PDF文本坐标一般有两种方案。
1. 代码校验(最精准)
先用demo跑下,看下是否可以读取到指定坐标位置的文本内容。
/*** 获取文档坐标* @param file PDF文件对象* @param sourceTex 匹配的字符* @return 坐标*/public static Point getPoint(File file,String sourceTex) {Point point = new Point();//获取文档坐标try {PDDocument document = Loader.loadPDF(file);PDFTextStripper textStripper = new PDFTextStripper() {@Overrideprotected void writeString(String text, List<TextPosition> textPositions) throws IOException {if (text.contains(targetText)) {TextPosition textPositionStart = textPositions.get(0);TextPosition textPositionEnd = textPositions.get(textPositions.size()-1);point.setX(textPositionStart.getX());point.setY(textPositionStart.getY()); }}};textStripper.setSortByPosition(true);textStripper.setStartPage(1);textStripper.setEndPage(document.getNumberOfPages());textStripper.getText(document);document.close();} catch (IOException e) {e.printStackTrace();}return point;}
跑完demo后,发现可以读取到指定坐标位置的文本内容。
这里会有个小问题,就是返回的坐标点有的会有小数。因为当前返回类型float,所以需要转换成int。
2. 最直接粗暴的方法。
1. 福昕PDF文档工具。2. 直接用福昕PDF文档定位工具定位坐标。说实话,开发比较少用这种方式,因为感觉有点lower(其实是自己不太会用)
5. 整个demo先验证第三方库是否可行。
拿1个文件试试水
public static void main(String[] args) {String filePath = "D:\\test\\test.pdf";try {PDDocument document = Loader.loadPDF(file);PDFTextStripperByArea textStripper = new PDFTextStripperByArea ();Rectangle rectangle = new Rectangle(80,120, 250,10);String regionName = "regionName";textStripper.addRegion(regionName, rectangle);PDPage page = document.getPage(0);textStripper.extractRegions(page);String text = textStripper.getTextForRegion(regionName);System.out.println(text);textStripper.setSortByPosition(true);textStripper.setStartPage(1);textStripper.setEndPage(document.getNumberOfPages());textStripper.getText(document);document.close();}catch (IOException e) {e.printStackTrace();}}
结果能够正常输出对应的文本内容。
6. 整活上代码。
奉上全部demo代码
package com.example.demo;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.alibaba.fastjson2.JSON;
import org.apache.pdfbox.Loader;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.text.PDFTextStripper;
import org.apache.pdfbox.text.PDFTextStripperByArea;
import org.apache.pdfbox.text.TextPosition;
import org.springframework.boot.test.autoconfigure.data.cassandra.DataCassandraTest;import java.awt.*;
import java.awt.geom.Rectangle2D;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.List;
import java.util.stream.Collectors;/*** Desc: 验证pdfbox的可行性** @author admin* @date since 2023/8/8 18:44*/public class PdfDemo {//要匹配的位置内容点private static final String[] target= {"name", "address"};public static void main(String[] args) {ExcelWriter excelWriter= ExcelUtil.getWriter("D:\\test\\pdf\\test.xls");String folderPath = "D:\\test\\pdf";File folder = new File(folderPath);if (folder.exists() && folder.isDirectory()) {List<Map<String,Object>> mps = listPdfFiles(folder);excelWriter.write(mps, true);} else {System.out.println("Invalid folder path.");}excelWriter.close();}/*** 获取pdf文件列表** @param folder 文件夹* @return {@code List<Map<String,Object>>}*/private static List<Map<String,Object>> listPdfFiles(File folder) {List<Map<String,Object>> mps = new ArrayList<>();File[] files = folder.listFiles();if (files != null) {for (File file : files) {if (file.isDirectory()) {listPdfFiles(file); // 递归调用,处理子文件夹} else {String fileName = file.getName();if (fileName.toLowerCase().endsWith(".pdf")) {mps.add(getLineData(file));}}}}return mps;}/*** 行数据** @param file 文件* @return {@code Map<String,Object>}*/public static Map<String,Object> getLineData(File file){Map<String,Object> lineData = new HashMap<>(target.length+2);List<Point> pointList = getPoint(file);String[] arr= getPointValue(file, pointList.stream().map(s -> new Rectangle(s.getX(), s.getY(), 260, 10)).toArray(Rectangle[]::new));if(arr.length>=target.length) {for(int i=0;i<target.length;i++){lineData.put(target[i], arr[i]);}lineData.put("fileName", file.getName().toLowerCase().replace(".pdf", ""));}return lineData;}/*** 获得PDF指定坐标点文本值** @param file 文件* @param rectangles 矩形坐标* @return {@code String[]}*/public static String[] getPointValue( File file,Rectangle... rectangles){String[] textArr = new String[rectangles.length];// String text="";try {PDDocument document = Loader.loadPDF(file);PDFTextStripperByArea textStripper = new PDFTextStripperByArea ();for(int i = 0; i < rectangles.length;i++ ) {Rectangle rectangle =rectangles[i];String regionName = "regionName"+rectangle.getX()+rectangle.getY();textStripper.addRegion(regionName, rectangle);PDPage page = document.getPage(0);textStripper.extractRegions(page);// 获取区域的textString text = textStripper.getTextForRegion(regionName);text = text.replace("\u0000","-").replace(" ","");System.out.println(">>text"+text);textArr[i]=text;}textStripper.setSortByPosition(true);textStripper.setStartPage(1);textStripper.setEndPage(document.getNumberOfPages());textStripper.getText(document);document.close();}catch (IOException e) {e.printStackTrace();}return textArr;}public static List<Point> getPoint( File file){List<Point> pointList=new ArrayList<>();try {PDDocument document = Loader.loadPDF(file);PDFTextStripper textStripper = new PDFTextStripper() {@Overrideprotected void writeString(String text, List<TextPosition> textPositions) throws IOException {for(String target:target){if (text.contains(target)) {Point point = new Point();TextPosition textPositionEnd = textPositions.get(textPositions.size() - 1);point.setX((int) textPositionEnd.getEndX());point.setY((int) textPositionEnd.getY());pointList.add(point);}}}};textStripper.setSortByPosition(true);textStripper.setStartPage(1);textStripper.setEndPage(document.getNumberOfPages());textStripper.getText(document);document.close();} catch (IOException e) {e.printStackTrace();}System.out.println(">>>>>pointList" + JSON.toJSONString(pointList));return pointList;}
}
7. 验证代码可行性
整理出来的excel,检查里面有些空格没有处理,就让业务自己批量替换一下。
因为代码只是一次性用的,就没有怎么进行封装了。总体来讲业务同事比较满意。
结论
- 第三方库pdfbox可以操作PDF文档。3.0版本之后和历史版本相差比较大,最好先阅读下源码。
- 坐标定位的话,可以用第三方也可以代码定位
- 如果代码后续想复用的话,最好抽离出公共方法
- 文件比较多的情况下,建议增加多线程处理。
相关文章:

Java实战:高效提取PDF文件指定坐标的文本内容
前言 临时接到一个紧急需要处理的事项。业务侧一个同事有几千个PDF文件需要整理:需要从文件中的指定位置获取对应的编号和地址。 要的急,工作量大。所以就问到技术部有没有好的解决方案。 问技术的话就只能写个demo跑下了。 解决办法 1. 研究下PDF文档…...

centos磁盘满了,怎么清理大文件
当CentOS磁盘空间不足时,可以通过以下步骤清理大文件: 确定磁盘使用情况:运行以下命令查看磁盘使用情况和占用空间最大的文件或目录: df -h du -sh /*清理临时文件:运行以下命令清理临时文件夹中的过期数据ÿ…...

AIGC:【LLM(四)】——LangChain+ChatGLM:本地知识库问答方案
文章目录 一.文件加载与分割二.文本向量化与存储1.文本向量化(embedding)2.存储到向量数据库 三.问句向量化四.相似文档检索五.prompt构建六.答案生成 LangChainChatGLM项目(https://github.com/chatchat-space/langchain-ChatGLM)实现原理如下图所示 (与基于文档的问答 大同小…...

企业在线产品手册可以这样做,小白也能轻松上手
企业在线产品手册是为了方便用户了解和使用企业产品而设计的一种在线文档。它的目标是提供清晰、简洁、易于理解的产品信息,使用户能够轻松上手,并最大限度地发挥产品的功能和优势。 如何设计企业在线产品手册的建议和步骤: 目标用户分析&am…...

crypto-js中AES的加解密封装
在项目中安装依赖: npm i crypto-js在使用的页面引入: import CryptoJS from crypto-jscrypto-js中AES的加解密简单的封装了一下: //加密const KEY 000102030405060708090a0b0c0d0e0f // 秘钥 这两个需要和后端统一const IV 8a8c8fd8fe3…...

【计算机视觉】MoCo v2 讲解
在阅读本篇之前建议先学习: 【计算机视觉】MoCo 讲解 【计算机视觉】SimCLR 讲解 MoCo v2 论文信息 标题:Improved Baselines with Momentum Contrastive Learning 作者:Xinlei Chen 期刊: 发布时间与更新时间:2020.03.09 主题:计算机视觉、对比学习 arXiv:[2003.04297]…...

如何解决亚马逊银行账户验证问题?来看看这些技巧吧!
在开亚马逊店铺的过程中,想必不少卖家遇到了这么一个问题,那就是亚马逊卖家有的时候会收到亚马逊银行账户验证的消息,主要就是用来确保亚马逊卖家账户收款信息的安全性。 亚马逊银行账户验证是一个十分重要的问题,如果说这些问题…...

Android多渠道打包+自动签名工具 [原创]
多渠道打包自动签名工具 [原创] github源码:github.com/G452/apk-packer 如果觉得有帮助可以点个小星星支持一下,万分感谢! 使用步骤: 1、在apk-packer.exe目录内放入打包需要的配置: 1)签名文件.jks2&am…...

nodejs实现解析chm文件列表,无需转换为PDF文件格式,在线预览chm文件以及目录,不依赖任何网页端插件
特性: 1、支持任意深度的chm文件解析 2、解析后内容结构转换为tree数据呈现 3、点击树节点可以在html实时查看数据 4、不依赖任何浏览器端插件,兼容性较好 nodejs端核心代码 const $g = global.SG.$g, fs = global.SG.fs, router = global.SG.router, xlsx = global.SG.xl…...

.net core background service
之前聊过如何在.net core 中添加后台服务, 当时使用的是BackgroundService的形式,这里使用IHostedService接口 namespace oneModelMultiTable.BackgroundService {public class EllisTest : IHostedService, IDisposable{private readonly ILogger<EllisTest>…...

前端开发的工作职责精选【10篇】
前端开发的工作职责1 1、使用Divcss并结合Javascript负责产品的前端开发和页面制作; 2、熟悉W3C标准和各主流浏览器在前端开发中的差异,能熟练运用DIVCSS,提供针对不同浏览器的前端页面解决方案; 3、负责相关产品的需求以及前端程序的实现,…...

SpringBoot 升级内嵌Tomcat
SpringBoot 更新 Tomcat 最近公司的一个老项目需要升级下Tomcat,由于这个项目我完全没有参与,所以一开始我以为是一个老的Tomcat项目,升级它的Tomcat依赖或者是Tomcat容器镜像,后面发现是一个SpringBoot项目,升级的是…...

react搭建在线编辑html的站点——引入grapes实现在线拖拉拽编辑html
文章目录 ⭐前言⭐搭建react ts项目⭐引入grapes 插件⭐结束 ⭐前言 大家好,我是yma16,本文分享关于react搭建在线编辑html的站点。 react 发展历史 React是由Facebook开发的一种JavaScript库,用于构建用户界面。React最初发布于2013年&…...

Nginx反向代理服务配置和负载均衡配置
nginx反向代理服务配置 node1:128 node2:135 node3:130 node4:132 node2、node3、node4已安装nginx nginx安装可查看https://blog.csdn.net/HealerCCX/article/details/132089836?spm1001.2014.3001.5502 [rootnode3 ~]# yum i…...

react钩子函数理解
React钩子(Hooks)是React 16.8版本引入的一种特性,用于在无需编写类组件的情况下,在函数组件中添加状态管理和其他React特性。React钩子解决了函数组件在处理状态、副作用和代码复用方面的一些问题,使得代码更加清晰、…...

医疗保健中的 NLP:实体链接
一、说明 HEalthcare和生命科学行业产生大量数据,这些数据是由合规性和监管要求,记录保存,研究论文等驱动的。但随着数据量的增加,搜索用于研究目的的必要文件和文章以及数据结构成为一个更加复杂和耗时的过程。例如,如…...

java编程规范
一、时间格式为什么有大写有小写呢? new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");为了区分月份和分钟,用大写M代表月份,小写m代表分钟 而大写的H代表24小时制,小写h代表12小时制 二、下面的程序判断等值的方式&…...

合宙Air724UG LuatOS-Air script lib API--sim
sim Table of Contents sim sim.getIccid() sim.getImsi() sim.getMcc() sim.getMnc() sim.getStatus() sim.setQueryNumber(flag) sim.getNumber() sim.setId(id, cbFnc) sim.getId() sim 模块功能:查询sim卡状态、iccid、imsi、mcc、mnc sim.getIccid() 获取sim卡…...

【网络基础实战之路】基于三个分公司的内网搭建并连接运营商的实战详解
系列文章传送门: 【网络基础实战之路】设计网络划分的实战详解 【网络基础实战之路】一文弄懂TCP的三次握手与四次断开 【网络基础实战之路】基于MGRE多点协议的实战详解 【网络基础实战之路】基于OSPF协议建立两个MGRE网络的实验详解 PS:本要求基于…...

(Python)Requests+Pytest+Allure接口自动化测试框架从0到1搭建
前言:本文主要介绍在企业使用Python搭建接口自动化测试框架,数据驱动读取excel表里的数据,和数据库方面的交互,包括关系型数据库Mysql和非关系型数据库MongDB,连接数据库,读取数据库中数据,最后…...

实现vuex数据持久化处理
(创作不易,感谢有你,你的支持,就是我前行的最大动力,如果看完对你有帮助,请留下您的足迹) 目录 前言: 方案一 localStorage 介绍 值 示例 JSON.stringify() 介绍 语法 参数 返…...

Vue-系统登录进入首页后禁用浏览器返回键
解决方法 mounted() {history.pushState(null, null, document.URL)window.addEventListener(popstate, this.goBack, false) }, destroyed() {// 清除popstate事件 否则会影响到其他页面window.removeEventListener(popstate, this.goBack, false) }, methods: {goBack() {hi…...

Hadoop理论及实践-HDFS的Namenode及Datanode(参考Hadoop官网)
HDFS有什么特点,被设计做什么 Hadoop分布式文件系统(HDFS)被设计成适合运行在通用硬件(commodity hardware)上的分布式文件系统。有一下几个特点: HDFS是一个高度容错性的系统,具有高容错、高可靠性、高扩展性的特点,适合部…...

第四十九天
●兼容性测试:主要是检查软件在不同的硬件平台、软件平台上是否可以正常的运行。 •兼容测试测什么? Android碎片化严重,每一款游戏/应用在上线之前,都会做一轮覆盖一定机型量的兼容性测试。 在产品面对海量用户之前࿰…...

ArcGIS Pro简介下载安装地址
ArcGIS Pro简介 ArcGIS Pro是一款功能强大的地理信息系统(GIS)软件,由Esri开发。它为用户提供了一种直观、灵活且高效的方式来处理、分析和可视化地理数据。ArcGIS Pro具有现代化的用户界面和工作流程,使用户能够更好地利用地理信…...

MySQL 存储过程、函数、触发器、事件
目录 存储过程 创建存储过程 调用存储过程 查看存储过程 删除存储过程 进阶 变量 if条件判断 传递参数 case结构 while循环 repeat结构 loop语句 leave语句 游标/光标 存储函数 触发器 创建触发器 删除触发器 查看触发器 事件 查看事件调度器是否开启…...

【LeetCode】121. 买卖股票的最佳时机 -
这里写自定义目录标题 2023-8-9 19:25:01 121. 买卖股票的最佳时机 2023-8-9 19:25:01 我也是一次性遍历。 自己感觉是用两个指针来做的。 第一天(x 1) 的时候就已经买入了,假定某y天 比第x天 便宜 或 相等,那么我就应当是第…...

解决Vue+Element-UI 进行From表单校验时出现了英文提示问题
说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家! 问题描述 在使用form表单时,往往会对表单字段进行校验,字段为必填项时会添加required属性,此时自定义rules规则…...

cpolar内网穿透的安装
群晖6.X安装cpolar内网穿透 文章目录 群晖6.X安装cpolar内网穿透前言1. 下载cpolar的群晖套件1.1 打开群晖套件中心1.2 选择“手动安装”1.3 选择下载cpolar套件位置 2. 打开cpolar的Web-UI界面3. 注册会员 前言 随着硬件设备和软件技术的发展,以及数据量的发福暴涨…...

OPENCV C++(十)gramm矫正+直方图均衡化
两者都是只对单通道使用,对多通道的话 就需要分离通道处理再合并通道 两种方法,第一个要运算次数太多了,第二个只需要查表 伽马矫正函数,这里用第二种方法,且写法有点高级 int gammaCorrection(cv::Mat srcMat, cv::…...