环境准备与依赖安装
在开始构建档案数字化协作服务之前,必须先配置好运行环境。本系统基于 Python 开发,利用 FastAPI 提供高性能接口,结合 Tesseract OCR 进行图像文字识别,使用 SQLite 作为轻量级协作数据库。请严格按照以下步骤操作,确保环境无遗漏。
1. 安装 Python 环境
确保系统已安装 Python 3.8 或更高版本。在终端输入以下命令检查版本:
```bash
python --version
```
2. 安装 Tesseract OCR 引擎
这是实现档案数字化的核心组件,负责将图片转换为可检索文本。
- Windows 用户: 访问 https://github.com/UB-Mannheim/tesseract/wiki 下载最新的 Windows 安装包(推荐 tesseract-ocr-w64-setup-5.x.x.exe)。安装时务必勾选 "Additional language data" 并下载中文简体语言包,否则无法识别中文。安装路径建议保持默认:
C:\Program Files\Tesseract-OCR。
- Linux 用户: 执行以下命令安装引擎及中文包:
```bash
sudo apt update
sudo apt install tesseract-ocr tesseract-ocr-chi-sim
```
3. 创建项目目录与虚拟环境
在命令行执行以下指令,创建项目文件夹并激活虚拟环境,隔离依赖冲突:
```bash
mkdir archive_system
cd archive_system
python -m venv venv
Windows 激活
venv\Scripts\activate
Linux/Mac 激活
source venv/bin/activate
```
4. 安装 Python 依赖库
创建 requirements.txt 文件,并填入以下核心依赖。这些库分别负责 Web 框架、图像处理、OCR 调用及跨域支持:
```text
fastapi==0.104.1
uvicorn==0.24.0
python-multipart==0.0.6
Pillow==10.1.0
pytesseract==0.3.10
```
保存文件后,执行安装命令:
```bash
pip install -r requirements.txt
```
后端核心服务开发
后端服务负责接收前端上传的档案图片,调用 OCR 引擎提取文字,并将结果存储在数据库中供多端协作查询。我们将使用原生 SQLite,无需额外安装数据库服务。
1. 创建主程序文件
在项目根目录下创建 main.py。该文件包含完整的数据库初始化、OCR 逻辑及 API 接口定义。请直接复制以下完整代码,注意修改 Windows 下的 Tesseract 路径。
```python
import shutil
import sqlite3
import uuid
from typing import List
from pathlib import Path
from fastapi import FastAPI, UploadFile, File, Form, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
from PIL import Image
import pytesseract
配置区域
如果是 Windows 系统,请取消下面这行的注释,并修改为你的实际安装路径
pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe'
UPLOAD_DIR = Path("uploads")
UPLOAD_DIR.mkdir(exist_ok=True)
DB_FILE = "archive.db"
app = FastAPI(title="Archive Digitization Service")
允许跨域,方便前端调试
app.add_middleware(
CORSMiddleware,
allow_origins=[""],
allow_credentials=True,
allow_methods=[""],
allow_headers=[""],
)
数据库初始化
def init_db():
conn = sqlite3.connect(DB_FILE)
cursor = conn.cursor()
cursor.execute('''
CREATE TABLE IF NOT EXISTS documents (
id TEXT PRIMARY KEY,
filename TEXT NOT NULL,
file_path TEXT NOT NULL,
ocr_text TEXT,
status TEXT DEFAULT 'pending',
notes TEXT DEFAULT ''
)
''')
conn.commit()
conn.close()
init_db()
核心业务逻辑
@app.post("/upload")
async def upload_document(file: UploadFile = File(...)):
"""上传档案图片并执行 OCR 识别"""
生成唯一文件名
file_id = str(uuid.uuid4())
file_ext = file.filename.split(".")[-1]
save_filename = f"{file_id}.{file_ext}"
file_path = UPLOAD_DIR / save_filename
保存文件到本地
try:
with file_path.open("wb") as buffer:
shutil.copyfileobj(file.file, buffer)
except Exception as e:
raise HTTPException(status_code=500, detail=f"文件保存失败: {str(e)}")
执行 OCR 识别
try:
打开图片进行预处理(可选:转灰度提高识别率)
image = Image.open(file_path)
使用 lang='chi_sim+eng' 同时识别中英文
text = pytesseract.image_to_string(image, lang='chi_sim+eng')
except Exception as e:
raise HTTPException(status_code=500, detail=f"OCR 识别失败: {str(e)}")
存入数据库
conn = sqlite3.connect(DB_FILE)
cursor = conn.cursor()
cursor.execute(
"INSERT INTO documents (id, filename, file_path, ocr_text, status) VALUES (?, ?, ?, ?, ?)",
(file_id, file.filename, str(file_path), text, "processed")
)
conn.commit()
conn.close()
return {"id": file_id, "filename": file.filename, "status": "processed", "text": text}
@app.get("/documents")
async def list_documents():
"""获取所有档案列表,用于协作展示"""
conn = sqlite3.connect(DB_FILE)
cursor = conn.cursor()
cursor.execute("SELECT id, filename, ocr_text, status, notes FROM documents ORDER BY rowid DESC")
rows = cursor.fetchall()
conn.close()
data = []
for row in rows:
data.append({
"id": row[0],
"filename": row[1],
"text": row[2],
"status": row[3],
"notes": row[4]
})
return data
@app.post("/documents/{doc_id}/collaborate")
async def update_collaboration(doc_id: str, status: str = Form(...), notes: str = Form(...)):
"""更新档案状态和备注,实现多人协作标记"""
conn = sqlite3.connect(DB_FILE)
cursor = conn.cursor()
cursor.execute(
"UPDATE documents SET status=?, notes=? WHERE id=?",
(status, notes, doc_id)
)
if cursor.rowcount == 0:
conn.close()
raise HTTPException(status_code=404, detail="文档未找到")
conn.commit()
conn.close()
return {"message": "更新成功"}
```

2. 代码关键点解析
- OCR 配置: 代码中
pytesseract.image_to_string(image, lang='chi_sim+eng') 非常关键,指定了中英文混合识别模式。如果未下载中文语言包,此处会报错。
- 数据存储: 使用了
sqlite3 原生库,表结构包含 status(状态)和 notes(备注)字段,专门用于协作场景,例如标记“已审核”或添加“归档意见”。
- 文件处理: 使用
uuid 生成唯一 ID 防止文件名冲突,并存储在 uploads 目录下。
前端交互页面实现
为了方便操作,我们构建一个单页 HTML 前端。该页面包含文件上传区域、识别结果展示列表以及协作编辑功能。无需 Vue 或 React,直接使用原生 JavaScript 调用后端接口。
在项目根目录下创建 static 文件夹,并在其中创建 index.html:
```html
档案数字化协作平台
```
3. 配置静态文件服务
为了让 FastAPI 能够展示上述 HTML 页面,需要修改 main.py 底部,添加静态文件挂载代码。请在 main.py 的最后一行添加:
```python
from fastapi.staticfiles import StaticFiles
挂载 static 目录,访问路径为 /static
app.mount("/static", StaticFiles(directory="static"), name="static")
```
系统启动与功能验证
所有代码已就绪,现在启动服务并进行全流程测试。
1. 启动后端服务
在项目根目录下,确保虚拟环境已激活,执行以下命令启动服务器:
```bash
uvicorn main:app --reload --host 0.0.0.0 --port 8000
```
2. 访问前端页面
打开浏览器,直接访问以下地址:
```text
http://127.0.0.1:8000/static/index.html
```
3. 实操验证步骤
- 上传测试: 准备一张包含文字的中文图片或 PDF 截图。点击页面中间的虚线框区域,选择文件上传。
- OCR 验证: 观察页面反馈,上传成功后会自动刷新,你应该能看到图片下方的灰色文本框中显示出了识别出的文字内容。如果显示乱码或空白,请检查 Tesseract 是否安装了中文语言包。
- 协作测试: 在该文档卡片下方,找到“协作更新”区域。将状态修改为“已审核”,在备注框中输入“内容无误,同意归档”。
- 数据一致性检查: 点击“提交更新”按钮。刷新浏览器页面,检查刚才修改的状态和备注是否已保存,确保多人协作场景下数据状态能够正确回显。