如何高效识别票据表格?用DeepSeek-OCR-WEBUI + SpringBoot轻松搞定

如何高效识别票据表格?用DeepSeek-OCR-WEBUI + SpringBoot轻松搞定

1. 背景与业务场景分析

在企业级应用中,大量纸质单据如采购订单、发票、入库单等仍需录入系统。传统人工录入方式效率低、成本高且易出错。随着AI技术的发展,基于深度学习的OCR(光学字符识别)成为自动化处理结构化文档的关键技术。

尤其在财务、物流、零售等行业,票据表格识别是高频刚需。然而,普通OCR工具对复杂布局、跨行合并单元格、模糊图像或手写体的支持较差,导致准确率不理想。为此,需要一个高精度、可集成、支持结构化输出的解决方案。

DeepSeek-OCR-WEBUI 正是为此类场景设计的开源OCR引擎。它基于先进的大模型架构,在中文文本识别、表格解析方面表现优异,并提供Web API接口,便于与Java后端系统无缝对接。

本文将介绍如何通过 SpringBoot 后端服务调用 DeepSeek-OCR-WEBUI 的图表解析能力,实现票据表格的自动识别与结构化数据提取,最终构建一套完整的“拍照→识别→校验→入库”流程。


2. 技术选型与核心优势

2.1 DeepSeek-OCR-WEBUI 核心能力

DeepSeek-OCR-WEBUI 是基于 DeepSeek 自研OCR大模型封装的可视化Web服务,具备以下关键特性:

  • 多模式识别支持:支持 documentocrfigure 等多种提示类型,其中 figure 模式专为图表和表格优化。
  • 高精度表格解析:能准确识别复杂表格结构,包括表头、行列对齐、跨列/跨行单元格。
  • HTML格式输出:直接返回 <table> 标签包裹的HTML代码,便于前端渲染和结构化解析。
  • 轻量化部署:支持Docker一键部署,适配单卡GPU环境(如4090D),适合私有化部署。
  • 开放API接口:提供标准HTTP接口,方便与其他系统集成。

2.2 为什么选择 SpringBoot 集成?

SpringBoot 作为企业级Java开发主流框架,具有以下优势:

  • 成熟的MVC架构,易于构建RESTful API
  • 强大的生态支持(如RestTemplate、Jackson、Lombok)
  • 易于打包部署为独立JAR或Docker镜像
  • 可结合MyBatis、JPA等持久层框架完成数据落地

因此,采用 SpringBoot作为业务网关,调用DeepSeek-OCR-WEBUI服务进行表格识别,是一种兼顾开发效率与系统稳定性的工程实践方案。


3. 系统架构与工作流程

3.1 整体架构设计

整个系统由三部分组成:

[前端页面] ↓ (上传图片) [SpringBoot 应用] ↓ (HTTP POST 请求) [DeepSeek-OCR-WEBUI OCR服务] ↑ (返回HTML表格) [SpringBoot 解析为JSON] ↓ (返回结构化数据) [前端展示 + 人工校验] 
  • 前端使用Vue构建用户界面,支持图片上传与结果预览
  • SpringBoot 接收文件并转发至OCR服务
  • OCR服务返回HTML格式的表格内容
  • SpringBoot 将HTML解析为JSON数组,供前端消费

3.2 数据流转过程

  1. 用户上传一张包含表格的票据图片(如JPG/PNG)
  2. SpringBoot 接收 MultipartFile 文件对象
  3. 使用 RestTemplate 发起 multipart/form-data 请求到 /ocr 接口
  4. 设置 prompt_type=figure 以启用表格识别模式
  5. 获取响应中的 HTML 表格字符串
  6. 使用 Jsoup 或正则表达式解析 HTML 表格为 List<Map<String, String>>
  7. 返回统一格式的 JSON 结构给前端

4. DeepSeek-OCR-WEBUI 服务部署

4.1 启动 OCR 后端服务

确保已安装 Docker 和 Docker Compose,执行以下命令启动服务:

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

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

docker logs -f deepseek-ocr-webui 

服务默认监听 http://localhost:8081,可通过浏览器访问 WebUI 界面测试功能。

4.2 API 接口说明

OCR服务暴露的核心接口为:

POST /ocr Content-Type: multipart/form-data 
参数名类型必填说明
fileFile图片文件
prompt_typeString识别模式,表格识别使用 figure
find_termString查找关键词
custom_promptString自定义提示词
groundingBoolean是否开启分组
注意:要识别表格,请务必设置 prompt_type=figure,否则无法获得结构化表格输出。

5. SpringBoot 集成实现

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

5.2 实现 DeepSeekOcrService

// 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:8081/ocr"; @Override public Map<String, Object> recognitionTable(MultipartFile file) { log.info("开始识别表格,文件名: {}", file.getOriginalFilename()); try { RestTemplate restTemplate = new RestTemplate(); // 准备文件资源 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(); log.info("OCR返回HTML长度: {}", htmlContent.length()); 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); Elements tables = doc.select("table"); if (tables.isEmpty()) { throw new IllegalArgumentException("未检测到表格内容"); } Element table = tables.first(); Elements rows = table.select("tr"); List<Map<String, String>> dataList = new ArrayList<>(); List<String> headers = new ArrayList<>(); for (int i = 0; i < rows.size(); i++) { Element row = rows.get(i); Elements cells = row.select("td,th"); if (i == 0) { // 第一行为表头 for (Element cell : cells) { headers.add(cell.text().trim()); } } else { // 数据行 Map<String, String> dataRow = new HashMap<>(); for (int j = 0; j < Math.min(cells.size(), headers.size()); j++) { String key = headers.get(j); String value = cells.get(j).text().trim(); dataRow.put(key, value); } dataList.add(dataRow); } } Map<String, Object> result = new HashMap<>(); result.put("success", true); result.put("data", dataList); result.put("totalRows", dataList.size()); return result; } } 
依赖库说明:需引入 jsoup 用于HTML解析,在 pom.xml 中添加:

5.3 编写 Controller 提供 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) { if (file.isEmpty()) { return Map.of("success", false, "message", "文件为空"); } try { Map<String, Object> result = ocrService.recognitionTable(file); return result; } catch (Exception e) { log.error("处理文件时出错", e); return Map.of("success", false, "message", "识别失败:" + e.getMessage()); } } } 

6. 测试验证与结果分析

6.1 编写单元测试

// src/test/java/com/kaifamiao/dswebui/service/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); } } 

6.2 实际识别效果示例

输入原始图片(采购单):

OCR返回HTML片段:

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

解析后JSON输出:

{ "success": true, "totalRows": 4, "data": [ { "序号": "1", "条码": "6949123352617", "名称": "飞科PR-5261毛球修剪器", "单位": "个", "订货数量": "0.00", "采购数量": "1.00" }, ... ] } 

前端可直接渲染为表格供用户校验,确认无误后一键入库数据库。


7. 前后端整合与部署

7.1 前端Vue页面集成

项目包含一个基于Vue的前端界面,主要功能包括:

  • 图片上传组件
  • 实时进度提示
  • 表格预览区域
  • 校验与提交按钮

编译打包命令:

npm install npm run build 

生成的 dist/ 目录需复制到SpringBoot项目的 src/main/resources/static/ 下,使静态资源可被访问。

7.2 Docker 打包与运行

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"] 
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 即可使用完整系统。


8. 总结

本文详细介绍了如何利用 DeepSeek-OCR-WEBUI + SpringBoot 实现票据表格的高效识别与结构化提取,涵盖从环境部署、接口调用、HTML解析到前后端整合的全流程。

核心要点回顾:

  1. 精准识别模式选择:使用 prompt_type=figure 激活表格解析能力,是成功的关键。
  2. 结构化数据转换:通过 Jsoup 解析 HTML 表格为 JSON,便于前端消费。
  3. 松耦合架构设计:OCR服务独立部署,SpringBoot仅作代理与后处理,提升系统可维护性。
  4. 可扩展性强:后续可增加字段映射、规则校验、自动入库等功能。

该方案已在实际项目中验证,平均识别准确率达95%以上,显著降低人工录入成本,适用于各类需要处理结构化票据的业务场景。


获取更多AI镜像

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

Read more

2026 AI大模型实战:零基础玩转当下最火的AIGC

哈喽宝子们,2026年的AI大模型赛道简直卷出了新高度,中关村论坛上昆仑万维发布的Matrix-Game 3.0、SkyReels V4、Mureka V9三大世界级模型直接把全模态AIGC推上了新风口,而且昆仑天工旗下的SkyText、SkyCode等多款模型还开放了开源API,普通人也能轻松玩转AI大模型开发了。 一、当下 AI 大模型核心热点:人人都能做 AI 开发 1.全模态成主流:昆仑万维的 SkyReels V4 视频大模型实现音画一体生成、Mureka V9 音乐大模型支持创作意图精准落地,AI 从单一文本生成进入文本 / 图像 / 音频 / 视频全模态创作时代; 2.开源 API 全面开放:昆仑天工的 SkyText(文本生成)、SkyCode(代码生成)等模型开源,无需自建大模型,通过简单 API 就能实现商用级 AI 功能; 3.

Cogito-v1-preview-llama-3B代码实例:Python调用API实现自动代码补全

Cogito-v1-preview-llama-3B代码实例:Python调用API实现自动代码补全 1. 引言:当代码补全遇见混合推理模型 你有没有过这样的经历?深夜赶项目,面对一个复杂的函数逻辑,大脑一片空白,手指在键盘上悬停半天,就是敲不出下一行代码。或者,在调试一个棘手的bug时,明明感觉解决方案就在嘴边,却怎么也组织不成有效的代码。 传统的代码补全工具,比如IDE自带的智能提示,大多基于静态分析或简单的模式匹配。它们能帮你补全变量名、函数名,但在需要理解上下文、进行逻辑推理的复杂场景下,往往就力不从心了。 今天,我要介绍一个能真正“理解”你在写什么的代码助手——Cogito-v1-preview-llama-3B。这不是一个普通的语言模型,而是一个经过特殊训练的混合推理模型。简单来说,它不仅能像普通模型一样直接给出答案,还能在回答前“思考”一下,就像我们人类解决问题时会先在脑子里过一遍逻辑一样。 这篇文章,我将带你从零开始,用Python调用Cogito模型的API,搭建一个属于你自己的智能代码补全工具。整个过程非常简单,即使你之前没接触过API调用,也能轻松跟上

小白也能用的AI绘画神器:Z-Image i2L快速入门指南

小白也能用的AI绘画神器:Z-Image i2L快速入门指南 你是不是也试过很多AI绘画工具,结果不是要注册账号、等排队,就是生成一张图要花好几分钟,还担心图片被传到服务器上?今天要介绍的这个工具,不用联网、不传数据、不卡显存,打开就能画——而且操作简单到连手机都能点着玩。 它就是⚡ Z-Image i2L(DiffSynth Version),一个真正为普通人设计的本地文生图工具。没有复杂命令,没有报错黑屏,更不需要懂“LoRA”“ControlNet”这些词。只要你能打字,就能生成属于自己的高清图像。 这篇文章不讲原理、不堆参数,只说三件事: 它到底有多简单? 你第一次点开界面该做什么? 怎么调几个关键设置,让生成效果从“还行”变成“哇!” 全程零门槛,10分钟上手,现在就开始。 1. 为什么说它是“小白友好型”AI绘画工具? 很多人一听到“本地部署”“Diffusers框架”“BF16精度”,下意识就觉得:

AIGC实战测评:蓝耘元生代通义万相2.1图生视频的完美部署~

AIGC实战测评:蓝耘元生代通义万相2.1图生视频的完美部署~

文章目录 * 👏什么是图生视频? * 👏通义万相2.1图生视频 * 👏开源仓库代码 * 👏蓝耘元生代部署通义万相2.1图生视频 * 👏平台注册 * 👏部署通义万相2.1图生视频 * 👏使用通义万相2.1图生视频 * 👏总结 👏什么是图生视频? 图生视频是一种通过图像生成技术,结合文本信息生成视频的创新方式。通过输入一张图像和相关的描述文本,系统能够根据这些输入生成一个符合描述的视频。该技术利用深度学习和计算机视觉技术,将静态图像转化为动态视频,实现视觉内容的快速生成。这种技术的应用广泛,涵盖了内容创作、影视制作、广告生成等多个领域。 👏通义万相2.1图生视频 阿里巴巴旗下“通义”品牌宣布,其AI视频生成模型“通义万相Wan”正式推出独立网站,标志着其生成式AI技术的重大进展。新网站现已开放(网址:wan.video),用户可直接登录体验“文本生成视频”和“图像生成视频”功能,无需本地部署,极大降低了使用门槛。此外,每天登录网站还可获赠积分,激励用户持续探索。 文章链接:https: