惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

L
LangChain Blog
V
V2EX
爱范儿
爱范儿
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Martin Fowler
Martin Fowler
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Apple Machine Learning Research
Apple Machine Learning Research
WordPress大学
WordPress大学
有赞技术团队
有赞技术团队
宝玉的分享
宝玉的分享
Last Week in AI
Last Week in AI
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
罗磊的独立博客
小众软件
小众软件
Vercel News
Vercel News
博客园 - 司徒正美
阮一峰的网络日志
阮一峰的网络日志
V
Visual Studio Blog
J
Java Code Geeks
P
Proofpoint News Feed
MongoDB | Blog
MongoDB | Blog
B
Blog
美团技术团队
量子位

InfoQ - 促进软件开发领域知识与创新的传播

Meta 收购 Manus 这事儿泡汤了 5.5万 Star 开源项目 Ghostty 被迫出走,GitHub 正在终结一代技术人的乌托邦 谷歌开源“Agent Skill 超级工具箱”,云、库、引擎、AI全线打通,开发者狂喜 Slack 长时运行多智能体系统的上下文管理方案 从 T+1 到分钟级:金城银行基于 Apache Doris 构建高可靠、强一致的实时数据平台 谷歌云推出 Agents CLI,简化 AI 智能体开发全流程 Claude官方击穿高薪、高学历的安全防线!Anthropic点名10大高危职业,但有群人暂时稳了 亚马逊云科技终止 WorkMail 服务,并将 App Runner 转入维护模式 OPPO小布记忆:全模态碎片化内容的理解与智能整理实践|AICon上海 模力工场038周AI应用周榜:工具在消失,工作流在出现 Akamai CEO Tom Leighton:Agent 时代来临,云基础设施正从“中心化”转向“分布式边缘” 日均数百亿入库背后:从“人肉调度”到K8s弹性架构,度小满金融基于OceanBase重构入库架构实践 百度文库网盘发布GenFlow 4.0:月活用户超1亿,要把网盘变成全端AI工作台 Altman 投的 Agent 终端 Warp 开源了!斩获3.5万star 哪些客户需要拒, 敢让龙虾决定吗?_AI&大模型_InfoQ 中文站_InfoQ精选视频 从开发到生产:为什么越来越多的机器学习团队纷纷迁移到 Snowflake | BUILD 2025_AI&大模型_王玮_InfoQ精选视频 探索多智能体工作流:LangGraph Snowflake Cortex AI | BUILD 2025_AI&大模型_王玮_InfoQ精选视频 腾讯云分布式缓存数据库:AI Agent - 从提示词工程到 Harness 工程 | 腾讯云数据库 DBTalk_腾讯_凌敏_InfoQ精选视频 基于 Streamlit 为 CSV 数据构建分析智能体 | BUILD 2025_AI&大模型_王玮_InfoQ精选视频 AI 智能体:告别文档缺漏 | BUILD 2025_AI&大模型_王玮_InfoQ精选视频 构建 AI 驱动的数据管道:深度探讨 Snowflake Openflow 与非结构化数据 | BUILD 2025_AI&大模型_王玮_InfoQ精选视频 云端太贵、本地不够聪明,英特尔押注“端云混合AI”:智能体PC会替人完成工作 不到10%的存储投入,可能拖垮90%的GPU投资!IBM把AI Agent塞进存储系统,算清企业最容易忽略的一笔账 Snowpark 上手实战 | BUILD 2025_大数据_王玮_InfoQ精选视频 ClickHouse + Langfuse,构建 Agent 可观测基石 腾讯云分布式缓存数据库:Cluster Proxy 共享连接架构深度解析 | 腾讯云数据库 DBTalk_腾讯_凌敏_InfoQ精选视频 AI 写代码太烧钱了:Copilot、Claude 一起涨价,不如把程序员请回来? 英特尔发布至强600系列工作站处理器与锐炫Pro B70 GPU,全新AI工作站来了 腾讯云分布式缓存数据库:从 Redis 到 Valkey - 开源社区如何快速创新 | 腾讯云数据库 DBTalk_腾讯_凌敏_InfoQ精选视频 印奇这次要“从0重做”智驾模型!首谈阶跃和千里双公司布局:中国AI商业闭环要靠车跑出来
银行业PDF表格提取方案重构:基于Java的分层方案
作者:Mehuli Mu · 2026-04-24 · via InfoQ - 促进软件开发领域知识与创新的传播

引言:金融服务领域的一个隐性难题

在银行与金融科技领域,技术规划通常聚焦于 API、实时处理、云迁移及人工智能驱动的数据分析。然而,大量核心业务流程仍依赖企业系统中结构化程度最低的文件格式——PDF。银行对账单、交易报告、监管披露材料、开户资料以及客户上传文件不断以 PDF 的格式流入。这些文档需要为分析平台、风险模型、合规审核及客户视角分析提供数据支撑。

关键挑战在于 PDF 的结构。PDF 的设计初衷是保证视觉保真度,而非承载语义化数据。表格很少以标准表格对象的形式呈现,列靠间距来体现,行靠对齐来区分。页眉、页脚、免责声明、横幅等版式元素还经常会打断交易数据区域。这种情况在金融服务行业尤为突出,主要原因包括:对账单来自多家机构与供应商、模板会无预警发生变更、旧版对账单多为扫描图片,以及交易记录经常跨行显示或包含合并单元格。

在生产环境中,信息提取失败并不是个小问题。解析错误可能会传导至偿付能力核查、贷款审批及监管报告等环节,而这些场景均对可审计性和可重复性有严格要求。本文将阐述 PDF 表格提取在规模化应用中失效的原因,说明单一策略的 Java 实现为何在真实业务环境中难以稳定运行,并介绍如何通过架构化方法提升可靠性。

第一种实现方案:流式解析一度有效

在设计银行数据处理流程时,提取金融对账单的需求看似简单:只需要抽取交易表格并映射为相应的数据结构。对于文本型 PDF,常用方案是采用流式解析器,先提取带坐标信息的文本片段,按纵向坐标将片段归为一行,再根据横向区间将行拆分为列,最后将列映射为 DateDescriptionAmountBalance 等字段。

举个简单的例子:

在开发环境中,这种方法或许够用。但在生产环境中,初期暴露的问题往往不是异常或崩溃,而是看似正常、实则列分配错误的数据行。一个典型问题是:当对齐出现微小偏差时,金额与余额列会发生互换,而系统仍正常运行,下游业务也继续信任这个输出。这让我们意识到,PDF 提取并非传统意义上的解析问题,而是输入可靠性问题,我们在设计阶段就必须明确考虑可靠性。

为何流式提取在生产环境中处理对账单会失效

在处理真实的对账单格式时,同样的失效问题会反复出现。这类问题并不限于某一家银行,而是在多家机构和不同的 PDF 生成工具中普遍存在。

布局漂移和不稳定的列边界

流式解析的前提是假设各列拥有固定的横向坐标边界。而在真是的对账单中,横向位置常会因以下原因发生变化:字体与渲染差异、摘要内容宽度不固定、模板更新以及不同的 PDF 生成工具或导出设置的影响。

对人工阅读来说,表格依然清晰可读。但对于依赖横向坐标聚类的解析算法而言,哪怕微小的位置偏移都可能导致数值超出预设的列边界。在实际应用中,仅仅几像素的偏差就会让数据被错误归到其他列中。

跨多行交易记录

交易记录通常并非单行显示,常见的格式包括:

  • 第 1 行(日期 + 描述 + 金额)

  • 第 2 行(描述续行(无日期/金额))

  • 可选第 3 行(参考信息、汇率注释、地点或元数据)

如果把每一行物理行都当作一条交易记录,就会把一笔交易拆分成多条;可如果过度合并,又可能把相邻的交易混在一起。无论采用哪种方式,都需要有明确的多行处理逻辑与校验机制。

混合内容与多类表格区域

对账单中通常还包含其他对齐区域,例如账户摘要、费用明细、利息说明、合计数据或营销横幅。其中不少内容在视觉上与表格相似,若解析器仅依靠对齐方式判断,很可能将其误判为交易表格。对于这种情况,提取过程需要结合语义校验(如页眉识别、字段类型、行数据规律),而不能只依赖几何位置信息。

扫描版 PDF:OCR 让提取变成另一个问题

扫描版对账单没有可直接读取的文本层,流式解析无法奏效,因为不存在可选中的文本和坐标信息。这时必须依赖 OCR,但 OCR 也会带来新的问题,包括:字符识别错误(如 0/O1/l 混淆、小数点丢失)、文本框噪声干扰行列划分、文档倾斜或旋转导致的对齐偏差,以及压缩失真产生的虚假线条或原线条出现断裂。对于这种情况,仅“提取文本”远远不够,还需要从图像像素中重建表格结构,并与 OCR 结果对齐。

首次架构调整:引入 Python(Camelot)

在监管严格的环境中,一种常见的短期方案是在已有的 Java 服务之外引入基于 Python 的提取 API(Camelot),并结合使用面向图片类 PDF 的 OCR 流程。这个工具能够优化部分文档的提取效果,帮助团队判断针对不同类型的 PDF 应该采用哪种提取策略更为合适。

但这种架构需要付出相应的代价,主要包括:额外的运行环境与部署流程、重复的依赖治理和漏洞管理、多服务可观测性与调试开销上升,以及敏感文档在多组件间流转所带来更严苛的处理要求。

这并不是说引入 Python 工具是错误的,而是说提取的可靠性不能只靠选择某一个工具来解决。系统需要一套合适的架构,既能在文档格式多变的情况下稳定运行,又能降低运维成本。

重构方案:基于验证与降级的策略选择

关键的改进在于将“选择最优解析器”的思路转变为“在运行时选取最优结果”,同时绝不隐藏低置信度结果。这种方法需要具备三项能力:

  • 多种提取策略,包括流式提取、表格格线式提取,以及 OCR 处理的变体

  • 可对错误输出进行早期检测的验证与评分机制

  • 明确且可审计的回退行为

这就是构成生产级流水线的架构。

强化的流式解析

流式解析在处理文本型 PDF 时依然有效,区别在于将流式输出视为必须经过验证的候选结果。参考如下伪代码:

流式提取流程

// PSEUDOCODEList<TextBox> boxes = pdfTextExtractor.extract(page);List<Line> lines = clusterByY(boxes);Header header = headerDetector.find(lines); // keyword scoring: Date, Amount, Balance, etc.ColumnModel columns = columnInferer.infer(lines, header);Table table = rowAssembler.assemble(lines, columns);ValidationScore score = validator.score(table);return ExtractionResult.of(table, score, Strategy.STREAM);

复制代码

重要的验证信号

典型验证项包括:页眉检测(或强页眉信号识别)、日期解析成功率、金额与余额列的数值解析成功率、行一致性校验(即预期应填充的列数),以及合理性检查(例如余额解析结果以数值为主,不应被非数字文本主导)。

我们的目标并非追求完美,而是捕捉那些表面有效、实则结构错误的失效模式。

格线解析:有线/扫描表格的网格式抽取方法

对于扫描版对账单与带框线表格,格线解析能够有效提升识别可靠性,原因在于它使用的是视觉结构(边框线条)进行解析,而非依赖文本对齐。参考如下伪代码:

格线提取流程

// PSEUDOCODEBufferedImage image = renderer.render(page);GridLines lines = lineDetector.detect(image);      // horizontal + vertical linesCellMatrix cells = gridBuilder.build(lines);       // joints/intersections -> cell gridList<OcrBox> ocrBoxes = ocrEngine.extract(image);  // text + bounding boxesTable table = cellAssigner.assign(cells, ocrBoxes);ValidationScore score = validator.score(table);return ExtractionResult.of(table, score, Strategy.LATTICE);

复制代码

格线失效模式

格线解析并非万能,它在多种场景下均可能失效,例如:无网格线的空白分隔表格、线条断裂或不完整(如缺少连接点)、水印或阴影产生的干扰线条、存在合并单元格需进行跨列/跨行检测,以及多页表格宽度不一致等。与流式解析同理,关键在于对格线解析的输出结果进行校验,并将其作为候选方案,而非绝对正确的结论。

混合解析:选取最优结果,而非最优解析器

混合解析是面向真实场景多变性而设计的生产级策略。在生产环境中,我们的目标并不是要判定哪种解析技术最优,而是对多组抽取结果进行评估与打分,返回针对当前文档最可靠的结果,并在置信度较低时提供清晰的降级回退方案。参考如下伪代码:

编排器

// PSEUDOCODEExtractionResult stream = streamParser.tryExtract(pdf);ExtractionResult lattice = latticeParser.tryExtract(pdf);ExtractionResult best = chooseBest(stream, lattice);if (!best.score().isAcceptable()) {    return fallbackHandler.lowConfidence(pdf, stream, lattice);}return best;

复制代码

评分输入示例

评分模型不需要太复杂也能达到很好的效果。常见的输入包括:页眉匹配度(关键词与列数匹配情况)、日期和数值列的解析成功率,以及行数是否合理(行数过少或过多)。

实用的设计思路是让评分具备可解释性。当抽取结果被驳回时,系统应明确说明原因(例如日期解析率低于 60%、未检测到页眉、行与行之间列数不一致)。

最重要的原则:绝不隐藏低置信度结果

在金融系统中,提取错误比未提取到结果的后果更为严重。当置信度低于设定阈值时,处理流程应执行以下操作:仅返回带有明确标识的部分结果、转入指定的人工审核或异常处理流程、存储非敏感诊断信息用于问题排查,并在低置信度结果数量激增时触发格式漂移告警。

这种响应措施可以防止数据被静默损坏。

机器学习辅助布局检测:窄场景使用,强约束保障

部分 PDF 可能会同时让流式解析与格线解析失效:这类文件没有清晰的网格线、页面为复杂多栏布局、混杂叙述文本块,还可能带有印章、旋转角度或使用非常规模板。

针对这类情况,机器学习可作为区域分割工具,主要用于检测潜在的表格区域。更稳妥的模式是:由机器学习给出表格边界框,再对框内区域进行解析(结合 OCR 与格线解析或流式解析),随后校验输出结果,若校验不通过则自动触发回退机制。

但在受监管的业务流程中,机器学习不能作为不经核实就直接采信的提取工具。它的作用是缩小搜索范围、优化定位精度,而非绕过确定性校验环节。

Java 优先解决方案的重建:生产级摄入子系统

最终的架构不是一个解析器,而是一个职责分离明确的摄入子系统:

  • 文档分类:文本/扫描件、质量特征值以及页面辅助信息

  • 流式解析器:带有对齐逻辑的文本层提取

  • 格线解析器:带有 OCR 对齐的网格检测

  • OCR 模块:适用于扫描文档的统一文本框接口

  • 混合编排器:运行时策略选择

  • 验证器/评分器:可解释的质量门控

  • 诊断/可观测性:指标、失败原因和可追溯性

输出约定同样关键。我们统一规范了一个标准数据结构,包括:

transactions[](结构化行);

strategyUsed

confidenceScore

warnings[]

parsingDiagnostics(非敏感摘要)。

这种结构让下游调用方将抽取结果视为概率性、可审计的数据,而非盲目采信的结果。

最后,这种设计模式可通过纯 Java 实现,无需引入额外的运行时。例如,我开源了 Java 库 ExtractPDF4J,通过融合多种互补解析策略(流式、格线/OCR)并输出便于校验的结果实现了文中所述的生产环境多变性处理方案。

Java 架构师构建文档摄入管道系统的经验

这些是在生产环境中效果最为显著的实践::

  • 将 PDF 抽取视为可靠性与验证问题,而非单纯的文件格式问题

  • 避免采用单一解析策略;采用流式解析 + 格线/OCR 互补方案

  • 尽早实现验证与评分机制,并保证可解释性

  • 使用明确的回退机制与人工审核通道;不隐藏低置信度结果

  • 完善可观测性(如成功率、置信度分布、主要失败原因及格式漂移告警)

  • 仅在小范围场景使用机器学习做区域分割,且必须经过确定性验证把关

  • 优先优化长期运营成本(安全审查、治理、部署与调试流程),而非只追求抽取准确率

结论:为置信度而设计,而非追求完美

生产环境中 PDF 表格提取失效根源在于金融文档本身存在多变、老旧且格式不统一的问题。常见误区是把它当成只需要更好的工具就可以解决的工程问题。而在实际应用中,系统的可靠性源自整体架构设计:包括分层解析策略、校验机制、评分体系以及明确的回退处理逻辑。

对于银行及金融科技团队而言,目标并非单纯从 PDF 中提取表格,而是确保下游系统能够信任提取的数据,并且知道何时不可信任。这正是演示案例与生产级摄入管道系统的核心区别。

【声明:本文由 InfoQ 翻译,未经许可禁止转载。】

查看英文原文:https://www.infoq.com/articles/redesign-pdf-table-extraction/