news 2026/3/28 12:38:20

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/3/15 15:32:02

Qwen2.5推荐部署配置:4090D x4集群最优参数设置实战指南

Qwen2.5推荐部署配置&#xff1a;4090D x4集群最优参数设置实战指南 1. 引言 1.1 业务场景描述 随着大语言模型在实际应用中的广泛落地&#xff0c;轻量级但高性能的模型部署方案成为开发者和企业关注的重点。Qwen2.5-0.5B-Instruct 作为阿里云最新推出的指令调优小型语言模型…

作者头像 李华
网站建设 2026/3/22 11:35:55

安卓手机变身全能输入设备:USB HID客户端深度解析

安卓手机变身全能输入设备&#xff1a;USB HID客户端深度解析 【免费下载链接】android-hid-client Android app that allows you to use your phone as a keyboard and mouse WITHOUT any software on the other end (Requires root) 项目地址: https://gitcode.com/gh_mirr…

作者头像 李华
网站建设 2026/3/24 17:41:12

FST ITN-ZH教程:中文文本标准化系统日志分析

FST ITN-ZH教程&#xff1a;中文文本标准化系统日志分析 1. 简介与背景 随着语音识别、自然语言处理和智能客服系统的广泛应用&#xff0c;中文逆文本标准化&#xff08;Inverse Text Normalization, ITN&#xff09; 成为关键的后处理环节。在语音识别输出中&#xff0c;数字…

作者头像 李华
网站建设 2026/3/26 11:33:02

手把手教你读懂L298N电机驱动原理图中的H桥设计

手把手教你读懂L298N电机驱动原理图中的H桥设计你有没有遇到过这种情况&#xff1a;手握一块L298N驱动模块&#xff0c;接上电机、电源和Arduino&#xff0c;代码一烧录——电机不转&#xff1f;反转了&#xff1f;或者芯片烫得能煎蛋&#xff1f;别急&#xff0c;问题很可能不…

作者头像 李华
网站建设 2026/3/27 5:29:40

一文说清L298N电机驱动核心要点:工作模式图解说明

从零搞懂L298N&#xff1a;不只是接线&#xff0c;更是理解电机控制的起点你有没有在做智能小车时&#xff0c;遇到过这样的问题——明明代码烧进去了&#xff0c;电机却不转&#xff1f;或者一通电就发热严重&#xff0c;甚至芯片烫得不敢碰&#xff1f;又或者想让小车急停&am…

作者头像 李华
网站建设 2026/3/15 17:11:15

Open Interpreter桌面客户端体验:早期版本部署教程

Open Interpreter桌面客户端体验&#xff1a;早期版本部署教程 1. 引言 随着大语言模型&#xff08;LLM&#xff09;在代码生成领域的深入应用&#xff0c;开发者对“自然语言驱动编程”的需求日益增长。然而&#xff0c;大多数AI编程助手依赖云端API&#xff0c;存在数据隐私…

作者头像 李华