衢州市网站建设_网站建设公司_百度智能云_seo优化
2026/1/17 5:24:57 网站建设 项目流程

SpringBoot集成DeepSeek-OCR实战|高效识别表格数据

1. 背景与业务场景

在企业级应用中,大量纸质单据如采购订单、发票、入库单等仍需人工录入系统。这种方式不仅效率低下,还容易因人为因素导致数据错误。随着AI技术的发展,光学字符识别(OCR)成为自动化处理文档信息的关键手段。

DeepSeek-OCR 是由 DeepSeek 开源的一款高性能 OCR 大模型,具备强大的文本检测与识别能力,尤其擅长复杂场景下的表格、公式、手写体等内容的精准提取。其 WebUI 版本提供了便捷的部署方式和标准化 API 接口,非常适合集成到 Java 后端服务中。

本文将详细介绍如何在SpringBoot项目中接入已部署的DeepSeek-OCR-WEBUI服务,实现对包含表格图像的自动识别,并将识别结果转换为结构化 JSON 数据,供前端展示或后续业务逻辑使用。


2. 环境准备与服务启动

2.1 部署 DeepSeek-OCR-WEBUI 服务

要实现 SpringBoot 应用调用 OCR 功能,首先需要确保DeepSeek-OCR-WEBUI已正确部署并运行。该服务基于 Docker 容器化部署,支持 GPU 加速推理(推荐使用 4090D 单卡环境)。

进入项目目录并启动服务:

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

查看容器日志以确认服务正常启动:

docker logs -f deepseek-ocr-webui

服务成功启动后,默认监听http://localhost:8080,提供/ocr接口用于接收图片并返回识别结果。

注意:若修改了web_service.py中的接口逻辑,需重新构建镜像才能生效。


3. DeepSeek-OCR API 接口详解

核心识别接口定义位于/home/qy/DeepSeek-OCR-WebUI/web_service.py文件中的/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) ):

3.1 参数说明

参数名类型可选值说明
fileUploadFile必填待识别的图像文件(JPEG/PNG等格式)
prompt_typestrdocument,ocr,free,figure,describe,find,freeform指定识别模式
find_termstr可选查找特定关键词并标注位置
custom_promptstr可选自定义提示词,适用于freeform模式
groundingboolTrue/False是否进行语义分组

3.2 识别模式选择

对于表格数据识别,应选用prompt_type=figure模式。此模式专为图表、公式、结构化表格设计,能够准确还原行列布局,输出 HTML 格式的<table>结构。

例如,上传一张采购单截图,API 返回如下 HTML 内容:

<table> <tr><td>序号</td><td>条码</td><td>名称</td><td>单位</td><td>订货数量</td><td>采购数量</td></tr> <tr><td>1</td><td>6949123352617</td><td>飞科PR-5261毛球修剪器</td><td>个</td><td>0.00</td><td>1.00</td></tr> <tr><td>2</td><td>6944296500049</td><td>天香炸酱面180g*50</td><td>个</td><td>0.00</td><td>1.00</td></tr> <tr><td>总计</td><td></td><td></td><td></td><td>0.00</td><td>2.00</td></tr> </table>

该 HTML 表格可被进一步解析为 JSON 数组,便于前后端交互。


4. SpringBoot 集成实现

4.1 项目结构概览

src/ ├── main/ │ ├── java/ │ │ └── com/kaifamiao/dswebui/ │ │ ├── controller/OcrController.java │ │ ├── service/OcrService.java │ │ └── service/DeepSeekOcrService.java │ └── resources/ │ └── application.yml └── test/ └── java/ └── OcrServiceTest.java

4.2 定义 OCR 服务接口

创建OcrService接口,声明表格识别方法:

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

4.3 实现 DeepSeek 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 = 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"); // 关键:使用 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().is2xxSuccessful()) { String htmlContent = response.getBody(); log.info("OCR 返回 HTML 内容: {}", htmlContent); return parseHtmlTableToJSON(htmlContent); } else { log.error("OCR 服务调用失败,状态码: {}", response.getStatusCode()); throw new RuntimeException("OCR 服务异常"); } } catch (IOException e) { log.error("文件读取失败", e); throw new RuntimeException("文件处理失败", e); } } /** * 将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"); boolean isHeader = true; List<String> headers = new ArrayList<>(); for (Element tr : trList) { Elements tds = tr.select("td"); Map<String, String> row = new HashMap<>(); for (int i = 0; i < tds.size(); i++) { String text = tds.get(i).text().trim(); if (isHeader) { headers.add(tds.get(i).text().trim()); } else { if (i < headers.size()) { row.put(headers.get(i), text); } } } if (isHeader) { isHeader = false; } else { rows.add(row); } } } Map<String, Object> result = new HashMap<>(); result.put("success", true); result.put("data", rows); return result; } }
核心要点说明:
  • 使用RestTemplate发起 HTTP 请求,支持文件上传。
  • 设置prompt_type=figure以启用表格识别模式。
  • 利用Jsoup解析返回的 HTML 表格内容,提取表头与行数据。
  • 将每行数据映射为Map<String, String>,最终封装为 JSON 数组。

4.4 编写测试用例验证功能

// 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"); 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")); Assertions.assertFalse(((List<?>) result.get("data")).isEmpty()); } }

测试通过后,控制台将输出类似以下结构的数据:

{ "success": true, "data": [ { "序号": "1", "条码": "6949123352617", "名称": "飞科PR-5261毛球修剪器", "单位": "个", "采购数量": "1.00" }, { "序号": "2", "条码": "6944296500049", "名称": "天香炸酱面180g*50", "单位": "个", "采购数量": "1.00" } ] }

4.5 提供 REST 控制器接口

// 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上传图片,获取结构化表格数据。


5. 前端页面集成(Vue)

项目附带一个基于 Vue 的前端界面,用于上传图片并展示识别结果。

5.1 页面功能说明

  • 图片上传组件
  • 实时预览上传图像
  • 显示 OCR 识别后的结构化表格
  • 支持人工校验后一键入库

5.2 构建与打包

安装 Node.js 20+ 并执行构建:

npm install npm run build

生成的静态资源位于dist/目录,需复制到 SpringBoot 项目的src/main/resources/static/下。


6. 打包与 Docker 部署

6.1 后端打包

使用 Maven 构建 JAR 包:

mvn clean package -DskipTests

生成的 jar 文件路径:target/deepseek-web-ui-1.0.0.jar


6.2 Docker 镜像构建

编写Dockerfile

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"]

配套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即可使用完整 OCR 应用。


7. 总结

本文详细介绍了如何将 DeepSeek-OCR-WEBUI 集成至 SpringBoot 应用中,实现高效、准确的表格数据识别。整个流程涵盖:

  1. 本地部署 DeepSeek-OCR 服务,利用 Docker 快速启动;
  2. 理解 API 接口参数,特别是prompt_type=figure对表格识别的关键作用;
  3. SpringBoot 实现文件上传与远程调用,结合RestTemplateJsoup完成数据获取与解析;
  4. 前后端联调与打包部署,形成完整的可运行系统。

该方案显著提升了纸质单据数字化效率,减少人工录入成本,适用于金融、物流、教育等多个行业场景。

未来可扩展方向包括:

  • 添加异步任务队列处理大批量图片;
  • 引入缓存机制避免重复识别;
  • 结合 NLP 技术实现字段语义理解与自动填充。

获取更多AI镜像

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询