2026/4/18 11:28:57
网站建设
项目流程
在公司网站建设会议上的汇报,武威 网站建设,检测网站为什么打不开了,wordpress段落基于DeepSeek-OCR-WEBUI的文档识别实践#xff5c;SpringBoot应用无缝对接
1. 背景与业务场景
在企业级应用中#xff0c;大量纸质单据如采购订单、发票、入库凭证等仍需人工录入系统#xff0c;不仅效率低下#xff0c;还容易出错。随着AI技术的发展#xff0c;光学字符…基于DeepSeek-OCR-WEBUI的文档识别实践SpringBoot应用无缝对接1. 背景与业务场景在企业级应用中大量纸质单据如采购订单、发票、入库凭证等仍需人工录入系统不仅效率低下还容易出错。随着AI技术的发展光学字符识别OCR已成为自动化数据采集的关键手段。DeepSeek-OCR-WEBUI 是基于深度学习的大模型OCR解决方案具备高精度、多语言支持和复杂场景适应能力。其开源特性与Web API设计使其非常适合集成到现有Java后端系统中实现“拍照→识别→结构化输出→人工校验→一键入库”的完整流程。本文将详细介绍如何将DeepSeek-OCR-WEBUI部署为独立服务并通过SpringBoot应用调用其API完成表格图像识别最终实现前端可视化展示与数据结构化转换。2. DeepSeek-OCR-WEBUI 核心功能解析2.1 技术架构概述DeepSeek-OCR-WEBUI 采用 CNN Attention 的混合架构结合文本检测Text Detection与文本识别Text Recognition双阶段模型能够精准定位图像中的文字区域并进行高准确率解码。系统内置后处理模块可自动修复断字、纠正拼写错误、统一标点格式。该服务以 Docker 容器形式提供包含以下核心组件web_service.pyFlask 实现的 RESTful API 接口OCR 模型文件预训练权重支持中文为主、多语言扩展前端 WebUI用于本地测试与调试的图形界面2.2 关键接口说明服务启动后默认监听http://localhost:8080主要接口如下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_typefigure此模式专为图表、公式、表格设计能有效提取table结构的 HTML 输出。3. SpringBoot 后端集成方案3.1 系统架构设计整体架构分为三层前端层Vue 构建的操作页面支持图片上传与结果显示业务层SpringBoot 提供 REST API负责调用 OCR 服务并处理响应AI 层DeepSeek-OCR-WEBUI 容器服务执行实际 OCR 识别任务各层之间通过 HTTP 协议通信松耦合设计便于部署与维护。3.2 环境准备与依赖配置确保已安装JDK 21Maven 3.8Node.js 20用于前端构建Docker Docker ComposeMaven 添加关键依赖dependencies dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency dependency groupIdorg.springframework/groupId artifactIdspring-web/artifactId /dependency dependency groupIdcom.fasterxml.jackson.core/groupId artifactIdjackson-databind/artifactId /dependency dependency groupIdorg.jsoup/groupId artifactIdjsoup/artifactId version1.16.1/version /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-test/artifactId scopetest/scope /dependency /dependencies其中jsoup用于解析 OCR 返回的 HTML 表格内容。4. 核心代码实现4.1 OcrService 接口定义// src/main/java/com/kaifamiao/dswebui/service/OcrService.java public interface OcrService { /** * 识别表格图片并返回结构化数据 * * param file 上传的包含表格的图片文件 * return 包含表格数据的Map对象将以JSON格式返回给前端 */ MapString, Object recognitionTable(MultipartFile file); }4.2 OCR 服务实现类// 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:8080/ocr; private RestTemplate restTemplate; public DeepSeekOcrService() { SimpleClientHttpRequestFactory factory new SimpleClientHttpRequestFactory(); factory.setConnectTimeout(30000); factory.setReadTimeout(60000); this.restTemplate new RestTemplate(factory); } Override public MapString, Object recognitionTable(MultipartFile file) { log.info(开始识别表格图片: {}, file.getOriginalFilename()); try { // 准备文件资源 ByteArrayResource resource new ByteArrayResource(file.getBytes()) { Override public String getFilename() { return file.getOriginalFilename(); } }; // 构建请求参数 MultiValueMapString, Object body new LinkedMultiValueMap(); body.add(file, resource); body.add(prompt_type, figure); // 关键使用 figure 模式识别表格 body.add(grounding, false); // 设置请求头 HttpHeaders headers new HttpHeaders(); headers.setContentType(MediaType.MULTIPART_FORM_DATA); // 创建请求实体 HttpEntityMultiValueMapString, Object requestEntity new HttpEntity(body, headers); // 发送POST请求到OCR服务 ResponseEntityString response restTemplate.postForEntity(OCR_SERVICE_URL, requestEntity, String.class); if (response.getStatusCode().is2xxSuccessful() response.getBody() ! null) { log.info(OCR识别成功返回HTML长度: {}, response.getBody().length()); return parseHtmlTableToJSON(response.getBody()); } else { log.error(OCR服务返回异常状态码: {}, response.getStatusCode()); throw new RuntimeException(OCR识别失败 response.getStatusCode()); } } catch (Exception e) { log.error(调用OCR服务发生异常, e); throw new RuntimeException(OCR识别请求失败: e.getMessage(), e); } } /** * 将HTML表格解析为JSON格式 * * param html 包含表格的HTML字符串 * return 转换后的JSON数据 */ private MapString, Object parseHtmlTableToJSON(String html) { Document doc Jsoup.parse(html); Element table doc.selectFirst(table); if (table null) { throw new IllegalArgumentException(未找到table标签); } ListMapString, String rows new ArrayList(); Elements trList table.select(tr); boolean isFirstRow true; ListString headers new ArrayList(); for (Element tr : trList) { Elements tds tr.select(td); MapString, 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); } else { String key i headers.size() ? headers.get(i) : col_ i; row.put(key, text); } } if (!isFirstRow) { rows.add(row); } isFirstRow false; } MapString, Object result new HashMap(); result.put(success, true); result.put(data, rows); result.put(totalRows, rows.size()); return result; } }代码要点说明使用RestTemplate发起带文件上传的 multipart/form-data 请求prompt_typefigure是识别表格的关键参数利用Jsoup解析返回的 HTMLtable并转换为 JSON 数组表头动态生成col_0,col_1...避免硬编码列名4.3 Controller 层暴露接口// src/main/java/com/kaifamiao/dswebui/controller/OcrController.java RestController RequestMapping(/api/ocr) Slf4j public class OcrController { Autowired private OcrService ocrService; PostMapping(/process) public MapString, Object processFile(RequestParam(file) MultipartFile file) { if (file.isEmpty()) { return Map.of(success, false, message, 文件为空); } try { MapString, Object result ocrService.recognitionTable(file); log.info(OCR识别结果: {}, result); return result; } catch (Exception e) { log.error(处理文件时发生错误, e); return Map.of(success, false, message, 识别失败 e.getMessage()); } } }该接口接收前端上传的图片调用服务层完成识别并返回结构化 JSON 数据。4.4 编写单元测试验证功能// src/test/java/com/kaifamiao/dswebui/service/OcrServiceTest.java SpringBootTest Slf4j public class OcrServiceTest { Autowired private OcrService ocrService; Test void testRecognitionTableSuccess() throws Exception { // 从测试资源目录加载voucher.jpg文件 ClassPathResource resource new ClassPathResource(voucher.jpg); // 创建MultipartFile对象 MockMultipartFile file new MockMultipartFile( file, voucher.jpg, image/jpeg, resource.getInputStream() ); // 调用OCR服务进行识别 MapString, Object result ocrService.recognitionTable(file); log.info(OCR识别结果: {}, JSON.toJSONString(result)); // 断言结果基本结构 Assertions.assertTrue((Boolean) result.get(success)); Assertions.assertNotNull(result.get(data)); Assertions.assertTrue(((List?) result.get(data)).size() 0); } }测试用例确保服务在本地环境下正常运行可在 CI/CD 流程中加入自动化测试环节。5. 前端页面集成与打包5.1 Vue 页面功能说明前端项目位于ui/目录下主要功能包括图片上传组件实时进度提示表格数据渲染错误信息展示页面通过 Axios 调用/api/ocr/process接口接收 JSON 数据并在页面上以表格形式呈现。5.2 构建与集成步骤cd ui npm install npm run build构建完成后dist/目录生成静态资源文件将其复制到 SpringBoot 项目的src/main/resources/static/下cp -r ui/dist/* src/main/resources/static/SpringBoot 默认会托管static目录下的静态资源访问http://localhost:8080即可打开操作界面。6. Docker 容器化部署6.1 后端 Dockerfile# Java运行时阶段 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]6.2 docker-compose.yml 统一编排version: 3.8 services: deepseek-ocr-webui: image: deepseek-ocr-webui:latest container_name: deepseek-ocr-webui ports: - 8080:8080 volumes: - ./logs:/app/logs restart: unless-stopped ocr-app: build: . ports: - 8081:8080 environment: - SERVER_PORT8080 depends_on: - deepseek-ocr-webui volumes: - ./logs:/app/logs注意OCR 服务运行在 8080 端口SpringBoot 应用改为 8081 或其他端口避免冲突。6.3 启动命令docker compose up -d --build服务启动后访问http://localhost:8081查看前端页面SpringBoot 自动调用http://deepseek-ocr-webui:8080/ocr完成识别7. 总结7.1 实践价值总结本文实现了DeepSeek-OCR-WEBUI与SpringBoot的无缝集成完成了从图像输入到结构化数据输出的全流程闭环。该方案具有以下优势高可用性OCR 服务独立部署不影响主业务系统稳定性易扩展性可通过修改prompt_type支持合同、发票、手写体等多种场景低成本接入无需自研OCR模型直接调用成熟AI能力国产化支持DeepSeek 作为国产大模型在中文识别上表现优异7.2 最佳实践建议错误重试机制对网络不稳定场景添加重试逻辑如 Spring Retry异步处理优化对于大图或批量识别建议引入消息队列RabbitMQ/Kafka异步处理缓存策略相同图片可做 MD5 缓存避免重复识别安全控制限制上传文件类型与大小防止恶意攻击日志监控记录识别耗时、成功率等指标便于性能分析获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。