Java 解析pdf文档内容实战案例

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
简介: Java 解析pdf文档内容实战案例

一、应用场景

1.首先我个人认为一切的技术都是为了服务实际的业务场景,所以说业务场景很重要,我一般写文章也都是先说明我的业务场景,这样大家也应该会比较容易理解,能知道我们为什么要解析这个pdf文档内容。

2.项目上的实际案例是用来解析财务报表(资产负债表,利润表,所得税,增值税报表)的。但是那些报表,因为涉及隐私保密问题,所以我就用的个人银行流水给大家做一个详细的讲解过程。

3.咱么既然要解析PDF文档内容,肯定是想把它解析成格式化数据(JSON)格式的,对吧,这样才能方便我们对数据的一个使用。

二、直接上代码

具体基本每一行,我都有详细的注释说明。

1.先看看我要解析的源文件程序嗑学家_薪资流水.pdf

bff0ae9f0b894be4bd1aceb8aba13ae7.png


上面这个文件是相对比较规整格式的文件,实际情况应该会有许多报表格式不一样,解析出来的有换行之类的,需要特殊处理。

2.maven的pom文件引入依赖包如下:

<!-- pdfbox start -->  
        <!-- https://mvnrepository.com/artifact/org.apache.pdfbox/pdfbox -->
        <dependency>
            <groupId>org.apache.pdfbox</groupId>
            <artifactId>pdfbox</artifactId>
            <version>2.0.19</version>
        </dependency>
        <dependency>
            <groupId>org.apache.pdfbox</groupId>
            <artifactId>pdfbox-tools</artifactId>
            <version>2.0.19</version>
        </dependency>
        <dependency>
            <groupId>org.apache.pdfbox</groupId>
            <artifactId>fontbox</artifactId>
            <version>2.0.19</version>
        </dependency>
        <dependency>  
             <groupId>org.apache.pdfbox</groupId> 
             <artifactId>jempbox</artifactId> 
             <version>1.8.16</version> 
          </dependency> 
          <dependency>
             <groupId>org.apache.pdfbox</groupId> 
             <artifactId>xmpbox</artifactId> 
             <version>2.0.19</version> 
          </dependency> 
          <dependency> 
             <groupId>org.apache.pdfbox</groupId> 
             <artifactId>preflight</artifactId> 
             <version>2.0.19</version> 
          </dependency>
          <!-- pdfbox end -->

注:我这里还有对PDF文档的其他一些解析,包括html字符串生成PDF文档的实际应用需求,所以我这儿引入的包比较多一点儿,你可以根据自己需求,按需引入依赖包。

三、具体实现代码

3.1下面这个文件是一个完整的Java 类

注:此处我引入了alibaba的JSON解析包,如果您复制过去报错的,可以自行引入需要的包。

package com.xxx.util.pdf;
 
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
 
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;
 
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
 
public class ParsePdfContent {
    
    public static void main(String[] args) {
        ParsePdfContent.tqPdfDataToTxt("E:\\www\\temp\\程序嗑学家_薪资流水.pdf", "E:\\www\\temp\\cxkxj_xzls.txt");
    }
    /**
     * 测试解析pdf的文档内容,并将解析内容输出到Txt文档中
     * 正式使用时,无需将解析后的内容写入文件,测试时,写入文件是为了方便查看解析后的原始内容
     * @param sourcePdfPath 要解析的pdf源文件
     * @param outFilePath 解析后的文本内容输出路径
     */
    public static void tqPdfDataToTxt(String sourcePdfPath,String outFilePath) {
        File file = new File(sourcePdfPath);
        if(file.exists()) {
            try {
                PDDocument doc = PDDocument.load(file);
                //正式使用时,此处注释开始--------------
                FileOutputStream fos = new FileOutputStream(outFilePath);
                Writer writer = new OutputStreamWriter(fos, "UTF-8");
                //正式使用时,此处注释结束--------------
                PDFTextStripper stripper = new PDFTextStripper();
                stripper.setSortByPosition(true);// 排序
                stripper.setEndPage(1);//要解析的结束页数,此处我只解析第一页
                stripper.setWordSeparator("##");//单元格内容的分隔符号
                stripper.setLineSeparator("\n");//行与行之间的分隔符号
                String text = stripper.getText(doc);
                String[] rows = text.split("\n");
                //======从这里开始需要根据自己的实际解析内容做不同的处理start=======
                JSONArray list=new JSONArray();//存储解析数据的集合
                /**
                 * startFlag
                 * 解析内容开始的标志(大白话就是记录从哪一行开始是咱们的有用数据)
                 * 这里需要先解析一遍并输出到文件,才能具体知道
                 */
                String startFlag="Balance##Transaction";
                String endFlag="1/35";//结束标志
                int k=0;//开始获取数据标志
                boolean bb_End=false;//报表获取数据结束标志
                /**
                 * keys
                 * 标识字段的key
                 * date:记账日期
                 * currency:货币
                 * amount:交易金额
                 * balance:联机余额
                 * transactionType:交易摘要
                 * counterParty:对手信息
                 */
                String[] keys= {"date","currency","amount","balance","transactionType","counterParty"};
                for (int r=0;r<rows.length;r++) {
                    /**
                     * 这里根据自己的解析内容做不同的业务处理
                     * 我这里总共6列数据
                     */
                    JSONObject rowJson=new JSONObject();
                    rows[r]=rows[r].replaceAll(" ", "").replaceAll("\r", "");//此处我把每一行的空格和\r去掉
                    String[] split = rows[r].split("##");
                    if(k==1&&!bb_End) {//增值税表
                        if(rows[r].startsWith("本期应补(退)税额##22")||rows[r].startsWith("期末未缴查补税额##38")) {
                            bb_End=true;
                        }
                        //这里我判断是否完全匹配,是防止有换行的,这个需要根据实际情况做不同处理
                        if(split.length==keys.length) {//完全匹配列数(6)
                            for (int i=0;i<keys.length;i++) {
                                rowJson.put(keys[i], split[i]);
                            }
                            list.add(rowJson);
                            continue;
                        }
                        if(bb_End) {
                            break;//结束解析
                        }
                    }else {
                        if(rows[r].startsWith(startFlag)) {
                            k++;
                            continue;
                        }
                    }
                }
                //======从这里开始需要根据自己的实际解析内容做不同的处理end=======
                //正式使用时,此处注释开始--------------
                stripper.writeText(doc, writer);//写入本地文件(测试用)
                writer.close();
                //正式使用时,此处注释结束--------------
                doc.close();
                System.out.println("解析后格式化的JSON数据如下:");
                System.out.println(JSON.toJSONString(list));
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (UnsupportedEncodingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println("======================解析完成============================");
        }else {
            System.err.println("找不到要解析的pdf文件");
        }
    }
}

3.2上面这个事例代码里面,我不仅把pdf内容输出到了文件内,还做了一个格式化输出的解析。

3.3输出的文件cxkxj_xzls.txt 内容如下:

招商银行交易流水
Transaction Statement of China Merchants Bank
2021-03-14 -- 2022-03-14
户  名:赵艳飞##账号:6214********0098
Name##Account No
账户类型:ALL/全币种##开 户 行:北京分行西二旗支行
Account Type##Sub Branch
申请时间:2022-03-16 15:42:11##验 证 码:3RCEE96T
Date##Verification Code
记账日期##货币##交易金额##联机余额##交易摘要##对手信息
Transaction
Date##Currency
Amount
Balance##Transaction Type##Counter Party
2021-03-14##CNY##100.00##381.19##网联收款##财付通支付科技有限公司
2021-03-14##CNY##-231.00##150.19##快捷支付##阳坊胜利涮羊肉(风雅园店)
2021-03-15##CNY##-18.00##132.19##快捷支付##西北楼牛肉面
2021-03-16##CNY##-8.00##124.19##快捷支付##微信面对面收款
2021-03-16##CNY##-19.00##105.19##快捷支付##微信转账
2021-03-16##CNY##-11.00##94.19##快捷支付##面馆
2021-03-17##CNY##-22.68##71.51##快捷支付##网银在线(北京)科技有限公司
2021-03-17##CNY##-6.50##65.01##快捷支付##微信转账
2021-03-17##CNY##-11.00##54.01##快捷支付##微信面对面收款
2021-03-17##CNY##-3.00##51.01##银联快捷支付##微信转账
2021-03-17##CNY##-0.83##50.18##零售汇出汇款##深圳市腾讯计算机系统有限公司
2021-03-17##CNY##0.83##51.01##零售汇入汇款##深圳市腾讯计算机系统有限公司
2021-03-17##CNY##0.01##51.02##网联收款##财付通支付科技有限公司
2021-03-17##CNY##-12.00##39.02##银联快捷支付##微信面对面收款
2021-03-18##CNY##200.50##239.52##报销款##北京天邦众和信息科技有限公司
2021-03-18##CNY##-14.00##225.52##快捷支付##微信面对面收款
2021-03-18##CNY##-12.00##213.52##快捷支付##微信面对面收款
2021-03-19##CNY##-6.50##207.02##快捷支付##微信转账
1/35

c528e48f8b4b4c988b8fe3a7155eb3bc.png

3.4格式化输出内容就是JSON数组

b9a75d2a4bf94a3b86dcb89e6e39524a.png

四、结语:

小编是一名爱生活,爱代码,爱交朋友的热血青年,希望我们能够共同进步,共同成长。

感觉有帮助的帮小编点个免费的赞吧,如有问题,可以私信或者评论区留言,小编知无不言,言无不尽。

喜欢小编的可以微信搜素:民谣嗑学家

关注我个人公众号,小编平时,除了工作码代码,还是一名业余吉他爱好者,有喜欢的朋友可以一起交流交流。

相关文章
|
12天前
|
人工智能 编解码 文字识别
OCRmyPDF:16.5K Star!快速将 PDF 文件转换为可搜索、可复制的文档的命令行工具
OCRmyPDF 是一款开源命令行工具,专为将扫描的 PDF 文件转换为可搜索、可复制的文档。支持多语言、图像优化和多核处理。
140 17
OCRmyPDF:16.5K Star!快速将 PDF 文件转换为可搜索、可复制的文档的命令行工具
|
26天前
|
JavaScript Java 测试技术
基于Java+SpringBoot+Vue实现的车辆充电桩系统设计与实现(系统源码+文档+部署讲解等)
面向大学生毕业选题、开题、任务书、程序设计开发、论文辅导提供一站式服务。主要服务:程序设计开发、代码修改、成品部署、支持定制、论文辅导,助力毕设!
57 6
|
27天前
|
存储 缓存 Java
Java中的分布式缓存与Memcached集成实战
通过在Java项目中集成Memcached,可以显著提升系统的性能和响应速度。合理的缓存策略、分布式架构设计和异常处理机制是实现高效缓存的关键。希望本文提供的实战示例和优化建议能够帮助开发者更好地应用Memcached,实现高性能的分布式缓存解决方案。
39 9
|
28天前
|
运维 Shell 数据库
Python执行Shell命令并获取结果:深入解析与实战
通过以上内容,开发者可以在实际项目中灵活应用Python执行Shell命令,实现各种自动化任务,提高开发和运维效率。
56 20
|
1月前
|
供应链 搜索推荐 API
深度解析1688 API对电商的影响与实战应用
在全球电子商务迅猛发展的背景下,1688作为知名的B2B电商平台,为中小企业提供商品批发、分销、供应链管理等一站式服务,并通过开放的API接口,为开发者和电商企业提供数据资源和功能支持。本文将深入解析1688 API的功能(如商品搜索、详情、订单管理等)、应用场景(如商品展示、搜索优化、交易管理和用户行为分析)、收益分析(如流量增长、销售提升、库存优化和成本降低)及实际案例,帮助电商从业者提升运营效率和商业收益。
190 20
|
1月前
|
存储 监控 Java
JAVA线程池有哪些队列? 以及它们的适用场景案例
不同的线程池队列有着各自的特点和适用场景,在实际使用线程池时,需要根据具体的业务需求、系统资源状况以及对任务执行顺序、响应时间等方面的要求,合理选择相应的队列来构建线程池,以实现高效的任务处理。
120 12
|
1月前
|
数据采集 XML API
深入解析BeautifulSoup:从sohu.com视频页面提取关键信息的实战技巧
深入解析BeautifulSoup:从sohu.com视频页面提取关键信息的实战技巧
|
2月前
|
安全 API 数据安全/隐私保护
速卖通AliExpress商品详情API接口深度解析与实战应用
速卖通(AliExpress)作为全球化电商的重要平台,提供了丰富的商品资源和便捷的购物体验。为了提升用户体验和优化商品管理,速卖通开放了API接口,其中商品详情API尤为关键。本文介绍如何获取API密钥、调用商品详情API接口,并处理API响应数据,帮助开发者和商家高效利用这些工具。通过合理规划API调用策略和确保合法合规使用,开发者可以更好地获取商品信息,优化管理和营销策略。
|
2月前
|
自然语言处理 搜索推荐 数据安全/隐私保护
鸿蒙登录页面好看的样式设计-HarmonyOS应用开发实战与ArkTS代码解析【HarmonyOS 5.0(Next)】
鸿蒙登录页面设计展示了 HarmonyOS 5.0(Next)的未来美学理念,结合科技与艺术,为用户带来视觉盛宴。该页面使用 ArkTS 开发,支持个性化定制和无缝智能设备连接。代码解析涵盖了声明式 UI、状态管理、事件处理及路由导航等关键概念,帮助开发者快速上手 HarmonyOS 应用开发。通过这段代码,开发者可以了解如何构建交互式界面并实现跨设备协同工作,推动智能生态的发展。
196 10
鸿蒙登录页面好看的样式设计-HarmonyOS应用开发实战与ArkTS代码解析【HarmonyOS 5.0(Next)】
|
2月前
|
物联网 调度 vr&ar
鸿蒙HarmonyOS应用开发 |鸿蒙技术分享HarmonyOS Next 深度解析:分布式能力与跨设备协作实战
鸿蒙技术分享:HarmonyOS Next 深度解析 随着万物互联时代的到来,华为发布的 HarmonyOS Next 在技术架构和生态体验上实现了重大升级。本文从技术架构、生态优势和开发实践三方面深入探讨其特点,并通过跨设备笔记应用实战案例,展示其强大的分布式能力和多设备协作功能。核心亮点包括新一代微内核架构、统一开发语言 ArkTS 和多模态交互支持。开发者可借助 DevEco Studio 4.0 快速上手,体验高效、灵活的开发过程。 239个字符
243 13
鸿蒙HarmonyOS应用开发 |鸿蒙技术分享HarmonyOS Next 深度解析:分布式能力与跨设备协作实战

热门文章

最新文章

推荐镜像

更多