一行代码搞定文件内容提取:ContentUtil.getContent(Path) + SPI 集成 OCR(PaddleOCR 在线版/自建 OCR)
本文介绍了一个统一文件内容提取工具ContentUtil.getContent(Path)的实现方案。该工具通过一行代码即可智能识别文件类型,自动选择OCR或Tika解析方案:图片和扫描版PDF走OCR(支持SPI插拔不同OCR SDK),其他文件使用Apache Tika处理。文章详细解析了内容提取的工作流程,包括文件分流判断、扫描版PDF识别逻辑、基于SPI的OCR实现切换机制,以及当前明确支
目标:用一行代码
String content = ContentUtil.getContent(Path.of(filePath));完成“文件内容提取”。
- 图片 / 扫描版 PDF:自动走 OCR(通过 SPI 插拔不同 OCR SDK)
- 其它文件:自动走 Apache Tika(Word/Excel/PPT/文本/代码/HTML…)
文章介绍了内容解析链路的工作方式、如何用 SPI 切换 OCR Provider、
langchain4j-spring-ai-sdk-ocr-sample如何快速跑通,以及当前明确支持的文件类型范围。
Git 代码:https://gitee.com/zhangjq123/langchain4j-spring-agent/blob/master/langchain4j-spring-ai/langchain4j-spring-ai-seg-flow/src/test/java/com/soft/nda/segment/util/ContentUtilTest.java
1. 先看效果:一行代码提取正文
最常用的调用方式就是这一句:
String content = ContentUtil.getContent(Path.of(filePath));
这行代码的含义很直观:
- 只需要提供一个本地文件路径(
Path) ContentUtil会根据文件类型自动选择解析方案- 最终返回 纯文本 content(适用于入库、分割、向量化、RAG 等)
典型场景
- 招投标文件(大量 PDF + 图片扫描件)
- 办公文件(Word/Excel/PPT)
- 网页/Markdown/代码文件
2. ContentUtil.getContent(Path) 到底做了什么?(流程解读)
ContentUtil.getContent(Path path) 的内部逻辑可以拆成三件关键事。
2.1 统一入口:Path / MultipartFile 都走 InputStream
- Path 版:
Files.newInputStream(path) - MultipartFile 版:
file.getInputStream()
两者都会包一层 BufferedInputStream,保证解析过程中能 mark/reset。
2.2 先分流:PDF / 图片 / 其他
整体分流逻辑如下:
- 先判断是不是 PDF
- 如果是 PDF:会先试探是否“扫描版 PDF”
- 如果是扫描件:走 OCR
- 如果不是扫描件:走 Tika
- 图片
- 如果后缀匹配图片:直接走 OCR
- 其他文件
- 统一走 Tika
2.3 扫描版 PDF 怎么判断?(避免误 OCR)
这里使用 PDFBox 做启发式判断:
- 抽取文本长度是否很少(
textLen < 50) - 页面内图片是否很多/面积占比很高(例如图片数 >= 页数,或图片面积占比 >= 0.3)
满足“文字少 + 图片重”的条件,就判为“扫描 PDF”。
这样做的好处:
- 普通 PDF 不会白白 OCR(速度快、成本低)
- 扫描件能自动 OCR(可用性强)
3. OCR 是怎么做到可插拔的?(SPI + OcrManager)
这套 OCR 的关键点是:通过 SPI 发现并加载 OCR 实现,并且可以通过配置选择“哪一个实现生效”。
3.1 SPI 自动发现 OCR 实现
ContentUtil 静态初始化时会执行:
ServiceLoader.load(OcrManager.class)- 遍历所有实现并打印日志:
[ContentUtil] SPI发现OcrManager: xxx
这意味着:
- 新增 OCR SDK module(例如 Tencent/阿里云/本地 Paddle)
- 只要它提供 SPI 配置,运行时就会被自动发现
3.2 从配置选中某个 OCR Provider
ContentUtil 会读取 OCR 配置(通过 OcrConfigLoader.loadOcrProperties()),拿到:
ocr.providers.code
随后按 manager.getCode().equalsIgnoreCase(code) 匹配,匹配成功的那个 Manager 就作为 ocrManager 使用。
3.3 OCR 请求与输出(统一抽象)
识别图片/PDF 时,会构造统一请求:
OcrRequestfileType:png/jpg/jpeg/...或pdflanguage:zhscene:defaultcontent:文件字节
然后调用:
ocrManager.recognize(req)
拿到:
OcrResult.text:合并后的纯文本(用于入库/分割)
4. 已接入的 OCR:PaddleOCR 在线版 + 自建 OCR
4.1 PaddleOCR 在线版(百度 AIStudio)
当前对接的在线能力来自:
- https://aistudio.baidu.com/paddleocr
仓库里提供了对应对接模块:
langchain4j-spring-ai-sdk-ocr-paddle-vl-1.5
它属于“布局解析(layout parsing)”的 API,除了 OCR 文本,还可以输出布局结构、Markdown 等。
4.2 自建 OCR(例如本地 HTTP PaddleOCR 服务)
在 sample 配置里也预留了本地 HTTP 形式:
code: paddleendpoint: http://127.0.0.1:8002/ocr_base64
这类方案通常适合:
- 内网部署、成本可控
- 对吞吐有要求(多线程批量 OCR)
注意:无论在线还是自建,都通过统一的 OcrManager / OcrRequest 进行调用,业务侧无需改代码。
5. langchain4j-spring-ai-sdk-ocr-sample:两种 OCR 用法怎么切换?
sample 模块提供:
application.yml:配置 OCR providerOcrSdkSample.java:一个可直接跑的 mainMyContentUtil:封装了同样的 getContent 用法
5.1 配置切换(核心只改一个 code)
在 langchain4j-spring-ai-sdk-ocr-sample/src/main/resources/application.yml 里:
-
在线版 VL 1.5:
ocr.providers.code: paddle-vl-1.5endpoint: https://.../layout-parsingtoken: xxxx
-
自建 HTTP Paddle:
ocr.providers.code: paddleendpoint: http://127.0.0.1:8002/ocr_base64
5.2 运行示例
OcrSdkSample 的 main 方法里本质就是:
String text = MyContentUtil.getContent(path);
将图片/PDF 路径替换为本机文件即可。
6. 当前支持的文件类型(明确范围 + Tika 扩展范围)
这里分两类说明。
6.1 明确支持(代码里硬判断)
6.1.1 图片(必走 OCR)
ContentUtil.isImageFile() 明确支持以下后缀(大小写不敏感):
pngjpgjpegbmpgiftiff
6.1.2 PDF
pdf
其中:
- 扫描件 PDF:自动 OCR
- 非扫描 PDF:走 Tika 提取文本
6.2 Tika 尝试解析(强烈依赖文件实际内容)
除图片/PDF 外,ContentUtil 对其它文件统一走:
ApacheTikaDocumentParser(AutoDetect)
这意味着:
- 代码里并没有写死“白名单后缀”
- 只要 Tika 能解析出文本,就会返回
一般情况下,以下类型通常都能提取到文本(但受文件质量影响,不做 100% 保证):
- Office:
doc/docx/xls/xlsx/ppt/pptx - 文本与标记:
txt/md/html/xml/json/yaml/yml/csv - 代码:
java/py/js/ts/go/c/cpp/sql/properties等
如果需要“可控的支持清单”,建议后续在
ContentUtil增加一个getSupportedExtensions()并在 README 固化成白名单;当前实现是“能解析就解析”的策略。
7. 总结
ContentUtil.getContent(Path)是一个“统一文件内容提取入口”:- 图片/扫描 PDF 自动 OCR
- 其他文件自动 Tika
- OCR 通过 SPI 插拔式集成:
- 可在在线 PaddleOCR(百度 AIStudio)和自建 OCR 间自由切换
langchain4j-spring-ai-sdk-ocr-sample给了最小可运行示例和配置模板- 文件类型支持:
- 明确支持:pdf + png/jpg/jpeg/bmp/gif/tiff
- Tika 附加支持:多种 Office/文本/代码类型(取决于实际文件内容)
更多推荐


所有评论(0)