news 2026/3/22 12:25:23

SpringBoot集成DeepSeek-OCR实战|快速实现表格识别与结构化输出

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SpringBoot集成DeepSeek-OCR实战|快速实现表格识别与结构化输出

SpringBoot集成DeepSeek-OCR实战|快速实现表格识别与结构化输出

1. 背景与业务场景

在企业级应用中,大量纸质单据如采购订单、发票、入库凭证等仍需人工录入系统。这一过程不仅效率低下,还容易因人为疏忽导致数据错误。随着AI技术的发展,光学字符识别(OCR)已成为自动化文档处理的核心工具。

DeepSeek-OCR 是由 DeepSeek 开源的一款高性能 OCR 大模型,具备强大的文本检测与识别能力,尤其擅长复杂场景下的表格、票据和公式识别。其 WebUI 版本提供了直观的可视化界面和标准 API 接口,便于快速集成到各类业务系统中。

本文将详细介绍如何通过SpringBoot后端服务调用本地部署的DeepSeek-OCR-WEBUI服务,完成对包含表格图像的识别,并将其结果解析为结构化的 JSON 数据,最终实现从前端上传 → 后端处理 → 结构化输出的完整流程。


2. 系统架构与技术选型

2.1 整体架构设计

整个系统的运行逻辑分为三层:

  • 前端层:基于 Vue 构建的用户操作界面,支持图片上传与结果显示
  • 后端服务层:SpringBoot 应用,负责接收请求、转发至 OCR 引擎并处理返回结果
  • OCR 引擎层:独立部署的 DeepSeek-OCR-WEBUI 容器服务,提供/ocr接口进行图像识别
[前端上传图片] ↓ [SpringBoot Controller] ↓ [HTTP POST → DeepSeek-OCR-WEBUI /ocr 接口] ↓ [返回HTML格式表格] ↓ [SpringBoot 解析为JSON] ↓ [返回给前端展示]

该架构实现了职责分离,保证了 OCR 引擎的高可用性与可扩展性,同时便于后期接入更多 AI 模型。

2.2 技术栈说明

层级技术组件
前端Vue 3 + Element Plus + Axios
后端SpringBoot 3.x + RestTemplate + Jackson
OCR引擎DeepSeek-OCR-WEBUI(Docker部署)
构建与部署Maven + Docker + docker-compose

3. 部署DeepSeek-OCR-WEBUI服务

在集成之前,必须确保DeepSeek-OCR-WEBUI已正确部署并正常运行。

3.1 启动OCR后端服务

进入项目目录并使用 Docker Compose 启动服务:

cd ~/DeepSeek-OCR-WebUI docker compose up -d

查看容器日志以确认服务启动成功:

docker logs -f deepseek-ocr-webui

服务默认监听http://localhost:8080,可通过浏览器访问 WebUI 页面进行测试。

⚠️ 注意:建议使用 NVIDIA GPU(如 4090D)运行该镜像以获得最佳性能,CPU 模式下推理速度较慢。


4. DeepSeek-OCR接口详解

OCR 服务暴露了一个核心接口用于图像识别:

@app.post("/ocr") async def ocr_endpoint( file: UploadFile = File(...), prompt_type: str = Form("document"), find_term: str = Form(""), custom_prompt: str = Form(""), grounding: bool = Form(False) ):

4.1 关键参数说明

参数名类型可选值说明
file文件必填待识别的图像文件(JPG/PNG等)
prompt_type字符串document,ocr,free,figure,describe,find,freeform控制识别模式
find_term字符串可选查找特定关键词并标注位置
custom_prompt字符串可选自定义提示词,适用于复杂任务
grounding布尔值true/false是否启用实体定位分组

4.2 表格识别推荐配置

由于本文目标是识别表格内容,应选择prompt_type=figure,该模式专为图表、公式、表格设计,能更准确地保留原始布局信息。

例如发送请求时设置:

{ "prompt_type": "figure" }

响应体将返回一个标准 HTML<table>结构字符串,便于后续解析。


5. SpringBoot集成实现

5.1 创建OcrService接口

定义统一的服务接口,便于后续替换或扩展实现:

// src/main/java/com/kaifamiao/dswebui/service/OcrService.java public interface OcrService { /** * 识别表格图片并返回结构化数据 * * @param file 上传的包含表格的图片文件 * @return 包含表格数据的Map对象,将以JSON格式返回给前端 */ Map<String, Object> recognitionTable(MultipartFile file); }

5.2 实现DeepSeekOcrService

创建具体实现类,使用RestTemplate发送 HTTP 请求至 OCR 服务。

// src/main/java/com/kaifamiao/dswebui/service/DeepSeekOcrService.java @Service @Slf4j public class DeepSeekOcrService implements OcrService { private static final String OCR_SERVICE_URL = "http://localhost:8080/ocr"; private final RestTemplate restTemplate; public DeepSeekOcrService() { this.restTemplate = new RestTemplate(); } @Override public Map<String, Object> recognitionTable(MultipartFile file) { log.info("开始识别表格图片: {}", file.getOriginalFilename()); try { // 准备文件资源 ByteArrayResource resource = new ByteArrayResource(file.getBytes()) { @Override public String getFilename() { return file.getOriginalFilename(); } }; // 构建请求参数 MultiValueMap<String, Object> body = new LinkedMultiValueMap<>(); body.add("file", resource); body.add("prompt_type", "figure"); // 使用图表模式识别表格 // 设置请求头 HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.MULTIPART_FORM_DATA); // 创建请求实体 HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers); // 发送POST请求 ResponseEntity<String> response = restTemplate.postForEntity(OCR_SERVICE_URL, requestEntity, String.class); if (response.getStatusCode() == HttpStatus.OK) { String htmlContent = response.getBody(); log.debug("OCR返回HTML: {}", htmlContent); return parseHtmlTableToJSON(htmlContent); } else { log.error("OCR服务调用失败,状态码: {}", response.getStatusCode()); throw new RuntimeException("OCR识别失败"); } } catch (Exception e) { log.error("表格识别过程中发生异常", e); Map<String, Object> errorResult = new HashMap<>(); errorResult.put("success", false); errorResult.put("message", "识别失败:" + e.getMessage()); return errorResult; } } /** * 将HTML表格解析为JSON格式 * * @param html 包含表格的HTML字符串 * @return 转换后的JSON数据 */ private Map<String, Object> parseHtmlTableToJSON(String html) { Document doc = Jsoup.parse(html); Element table = doc.selectFirst("table"); List<Map<String, String>> rows = new ArrayList<>(); if (table != null) { Elements trList = table.select("tr"); for (Element tr : trList) { Elements tds = tr.select("td"); Map<String, String> row = new LinkedHashMap<>(); for (int i = 0; i < tds.size(); i++) { String text = tds.get(i).text().trim(); // 使用列索引作为key,也可提取表头做字段映射 row.put("col_" + i, text.isEmpty() ? "" : text); } rows.add(row); } } Map<String, Object> result = new HashMap<>(); result.put("success", true); result.put("data", rows); result.put("totalRows", rows.size()); return result; } }
依赖说明
  • RestTemplate:用于发起 HTTP 请求
  • Jsoup:轻量级 HTML 解析库,用于提取<table>内容
  • 添加依赖到pom.xml
<dependency> <groupId>org.jsoup</groupId> <artifactId>jsoup</artifactId> <version>1.16.1</version> </dependency>

5.3 编写单元测试验证功能

编写测试用例验证 OCR 服务是否正常工作。

// src/test/java/com/kaifamiao/dswebui/service/OcrServiceTest.java @SpringBootTest @Slf4j public class OcrServiceTest { @Autowired private OcrService ocrService; @Test void testRecognitionTableSuccess() throws Exception { // 从测试资源目录加载voucher.jpg文件 ClassPathResource resource = new ClassPathResource("voucher.jpg"); // 创建MultipartFile对象 MockMultipartFile file = new MockMultipartFile( "file", "voucher.jpg", "image/jpeg", resource.getInputStream() ); // 调用OCR服务进行识别 Map<String, Object> result = ocrService.recognitionTable(file); log.info("OCR识别结果: {}", JSON.toJSONString(result)); Assertions.assertTrue((Boolean) result.get("success")); } }

运行测试,观察日志输出是否成功解析出表格行数及内容。


5.4 提供REST API接口

创建控制器暴露 HTTP 接口供前端调用。

// src/main/java/com/kaifamiao/dswebui/controller/OcrController.java @RestController @RequestMapping("/api/ocr") @Slf4j public class OcrController { @Autowired private OcrService ocrService; @PostMapping("/process") public Map<String, Object> processFile(@RequestParam("file") MultipartFile file) { Map<String, Object> result = ocrService.recognitionTable(file); log.info("返回结果: {}", result); return result; } }

接口地址:POST /api/ocr/process,接受multipart/form-data格式的图片上传。


6. 前端页面集成

前端采用 Vue 实现简单上传界面,核心代码如下:

<template> <div class="container"> <h2>表格识别系统</h2> <input type="file" @change="handleFileChange" accept="image/*" /> <button @click="upload">上传识别</button> <div v-if="result"> <h3>识别结果(JSON):</h3> <pre>{{ JSON.stringify(result, null, 2) }}</pre> </div> </div> </template> <script setup> import { ref } from 'vue'; import axios from 'axios'; const file = ref(null); const result = ref(null); const handleFileChange = (e) => { file.value = e.target.files[0]; }; const upload = async () => { if (!file.value) { alert('请选择图片'); return; } const formData = new FormData(); formData.append('file', file.value); try { const res = await axios.post('/api/ocr/process', formData, { headers: { 'Content-Type': 'multipart/form-data' } }); result.value = res.data; } catch (err) { console.error(err); alert('识别失败'); } }; </script>

6.1 前端构建与打包

确保安装 Node.js 20+:

npm install npm run build

生成的dist目录需复制到 SpringBoot 的src/main/resources/static下,使静态资源可被直接访问。


7. 打包与Docker部署

7.1 后端打包

使用 Maven 构建 JAR 包:

mvn clean package -DskipTests

生成的文件位于target/deepseek-web-ui-1.0.0.jar


7.2 编写Dockerfile

# Java运行时阶段 FROM openjdk:21-jdk-slim # 设置工作目录 WORKDIR /app # 复制前端构建产物到后端静态资源目录 COPY target/deepseek-web-ui-1.0.0.jar /app/deepseek-web-ui.jar # 暴露端口 EXPOSE 8080 # 运行应用 ENTRYPOINT ["java", "-jar", "deepseek-web-ui.jar"]

7.3 编写docker-compose.yml

version: '3.8' services: ocr-app: build: . ports: - "8080:8080" environment: - SERVER_PORT=8080 volumes: - ./logs:/app/logs

启动服务:

docker compose up -d --build

访问http://localhost:8080即可打开前端页面,上传表格图片进行识别。


8. 总结

本文详细介绍了如何将DeepSeek-OCR-WEBUI集成到SpringBoot应用中,实现对表格图像的自动识别与结构化输出。主要成果包括:

  1. ✅ 成功调用本地 OCR 服务 API 实现图像识别
  2. ✅ 将返回的 HTML 表格解析为标准 JSON 格式,便于前后端交互
  3. ✅ 构建完整的前后端联调系统,支持图片上传与结果展示
  4. ✅ 使用 Docker 完成一体化部署,提升可移植性与维护效率

该方案已在实际业务场景中验证有效,显著降低了人工录入成本,提升了数据处理效率。未来可进一步优化方向包括:

  • 支持多页PDF批量识别
  • 增加表头语义识别,自动映射数据库字段
  • 引入异步任务机制,避免长时间阻塞请求

通过本次实践,开发者可以快速掌握 AI OCR 技术在企业级 Java 应用中的落地方法,为智能化文档处理提供有力支撑。


获取更多AI镜像

想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/20 6:01:20

G-Helper终极教程:轻松掌控华硕笔记本的轻量化神器

G-Helper终极教程&#xff1a;轻松掌控华硕笔记本的轻量化神器 【免费下载链接】g-helper Lightweight Armoury Crate alternative for Asus laptops. Control tool for ROG Zephyrus G14, G15, G16, M16, Flow X13, Flow X16, TUF, Strix, Scar and other models 项目地址: …

作者头像 李华
网站建设 2026/3/21 17:16:31

Qwen2.5-0.5B如何按需付费?低成本运维实战

Qwen2.5-0.5B如何按需付费&#xff1f;低成本运维实战 1. 背景与需求分析 随着大模型技术的普及&#xff0c;越来越多企业和开发者希望将AI能力集成到实际业务中。然而&#xff0c;高性能大模型通常依赖昂贵的GPU资源&#xff0c;导致推理成本居高不下&#xff0c;尤其对于初…

作者头像 李华
网站建设 2026/3/15 9:12:09

Bodymovin扩展面板完整配置指南:3步实现AE动画高效导出

Bodymovin扩展面板完整配置指南&#xff1a;3步实现AE动画高效导出 【免费下载链接】bodymovin-extension Bodymovin UI extension panel 项目地址: https://gitcode.com/gh_mirrors/bod/bodymovin-extension Bodymovin作为业界领先的After Effects动画导出解决方案&…

作者头像 李华
网站建设 2026/3/14 0:36:45

2025年终极护眼神器:用Dark Reader告别深夜浏览的视觉疲劳

2025年终极护眼神器&#xff1a;用Dark Reader告别深夜浏览的视觉疲劳 【免费下载链接】darkreader Dark Reader Chrome and Firefox extension 项目地址: https://gitcode.com/gh_mirrors/da/darkreader 还在为深夜coding时刺眼的白色背景苦恼吗&#xff1f;长文阅读时…

作者头像 李华
网站建设 2026/3/14 8:58:08

2026年AI检索系统入门必看:Qwen3嵌入模型实战指南

2026年AI检索系统入门必看&#xff1a;Qwen3嵌入模型实战指南 随着信息量的爆炸式增长&#xff0c;传统关键词匹配已无法满足现代搜索系统对语义理解、多语言支持和长文本处理的需求。在这一背景下&#xff0c;基于大模型的语义嵌入技术成为构建智能检索系统的基石。Qwen3 Emb…

作者头像 李华
网站建设 2026/3/14 7:38:24

AnimeGANv2一键部署教程:10分钟搭建个人动漫转换站

AnimeGANv2一键部署教程&#xff1a;10分钟搭建个人动漫转换站 1. 引言 随着AI技术在图像生成领域的不断突破&#xff0c;风格迁移&#xff08;Style Transfer&#xff09;已成为普通人也能轻松使用的创意工具。其中&#xff0c;AnimeGANv2 因其出色的二次元风格转换效果&…

作者头像 李华