news 2026/6/10 19:36:21

DeepSeek-OCR-WEBUI + SpringBoot 构建智能单据处理系统

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
DeepSeek-OCR-WEBUI + SpringBoot 构建智能单据处理系统

DeepSeek-OCR-WEBUI + SpringBoot 构建智能单据处理系统

1. 背景与需求分析

在企业级应用中,大量纸质单据(如采购订单、发票、入库单等)仍需人工录入到业务系统。这一过程不仅效率低下,且容易出错。随着AI技术的发展,尤其是大模型驱动的OCR能力显著提升,构建一个自动化、高精度的智能单据识别系统已成为可能。

DeepSeek-OCR-WEBUI 是基于深度学习的大模型OCR工具,具备强大的文本定位与结构化信息提取能力,尤其擅长表格、图表和复杂布局文档的识别。结合SpringBoot构建后端服务,可以实现从图像上传、OCR识别到数据结构化解析的完整流程,最终形成可落地的企业级解决方案。

本文将围绕“如何使用 DeepSeek-OCR-WEBUI 与 SpringBoot 构建智能单据处理系统”展开,涵盖环境部署、接口调用、HTML解析、前后端集成及容器化发布全过程,帮助开发者快速实现业务场景中的自动化数据采集。


2. 系统架构设计

2.1 整体架构图

+------------------+ HTTP POST +---------------------+ | 前端页面 (Vue) | ----------------> | SpringBoot 应用服务 | +------------------+ +----------+----------+ | 调用 OCR API | v +-----------------------------+ | DeepSeek-OCR-WEBUI (Docker) | +-----------------------------+ | 返回 HTML 表格字符串 | v +----------------------------+ | SpringBoot 解析为 JSON 数据 | +----------------------------+ | 返回给前端展示/入库 | v +--------------------+ | 数据库存储或人工校验 | +--------------------+

该系统采用分层解耦设计:

  • 前端层:Vue 实现用户交互界面,支持图片上传与结果展示;
  • 应用层:SpringBoot 提供 RESTful 接口,负责协调文件传输与OCR调用;
  • 识别层:DeepSeek-OCR-WEBUI 提供高性能OCR能力,返回结构化HTML;
  • 解析层:Java 后端对HTML中的<table>进行DOM解析并转换为JSON;
  • 持久层:可选接入数据库完成数据持久化。

3. DeepSeek-OCR-WEBUI 部署与API说明

3.1 部署OCR服务

确保已安装 Docker 和 GPU驱动(推荐NVIDIA 4090D单卡),执行以下命令启动OCR服务:

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

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

docker logs -f deepseek-ocr-webui

服务启动后,默认监听http://localhost:8080,提供Web UI 和 API 接口。


3.2 OCR核心API详解

OCR服务暴露的核心接口位于/web_service.py中:

@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文件必填待识别的图像文件
prompt_type字符串document,ocr,free,figure,describe,find,freeform指定识别模式
find_term字符串可选查找特定字段(如“发票号”)
custom_prompt字符串可选自定义提示词
grounding布尔值true/false是否启用实体标注
本项目关键配置:

为了识别表格内容,必须设置prompt_type=figure,该模式专为图表、公式、表格设计,能准确还原行列结构。

示例请求:

POST http://localhost:8080/ocr Content-Type: multipart/form-data file: voucher.jpg prompt_type: figure

响应示例(简化):

<table> <tr><td>序号</td><td>条码</td><td>名称</td>...</tr> <tr><td>1</td><td>6949123352617</td><td>飞科PR-5261毛球修剪器</td>...</tr> ... </table>

4. SpringBoot 应用开发实践

4.1 项目结构概览

src/ ├── main/ │ ├── java/com/kaifamiao/dswebui/ │ │ ├── controller/OcrController.java │ │ ├── service/OcrService.java │ │ └── service/DeepSeekOcrService.java │ └── resources/ │ ├── static/ <-- Vue 打包产物 │ └── application.yml └── test/ └── java/com/kaifamiao/dswebui/service/OcrServiceTest.java

使用 Maven 构建,依赖包括:

<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.jsoup</groupId> <artifactId>jsoup</artifactId> <version>1.16.1</version> </dependency> <dependency> <groupId>com.alibaba.fastjson2</groupId> <artifactId>fastjson2</artifactId> <version>2.0.43</version> </dependency> </dependencies>

4.2 定义OCR服务接口

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

4.3 实现OCR调用逻辑

// DeepSeekOcrService.java @Service @Slf4j public class DeepSeekOcrService implements OcrService { private static final String OCR_SERVICE_URL = "http://localhost:8080/ocr"; @Override public Map<String, Object> recognitionTable(MultipartFile file) { log.info("开始处理文件: {}", file.getOriginalFilename()); RestTemplate restTemplate = new RestTemplate(); 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().is2xxSuccessful()) { String htmlContent = response.getBody(); return parseHtmlTableToJSON(htmlContent); } else { log.error("OCR服务返回错误状态: {}", response.getStatusCode()); throw new RuntimeException("OCR识别失败"); } } catch (Exception e) { log.error("调用OCR服务异常", e); throw new RuntimeException("文件处理失败: " + 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("未找到表格元素"); } 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,th"); 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); row.put("col_" + i, text); } else { String key = i < headers.size() ? headers.get(i) : "col_" + i; row.put(key, text); } } 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发起多部分表单请求;
  • prompt_type=figure是识别表格的关键;
  • 利用Jsoup解析HTML<table>结构;
  • 动态生成列名(col_0,col_1...)避免空标题问题;
  • 输出标准JSON结构,便于前端渲染。

4.4 控制器层暴露接口

// 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.get("totalRows")); return result; } catch (Exception e) { log.error("处理文件失败", e); return Map.of("success", false, "message", "识别失败:" + e.getMessage()); } } }

4.5 编写单元测试验证功能

// OcrServiceTest.java @SpringBootTest @Slf4j public class OcrServiceTest { @Autowired private OcrService ocrService; @Test void testRecognitionTableSuccess() throws Exception { ClassPathResource resource = new ClassPathResource("voucher.jpg"); MockMultipartFile file = new MockMultipartFile( "file", "voucher.jpg", "image/jpeg", resource.getInputStream() ); Map<String, Object> result = ocrService.recognitionTable(file); log.info("OCR识别结果: {}", JSON.toJSONString(result)); Assertions.assertTrue((Boolean) result.get("success")); Assertions.assertTrue((Integer) result.get("totalRows") > 0); } }

运行测试可验证是否能正确调用OCR服务并解析出表格数据。


5. 前端页面集成(Vue)

5.1 页面功能设计

前端使用 Vue 实现简单操作界面,主要功能包括:

  • 图片上传组件;
  • 实时进度提示;
  • 表格数据预览;
  • 导出或提交按钮。

5.2 核心代码片段

<template> <div class="container"> <h2>智能单据识别系统</h2> <input type="file" @change="handleFileUpload" accept="image/*" /> <button @click="submit" :disabled="!selectedFile">开始识别</button> <div v-if="loading">正在识别...</div> <table v-if="tableData.length > 0" border="1" cellpadding="8" style="margin-top: 20px;"> <thead> <tr v-for="(row, i) in tableData.slice(0, 1)" :key="i"> <th v-for="(value, key) in row" :key="key">{{ key }}</th> </tr> </thead> <tbody> <tr v-for="(row, i) in tableData" :key="i"> <td v-for="(value, key) in row" :key="key">{{ value }}</td> </tr> </tbody> </table> </div> </template> <script> export default { data() { return { selectedFile: null, tableData: [], loading: false }; }, methods: { handleFileUpload(e) { this.selectedFile = e.target.files[0]; }, async submit() { if (!this.selectedFile) return; const formData = new FormData(); formData.append('file', this.selectedFile); this.loading = true; try { const res = await fetch('/api/ocr/process', { method: 'POST', body: formData }); const data = await res.json(); if (data.success) { this.tableData = data.data; } else { alert('识别失败: ' + data.message); } } catch (err) { alert('请求失败: ' + err.message); } finally { this.loading = false; } } } }; </script>

5.3 前端打包与集成

进入ui/目录,执行:

npm install npm run build

将生成的dist/文件夹复制到 SpringBoot 的src/main/resources/static/下即可通过/访问页面。


6. 容器化部署方案

6.1 Dockerfile 构建应用镜像

FROM openjdk:21-jdk-slim WORKDIR /app COPY target/deepseek-web-ui.jar /app/deepseek-web-ui.jar EXPOSE 8080 ENTRYPOINT ["java", "-jar", "deepseek-web-ui.jar"]

6.2 docker-compose.yml 统一编排

version: '3.8' services: ocr-app: build: . ports: - "8080:8080" environment: - SERVER_PORT=8080 volumes: - ./logs:/app/logs depends_on: - deepseek-ocr-webui deepseek-ocr-webui: image: deepseek-ocr-webui:latest container_name: deepseek-ocr-webui ports: - "8081:8080" runtime: nvidia deploy: resources: reservations: devices: - driver: nvidia count: 1 capabilities: [gpu]

注意:OCR服务映射为8081:8080,避免端口冲突。


6.3 启动完整服务栈

docker compose up -d --build

访问http://localhost:8080即可使用完整的单据识别系统。


7. 总结

本文详细介绍了如何利用DeepSeek-OCR-WEBUI + SpringBoot构建一套完整的智能单据处理系统,实现了从图像上传、表格识别、结构化解析到前后端展示的全流程闭环。

核心价值总结:

  • 高精度识别:借助大模型OCR能力,显著提升复杂单据的识别准确率;
  • 工程可落地:通过标准化REST API调用,易于集成进现有系统;
  • 结构化输出:将HTML表格自动转为JSON,便于后续处理;
  • 全栈可控:从前端到后端再到AI引擎,全部自主掌控;
  • 容器化部署:支持一键启动,适合生产环境部署。

最佳实践建议:

  1. 对于敏感字段(如金额、条码),建议增加人工复核环节;
  2. 可扩展添加图像预处理模块(去噪、矫正倾斜)以提高识别率;
  3. 在并发量较大时,考虑引入消息队列异步处理OCR任务;
  4. 定期更新OCR模型版本以获得更好的识别效果。

该方案已在多个实际项目中验证其稳定性与实用性,适用于金融、物流、零售等行业场景下的数字化转型需求。


获取更多AI镜像

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

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

2024年图片旋转判断技术发展趋势预测

2024年图片旋转判断技术发展趋势预测 1. 图片旋转判断的技术背景与核心挑战 在数字图像处理领域&#xff0c;图片旋转判断&#xff08;Image Orientation Detection&#xff09;是一项基础但关键的任务。随着移动设备、无人机、智能相机等终端的普及&#xff0c;用户拍摄的图…

作者头像 李华
网站建设 2026/6/10 18:34:42

bge-m3 vs E5-Mistral:大模型嵌入层性能全面对比评测

bge-m3 vs E5-Mistral&#xff1a;大模型嵌入层性能全面对比评测 1. 引言&#xff1a;为何需要高质量文本嵌入&#xff1f; 随着检索增强生成&#xff08;RAG&#xff09;和语义搜索技术的广泛应用&#xff0c;文本嵌入&#xff08;Text Embedding&#xff09;作为连接自然语…

作者头像 李华
网站建设 2026/6/10 18:01:13

Nucleus Co-Op分屏游戏终极指南:3步开启单机游戏多人派对

Nucleus Co-Op分屏游戏终极指南&#xff1a;3步开启单机游戏多人派对 【免费下载链接】nucleuscoop Starts multiple instances of a game for split-screen multiplayer gaming! 项目地址: https://gitcode.com/gh_mirrors/nu/nucleuscoop 还记得那些只能独自享受的单机…

作者头像 李华
网站建设 2026/6/10 19:07:19

核心要点:UDS NRC如何精准反馈ECU服务请求失败原因

如何让ECU“说清楚”哪里错了&#xff1f;——深入解析UDS负响应码&#xff08;NRC&#xff09;的精准诊断之道 你有没有遇到过这样的场景&#xff1a; 刷写Bootloader失败&#xff0c;诊断仪只回了一句“服务未执行”&#xff0c;然后就没了下文&#xff1f; 或者在产线测试…

作者头像 李华
网站建设 2026/6/10 16:13:54

小白也能懂!MinerU智能文档解析保姆级教程

小白也能懂&#xff01;MinerU智能文档解析保姆级教程 1. 引言&#xff1a;为什么需要智能文档解析&#xff1f; 在当今信息爆炸的时代&#xff0c;我们每天都会接触到大量的PDF文档、扫描件、学术论文和报表。这些文档往往包含复杂的排版、图表、公式和多列布局&#xff0c;…

作者头像 李华
网站建设 2026/6/10 16:12:59

抖音批量下载终极指南:自动化工具实现高效视频采集

抖音批量下载终极指南&#xff1a;自动化工具实现高效视频采集 【免费下载链接】douyinhelper 抖音批量下载助手 项目地址: https://gitcode.com/gh_mirrors/do/douyinhelper 还在为手动保存抖音视频而烦恼吗&#xff1f;抖音批量下载助手为你提供了一套完整的自动化工具…

作者头像 李华