上饶市网站建设_网站建设公司_MongoDB_seo优化
2026/1/17 1:39:43 网站建设 项目流程

从图片到JSON:DeepSeek-OCR实现表格精准识别

1. 背景与需求分析

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

然而,通用OCR工具在处理复杂表格时往往存在格式错乱、行列错位、合并单元格识别失败等问题。尤其在中文场景下,字体多样、排版不规范进一步加剧了识别难度。

DeepSeek-OCR-WEBUI 是基于深度学习的大模型OCR解决方案,其核心优势在于:

  • 支持多语言、多字体、复杂背景下的高精度识别
  • 内置图表解析模式(figure),专为表格、公式等结构化内容优化
  • 提供Web UI界面和标准API接口,便于集成
  • 中文识别准确率显著优于主流开源方案

本文将围绕“如何通过 DeepSeek-OCR 实现从图片到 JSON 的端到端表格识别”展开,重点介绍服务部署、接口调用、HTML转JSON解析逻辑及SpringBoot工程化落地实践。

2. DeepSeek-OCR-WEBUI 部署与接口说明

2.1 环境准备与镜像启动

DeepSeek-OCR-WEBUI 基于 Docker 容器化部署,支持单卡GPU运行(如4090D)。部署步骤如下:

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

启动后可通过日志查看服务状态:

docker logs -f deepseek-ocr-webui

服务默认监听http://localhost:8080,提供 Web 操作界面和 RESTful API 接口。

2.2 核心API接口详解

关键接口定义位于/home/qy/DeepSeek-OCR-WebUI/web_service.py文件中的/ocr路径:

@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。该模式会激活模型对表格结构的理解能力,输出标准 HTML<table>格式,保留原始行列关系和合并单元格信息。

若需扩展功能(如添加新参数或修改返回格式),可直接修改web_service.py并重新构建镜像。

3. SpringBoot 应用接入 OCR 服务

3.1 业务场景建模

典型应用场景:零售企业采购入库流程中,采购员拍摄纸质采购单,系统自动识别表格内容,生成结构化数据供人工校验后一键入库。

目标:将一张包含多行商品信息的采购表图片 → 解析为 JSON 数组对象。

输入示例(图片):

期望输出(JSON):

[ { "序号": "1", "条码": "6949123352617", "名称": "飞科PR-5261毛球修剪器", "单位": "个", "订货数量": "0.00", "采购数量": "1.00", "赠送数量": "0.00", "采购单价": "38.5000", "金额小计": "38.5000", "备注": "" }, ... ]

3.2 OcrService 接口设计

定义统一服务接口,解耦具体实现:

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

3.3 服务实现:HTTP调用与HTML解析

1. 发送POST请求至OCR服务

使用RestTemplate构造 multipart/form-data 请求:

@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()); 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); // 发送请求 ResponseEntity<String> response = restTemplate.postForEntity( OCR_SERVICE_URL, requestEntity, String.class); if (response.getStatusCode().is2xxSuccessful()) { String htmlContent = response.getBody(); return parseHtmlTableToJSON(htmlContent); } else { throw new RuntimeException("OCR服务调用失败: " + response.getStatusCode()); } } catch (Exception e) { log.error("表格识别过程中发生异常", e); Map<String, Object> errorResult = new HashMap<>(); errorResult.put("success", false); errorResult.put("message", e.getMessage()); return errorResult; } } }
2. HTML 表格解析为 JSON

利用Jsoup解析 HTML 并转换为 List<Map<String, String>> 结构:

private Map<String, Object> parseHtmlTableToJSON(String html) { Document doc = Jsoup.parse(html); Element table = doc.selectFirst("table"); List<Map<String, String>> result = new ArrayList<>(); if (table == null) { throw new IllegalArgumentException("未检测到有效表格"); } Elements rows = table.select("tr"); if (rows.isEmpty()) return Collections.emptyMap(); // 提取表头 Elements headers = rows.first().select("td, th"); List<String> headerNames = headers.stream() .map(Element::text) .collect(Collectors.toList()); // 遍历数据行 for (int i = 1; i < rows.size(); i++) { Element row = rows.get(i); Elements cells = row.select("td"); Map<String, String> rowData = new LinkedHashMap<>(); for (int j = 0; j < Math.min(cells.size(), headerNames.size()); j++) { String key = headerNames.get(j); String value = cells.get(j).text(); rowData.put(key, value.trim()); } result.add(rowData); } Map<String, Object> resultMap = new HashMap<>(); resultMap.put("success", true); resultMap.put("data", result); resultMap.put("totalRows", result.size()); return resultMap; }

3.4 控制器层暴露REST接口

@RestController @RequestMapping("/api/ocr") @Slf4j public class OcrController { @Autowired private OcrService ocrService; @PostMapping("/process") public Map<String, Object> processFile(@RequestParam("file") MultipartFile file) { Map<String, Object> result = ocrService.recognitionTable(file); log.info("OCR识别结果: {}", result); return result; } }

3.5 单元测试验证功能

@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.assertNotNull(result.get("data")); } }

4. 前后端整合与打包部署

4.1 前端页面集成

项目前端采用 Vue 编写,主要功能包括:

  • 图片上传组件
  • 实时预览区域
  • 识别结果展示表格
  • 导出JSON按钮

编译命令:

npm install npm run build

构建产物dist/目录需复制到 SpringBoot 项目的src/main/resources/static/下,使其可通过 HTTP 访问。

4.2 后端打包配置

使用 Maven 打包 SpringBoot 应用:

<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>

执行打包:

mvn clean package

生成 JAR 文件路径:target/deepseek-web-ui-1.0.0.jar

4.3 Docker 容器化部署

Dockerfile
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"]
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

最终效果:

识别结果展示:


获取更多AI镜像

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

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

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

立即咨询