如何在Spring MVC Web应用中集成文档扫描器?求免费可行方案
免费Web文档扫描方案适配Spring MVC
我完全懂你的困扰——传统的TWAIN Applet早就不符合现代Web标准了,不仅HTML5弃用了它,64位系统还不支持,付费方案又超出预算。下面给你几个实用的免费方案,完美适配你的Spring MVC项目:
1. 用开源社区版Web TWAIN SDK
Dynamic Web TWAIN有个免费社区版,足够满足基础扫描需求,不需要Applet,直接用JS就能调用本地扫描设备,而且兼容64位系统和主流浏览器(Chrome、Firefox、Edge这些都支持)。
前端集成示例
先引入SDK的JS文件,然后写扫描逻辑:
// 初始化扫描对象 Dynamsoft.DWT.CreateDWTObjectEx({ "WebTwainId": "scanner" }, function(obj) { // 选择扫描设备 obj.SelectSource(function() { obj.OpenSource(); // 开始扫描,扫描后自动上传到后端 obj.AcquireImage({ OnPostTransfer: function() { // 把扫描图转成Blob obj.ConvertToBlob(Dynamsoft.DWT.EnumDWT_ImageType.IT_PNG, function(blob) { let formData = new FormData(); formData.append("scanFile", blob, "scanned-document.png"); // 调用Spring MVC上传接口 fetch("/api/upload-scanned-file", { method: "POST", body: formData }).then(res => res.text()).then(msg => { console.log(msg); }); }); } }); }); });
Spring MVC后端接口
写个接收文件的接口,处理上传后的存储或业务逻辑:
import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.multipart.MultipartFile; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; @RestController public class ScanUploadController { @PostMapping("/api/upload-scanned-file") public ResponseEntity<String> uploadScannedFile(@RequestParam("scanFile") MultipartFile file) { if (file.isEmpty()) { return ResponseEntity.badRequest().body("上传文件不能为空"); } try { // 存储到服务器指定目录 Files.write(Paths.get("scanned-documents/" + file.getOriginalFilename()), file.getBytes()); return ResponseEntity.ok("文件上传成功,已保存至服务器"); } catch (IOException e) { e.printStackTrace(); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("文件上传失败"); } } }
2. 纯HTML5原生方案(依赖现代设备)
现在不少新款扫描仪支持被浏览器的MediaDevices API识别为图像捕获设备,你可以直接用原生JS调用设备流,捕获帧作为扫描文件,完全不需要第三方库,免费又轻量。
前端核心代码
async function initScanner() { try { // 获取所有媒体设备,筛选出扫描仪 const devices = await navigator.mediaDevices.enumerateDevices(); const scannerDevice = devices.find(device => device.kind === 'videoinput' && device.label.includes('Scanner')); if (!scannerDevice) { alert("未检测到兼容的扫描设备"); return; } // 请求设备流 const stream = await navigator.mediaDevices.getUserMedia({ video: { deviceId: { exact: scannerDevice.deviceId }, width: { ideal: 2000 }, // 按需设置分辨率 height: { ideal: 1600 } } }); const videoElement = document.getElementById('scanner-preview'); videoElement.srcObject = stream; // 捕获按钮点击事件 document.getElementById('capture-btn').addEventListener('click', () => { const canvas = document.createElement('canvas'); canvas.width = videoElement.videoWidth; canvas.height = videoElement.videoHeight; // 绘制视频帧到画布 canvas.getContext('2d').drawImage(videoElement, 0, 0); // 转成Blob上传 canvas.toBlob(blob => { let formData = new FormData(); formData.append("scanFile", blob, "scanned-image.jpg"); fetch("/api/upload-scanned-file", { method: "POST", body: formData }); }, 'image/jpeg', 0.9); }); } catch (err) { console.error("扫描初始化失败:", err); alert("请确保已授权浏览器访问设备,且扫描仪驱动正常"); } }
⚠️ 注意:这个方案只支持支持WebRTC的扫描仪,老设备可能不兼容,但胜在零依赖,完全免费。
3. 本地辅助程序+Spring MVC接口(兼容老设备)
如果你的用户用的是老款扫描仪,上面的Web方案都不兼容,可以写个轻量的本地桌面程序,通过HTTP接口和前端、Spring MVC后端交互。
比如用Python的PyTWAIN库写个本地扫描服务:
from twain import SourceManager from flask import Flask, send_file import os app = Flask(__name__) SCAN_DIR = './scanned_files' os.makedirs(SCAN_DIR, exist_ok=True) @app.route('/trigger-scan') def trigger_scan(): try: sm = SourceManager(0) source = sm.OpenSource() source.RequestAcquire(0, 1) # 触发扫描 image = source.GetImage() file_path = os.path.join(SCAN_DIR, 'scanned_doc.png') image.Save(file_path) # 返回扫描文件,前端可以拿到后上传到Spring MVC return send_file(file_path, mimetype='image/png') except Exception as e: return str(e), 500 if __name__ == '__main__': app.run(port=8081, debug=True)
前端可以通过fetch('http://localhost:8081/trigger-scan')获取扫描文件,再上传到你的Spring MVC后端接口。
最后要提醒的是:所有方案都需要用户本地安装好扫描仪的官方驱动,Web方案还需要用户在浏览器中授权访问设备的权限。
内容的提问来源于stack exchange,提问作者new coder
相关产品推荐
相关产品推荐

