目标:用一行代码 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));

这行代码的含义很直观:

  1. 只需要提供一个本地文件路径(Path
  2. ContentUtil 会根据文件类型自动选择解析方案
  3. 最终返回 纯文本 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 / 图片 / 其他

整体分流逻辑如下:

  1. PDF
  • 先判断是不是 PDF
  • 如果是 PDF:会先试探是否“扫描版 PDF”
    • 如果是扫描件:走 OCR
    • 如果不是扫描件:走 Tika
  1. 图片
  • 如果后缀匹配图片:直接走 OCR
  1. 其他文件
  • 统一走 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 时,会构造统一请求:

  • OcrRequest
    • fileTypepng/jpg/jpeg/...pdf
    • languagezh
    • scenedefault
    • content:文件字节

然后调用:

  • 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: paddle
  • endpoint: http://127.0.0.1:8002/ocr_base64

这类方案通常适合:

  • 内网部署、成本可控
  • 对吞吐有要求(多线程批量 OCR)

注意:无论在线还是自建,都通过统一的 OcrManager / OcrRequest 进行调用,业务侧无需改代码。


5. langchain4j-spring-ai-sdk-ocr-sample:两种 OCR 用法怎么切换?

sample 模块提供:

  • application.yml:配置 OCR provider
  • OcrSdkSample.java:一个可直接跑的 main
  • MyContentUtil:封装了同样的 getContent 用法

5.1 配置切换(核心只改一个 code)

langchain4j-spring-ai-sdk-ocr-sample/src/main/resources/application.yml 里:

  • 在线版 VL 1.5:

    • ocr.providers.code: paddle-vl-1.5
    • endpoint: https://.../layout-parsing
    • token: xxxx
  • 自建 HTTP Paddle:

    • ocr.providers.code: paddle
    • endpoint: 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() 明确支持以下后缀(大小写不敏感):

  • png
  • jpg
  • jpeg
  • bmp
  • gif
  • tiff
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/文本/代码类型(取决于实际文件内容)
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐