德阳市网站建设_网站建设公司_轮播图_seo优化
2026/1/16 5:34:51 网站建设 项目流程

基于DeepSeek-OCR-WEBUI的文档识别实践|SpringBoot应用无缝对接

1. 背景与业务场景

在企业级应用中,大量纸质单据如采购订单、发票、入库凭证等仍需人工录入系统,不仅效率低下,还容易出错。随着AI技术的发展,光学字符识别(OCR)已成为自动化数据采集的关键手段。

DeepSeek-OCR-WEBUI 是基于深度学习的大模型OCR解决方案,具备高精度、多语言支持和复杂场景适应能力。其开源特性与Web API设计,使其非常适合集成到现有Java后端系统中,实现“拍照→识别→结构化输出→人工校验→一键入库”的完整流程。

本文将详细介绍如何将DeepSeek-OCR-WEBUI部署为独立服务,并通过SpringBoot应用调用其API完成表格图像识别,最终实现前端可视化展示与数据结构化转换。


2. DeepSeek-OCR-WEBUI 核心功能解析

2.1 技术架构概述

DeepSeek-OCR-WEBUI 采用 CNN + Attention 的混合架构,结合文本检测(Text Detection)与文本识别(Text Recognition)双阶段模型,能够精准定位图像中的文字区域并进行高准确率解码。系统内置后处理模块,可自动修复断字、纠正拼写错误、统一标点格式。

该服务以 Docker 容器形式提供,包含以下核心组件:

  • web_service.py:Flask 实现的 RESTful API 接口
  • OCR 模型文件:预训练权重,支持中文为主、多语言扩展
  • 前端 WebUI:用于本地测试与调试的图形界面

2.2 关键接口说明

服务启动后,默认监听http://localhost:8080,主要接口如下:

@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) )
参数名类型可选值说明
file文件上传-待识别的图片文件(JPG/PNG等)
prompt_type字符串document,ocr,free,figure,describe,find,freeform控制识别模式
find_term字符串自定义关键词用于字段定位(如“发票号”)
custom_prompt字符串用户自定义提示词扩展识别逻辑
grounding布尔值true/false是否启用实体分组

特别注意:本文目标是识别表格内容,因此应使用prompt_type=figure,此模式专为图表、公式、表格设计,能有效提取<table>结构的 HTML 输出。


3. SpringBoot 后端集成方案

3.1 系统架构设计

整体架构分为三层:

  1. 前端层:Vue 构建的操作页面,支持图片上传与结果显示
  2. 业务层:SpringBoot 提供 REST API,负责调用 OCR 服务并处理响应
  3. AI 层:DeepSeek-OCR-WEBUI 容器服务,执行实际 OCR 识别任务

各层之间通过 HTTP 协议通信,松耦合设计便于部署与维护。

3.2 环境准备与依赖配置

确保已安装:

  • JDK 21+
  • Maven 3.8+
  • Node.js 20+(用于前端构建)
  • Docker & Docker Compose

Maven 添加关键依赖:

<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> </dependency> <dependency> <groupId>org.jsoup</groupId> <artifactId>jsoup</artifactId> <version>1.16.1</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>

其中jsoup用于解析 OCR 返回的 HTML 表格内容。


4. 核心代码实现

4.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); }

4.2 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 RestTemplate restTemplate; public DeepSeekOcrService() { SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory(); factory.setConnectTimeout(30000); factory.setReadTimeout(60000); this.restTemplate = new RestTemplate(factory); } @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 模式识别表格 body.add("grounding", false); // 设置请求头 HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.MULTIPART_FORM_DATA); // 创建请求实体 HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers); // 发送POST请求到OCR服务 ResponseEntity<String> response = restTemplate.postForEntity(OCR_SERVICE_URL, requestEntity, String.class); if (response.getStatusCode().is2xxSuccessful() && response.getBody() != null) { log.info("OCR识别成功,返回HTML长度: {}", response.getBody().length()); return parseHtmlTableToJSON(response.getBody()); } else { log.error("OCR服务返回异常状态码: {}", response.getStatusCode()); throw new RuntimeException("OCR识别失败:" + response.getStatusCode()); } } catch (Exception e) { log.error("调用OCR服务发生异常", e); throw new RuntimeException("OCR识别请求失败: " + e.getMessage(), 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"); if (table == null) { throw new IllegalArgumentException("未找到<table>标签"); } List<Map<String, String>> rows = new ArrayList<>(); Elements trList = table.select("tr"); boolean isFirstRow = 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 (isFirstRow) { headers.add("col_" + i); } else { String key = i < headers.size() ? headers.get(i) : "col_" + i; row.put(key, text); } } if (!isFirstRow) { rows.add(row); } isFirstRow = false; } Map<String, Object> result = new HashMap<>(); result.put("success", true); result.put("data", rows); result.put("totalRows", rows.size()); return result; } }
代码要点说明:
  • 使用RestTemplate发起带文件上传的 multipart/form-data 请求
  • prompt_type="figure"是识别表格的关键参数
  • 利用Jsoup解析返回的 HTML<table>并转换为 JSON 数组
  • 表头动态生成(col_0,col_1...),避免硬编码列名

4.3 Controller 层暴露接口

// 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) { if (file.isEmpty()) { return Map.of("success", false, "message", "文件为空"); } try { Map<String, Object> result = ocrService.recognitionTable(file); log.info("OCR识别结果: {}", result); return result; } catch (Exception e) { log.error("处理文件时发生错误", e); return Map.of("success", false, "message", "识别失败:" + e.getMessage()); } } }

该接口接收前端上传的图片,调用服务层完成识别,并返回结构化 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"); // 创建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")); Assertions.assertNotNull(result.get("data")); Assertions.assertTrue(((List<?>) result.get("data")).size() > 0); } }

测试用例确保服务在本地环境下正常运行,可在 CI/CD 流程中加入自动化测试环节。


5. 前端页面集成与打包

5.1 Vue 页面功能说明

前端项目位于ui/目录下,主要功能包括:

  • 图片上传组件
  • 实时进度提示
  • 表格数据渲染
  • 错误信息展示

页面通过 Axios 调用/api/ocr/process接口,接收 JSON 数据并在页面上以表格形式呈现。

5.2 构建与集成步骤

cd ui npm install npm run build

构建完成后,dist/目录生成静态资源文件,将其复制到 SpringBoot 项目的src/main/resources/static/下:

cp -r ui/dist/* src/main/resources/static/

SpringBoot 默认会托管static目录下的静态资源,访问http://localhost:8080即可打开操作界面。


6. Docker 容器化部署

6.1 后端 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"]

6.2 docker-compose.yml 统一编排

version: '3.8' services: deepseek-ocr-webui: image: deepseek-ocr-webui:latest container_name: deepseek-ocr-webui ports: - "8080:8080" volumes: - ./logs:/app/logs restart: unless-stopped ocr-app: build: . ports: - "8081:8080" environment: - SERVER_PORT=8080 depends_on: - deepseek-ocr-webui volumes: - ./logs:/app/logs

注意:OCR 服务运行在 8080 端口,SpringBoot 应用改为 8081 或其他端口避免冲突。

6.3 启动命令

docker compose up -d --build

服务启动后:

  • 访问http://localhost:8081查看前端页面
  • SpringBoot 自动调用http://deepseek-ocr-webui:8080/ocr完成识别

7. 总结

7.1 实践价值总结

本文实现了DeepSeek-OCR-WEBUISpringBoot的无缝集成,完成了从图像输入到结构化数据输出的全流程闭环。该方案具有以下优势:

  • 高可用性:OCR 服务独立部署,不影响主业务系统稳定性
  • 易扩展性:可通过修改prompt_type支持合同、发票、手写体等多种场景
  • 低成本接入:无需自研OCR模型,直接调用成熟AI能力
  • 国产化支持:DeepSeek 作为国产大模型,在中文识别上表现优异

7.2 最佳实践建议

  1. 错误重试机制:对网络不稳定场景添加重试逻辑(如 Spring Retry)
  2. 异步处理优化:对于大图或批量识别,建议引入消息队列(RabbitMQ/Kafka)异步处理
  3. 缓存策略:相同图片可做 MD5 缓存,避免重复识别
  4. 安全控制:限制上传文件类型与大小,防止恶意攻击
  5. 日志监控:记录识别耗时、成功率等指标,便于性能分析

获取更多AI镜像

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

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

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

立即咨询