news 2026/2/19 16:00:21

DeepSeek-OCR-WEBUI核心功能解析|附SpringBoot接入实战案例

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
DeepSeek-OCR-WEBUI核心功能解析|附SpringBoot接入实战案例

DeepSeek-OCR-WEBUI核心功能解析|附SpringBoot接入实战案例

1. DeepSeek-OCR-WEBUI是什么?为什么值得关注?

你有没有遇到过这样的场景:一堆纸质单据、发票、合同需要录入系统,手动一条条敲键盘不仅费时,还容易出错。这时候,如果有一款工具能“看懂”图片里的文字,甚至还能识别表格结构,直接把内容转成结构化数据,那该多好?

DeepSeek-OCR-WEBUI 正是为此而生。它是基于国产自研大模型的高性能OCR系统,不仅能识别中文文本,还能理解复杂版式、表格、公式,甚至支持语义级提示词控制识别行为。更关键的是——它开源、可本地部署、支持API调用,非常适合集成到企业内部系统中。

本文将带你深入解析它的核心功能机制,并手把手实现一个SpringBoot应用接入实战案例,最终完成从“拍照→上传→识别表格→结构化输出”的完整流程。


2. 核心功能深度解析

2.1 多模式识别:不只是“识字”,更是“理解内容”

传统OCR只能提取图像中的字符,但 DeepSeek-OCR-WEBUI 提供了多种prompt_type模式,让识别过程变得更智能、更有目的性。

模式功能说明典型应用场景
document转换为 Markdown 格式,保留标题、段落、列表等结构合同扫描件数字化、论文归档
ocr提取所有可见文字,不做格式处理快速获取图片中的全部文本
free纯文本提取,去格式化简单信息抽取,如验证码识别
figure重点!解析图表、表格、数学公式单据识别、报表分析、教学资料处理
describe生成图像描述,类似图文对话图片语义理解、无障碍辅助
find查找特定关键词并标注位置发票字段定位(如“金额”、“税号”)
freeform自定义提示词,灵活控制识别逻辑定制化业务需求

划重点:我们要识别采购单上的表格数据,所以必须使用figure模式。这是实现结构化输出的关键!

2.2 基于提示词的精准控制(Prompt-Based OCR)

这可能是 DeepSeek-OCR 最惊艳的设计之一——你可以像和AI聊天一样告诉它:“我要识别这张图里的表格”。

比如:

{ "prompt_type": "figure", "custom_prompt": "请提取这张采购单中的商品明细表,包含序号、条码、名称、数量、单价、金额" }

通过custom_prompt,你可以引导模型关注特定区域或字段,极大提升复杂文档的识别准确率。这种“语义驱动”的方式,远超传统规则匹配。

2.3 输出结构化HTML,便于二次解析

与大多数返回纯文本或JSON的OCR不同,DeepSeek-OCR 在figure模式下会返回标准的 HTML<table>结构:

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

这个设计非常聪明:

  • 对前端友好:可以直接渲染展示
  • 对后端友好:可用成熟库(如 Jsoup)轻松解析为 JSON
  • 保留原始布局:避免因空格、换行导致的数据错位

3. SpringBoot 接入全流程实战

现在我们进入实战环节。目标很明确:构建一个 Web 应用,用户上传一张含表格的单据图片,后端调用 DeepSeek-OCR 服务,返回结构化 JSON 数据。

整体架构如下:

前端 (Vue) → SpringBoot 后端 → DeepSeek-OCR-WebUI API → 返回HTML → 解析为JSON → 返回给前端

3.1 准备工作:启动OCR服务

确保你已经成功部署了 DeepSeek-OCR-WebUI 镜像(建议使用 Docker Compose 方式):

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

查看日志确认服务已启动:

docker logs -f deepseek-ocr-webui

默认情况下,OCR 服务运行在http://localhost:8080,提供/ocr接口。


3.2 定义服务接口

我们先定义一个通用的 OCR 服务接口:

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

3.3 实现OCR调用逻辑

创建具体实现类,使用RestTemplate调用远程OCR接口:

// src/main/java/com/example/ocr/service/impl/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 { // 构建 multipart 请求体 LinkedMultiValueMap<String, Object> requestBody = new LinkedMultiValueMap<>(); requestBody.add("file", new ByteArrayResource(file.getBytes()) { @Override public String getFilename() { return file.getOriginalFilename(); } }); requestBody.add("prompt_type", "figure"); // 关键:使用 figure 模式识别表格 requestBody.add("grounding", false); // 设置请求头 HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.MULTIPART_FORM_DATA); // 发送请求 HttpEntity<LinkedMultiValueMap<String, Object>> requestEntity = new HttpEntity<>(requestBody, headers); 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 (IOException e) { log.error("文件读取异常", e); throw new RuntimeException("文件处理失败", e); } } /** * 将HTML表格解析为JSON格式 */ private Map<String, Object> parseHtmlTableToJSON(String html) { Document doc = Jsoup.parse(html); Elements tables = doc.select("table"); if (tables.isEmpty()) { return Collections.singletonMap("data", Collections.emptyList()); } Element table = tables.first(); Elements rows = table.select("tr"); List<Map<String, String>> result = new ArrayList<>(); List<String> headers = null; for (int i = 0; i < rows.size(); i++) { Element row = rows.get(i); Elements cells = row.select("td,th"); List<String> cellValues = cells.stream() .map(Element::text) .map(String::trim) .collect(Collectors.toList()); if (i == 0) { // 第一行作为表头 headers = cellValues; } else { // 其余行为数据行 Map<String, String> rowData = new HashMap<>(); for (int j = 0; j < headers.size() && j < cellValues.size(); j++) { String key = headers.get(j); String value = cellValues.get(j); rowData.put(key, value); } result.add(rowData); } } Map<String, Object> resultMap = new HashMap<>(); resultMap.put("headers", headers); resultMap.put("data", result); return resultMap; } }

注意事项:

  • 添加依赖:spring-web,jsoup
  • 使用ByteArrayResource包装文件流
  • prompt_type=figure是识别表格的核心参数

3.4 编写测试用例验证功能

src/test/resources/下放一张测试图片voucher.jpg,编写单元测试:

// src/test/java/com/example/ocr/service/OcrServiceTest.java @SpringBootTest @Slf4j 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识别结果: \n{}", JSON.toJSONString(result, true)); Assertions.assertNotNull(result.get("data")); Assertions.assertTrue(((List<?>) result.get("data")).size() > 0); } }

运行测试,你会看到类似以下输出:

{ "headers": ["序号","条码","名称","单位","订货数量","采购数量","赠送数量","采购单价","金额小计","备注"], "data": [ {"序号":"1","条码":"6949123352617","名称":"飞科PR-5261毛球修剪器",...}, {"序号":"2","条码":"6944296500049","名称":"天香炸酱面180g*50",...} ] }

成功!表格已被正确解析为结构化 JSON。


3.5 暴露HTTP接口供前端调用

最后,添加 Controller 层接口:

// src/main/java/com/example/ocr/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) { return ocrService.recognitionTable(file); } }

启动 SpringBoot 项目,默认监听8080端口(注意与OCR服务区分端口,可通过server.port=9090修改)。


4. 前后端联调与打包部署

4.1 前端页面集成(Vue)

项目自带ui目录,使用 Vue 实现上传界面:

<template> <div> <input type="file" @change="handleFileUpload" accept="image/*" /> <button @click="submit">识别表格</button> <table v-if="tableData.length"> <thead> <tr><th v-for="h in headers">{{ h }}</th></tr> </thead> <tbody> <tr v-for="row in tableData"><td v-for="cell in Object.values(row)">{{ cell }}</td></tr> </tbody> </table> </div> </template> <script> export default { data() { return { file: null, headers: [], tableData: [] }; }, methods: { handleFileUpload(e) { this.file = e.target.files[0]; }, async submit() { const formData = new FormData(); formData.append('file', this.file); const res = await fetch('http://localhost:9090/api/ocr/process', { method: 'POST', body: formData }); const result = await res.json(); this.headers = result.headers; this.tableData = result.data; } } } </script>

构建前端资源:

npm install npm run build

dist目录下的静态文件复制到 SpringBoot 的src/main/resources/static下即可访问。


4.2 打包为Docker镜像统一部署

根目录创建Dockerfile

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

配套docker-compose.yml

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

一键启动:

docker compose up -d --build

访问http://localhost:9090即可使用完整应用。


5. 总结

通过本文,我们完成了对DeepSeek-OCR-WEBUI的一次深度实践:

  • 理解了其核心能力:多模式识别、提示词驱动、结构化输出
  • 掌握了接入方法:SpringBoot + RestTemplate 调用 API
  • 实现了表格识别闭环:图片上传 → OCR识别 → HTML解析 → JSON输出
  • 完成了工程化落地:前后端分离、Docker容器化部署

这套方案特别适合用于:

  • 企业报销单自动化处理
  • 物流运单信息提取
  • 教育领域试卷/作业数字化
  • 档案馆老旧文档电子化

更重要的是,整个技术栈完全自主可控,无需依赖第三方云服务,保障数据安全。


获取更多AI镜像

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

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

智能家居设备控制中枢搭建指南

智能家居设备控制中枢搭建指南 【免费下载链接】stock stock&#xff0c;股票系统。使用python进行开发。 项目地址: https://gitcode.com/gh_mirrors/st/stock 一、智能家居多设备协同的核心痛点分析 如何让不同品牌的智能设备协同工作&#xff1f;在智能家居普及过程…

作者头像 李华
网站建设 2026/2/17 17:44:05

如何用AI翻译工具突破语言壁垒?Sakura启动器图形化界面实战指南

如何用AI翻译工具突破语言壁垒&#xff1f;Sakura启动器图形化界面实战指南 【免费下载链接】Sakura_Launcher_GUI Sakura模型启动器 项目地址: https://gitcode.com/gh_mirrors/sa/Sakura_Launcher_GUI 在全球化协作日益频繁的今天&#xff0c;语言障碍仍然是制约效率的…

作者头像 李华
网站建设 2026/2/15 14:59:28

如何用Prompt做图像分割?SAM3镜像让万物分割更智能

如何用Prompt做图像分割&#xff1f;SAM3镜像让万物分割更智能 你有没有试过—— 一张杂乱的街景图里&#xff0c;只想单独抠出那辆红色自行车&#xff1b; 一张家庭合影中&#xff0c;快速圈出所有穿蓝色衣服的人&#xff1b; 一张产品图里&#xff0c;不点不画、不调参数&am…

作者头像 李华
网站建设 2026/2/5 17:21:52

3步打造你的数字时光机:永久保存社交记忆的全攻略

#3步打造你的数字时光机&#xff1a;永久保存社交记忆的全攻略 【免费下载链接】GetQzonehistory 获取QQ空间发布的历史说说 项目地址: https://gitcode.com/GitHub_Trending/ge/GetQzonehistory 你是否曾在深夜翻阅QQ空间&#xff0c;突然意识到那些承载着青春记忆的说…

作者头像 李华