技术选型与环境准备
本指南将带你从零构建一套基于Web的会计档案管理系统,核心功能包括凭证扫描件上传、OCR文字识别(支持中英文)、档案检索及元数据管理。技术栈选用Python Flask作为后端,Vue 3作为前端,Tesseract OCR作为识别引擎,SQLite作为数据库。这套方案无需购买昂贵的商业软件,所有数据均存储在本地,安全且可控。
一、基础环境安装
首先需要配置Python和Node.js环境。请确保操作系统为Windows 10+或Ubuntu 20.04+。
安装Python 3.9+ :访问Python官网下载安装包,安装时务必勾选"Add Python to PATH"。打开终端输入以下命令验证:
```bash
python --version
pip --version
```
安装Node.js 16+ :访问Node.js官网下载LTS版本并安装。验证命令:
```bash
node -v
npm -v
```
二、安装Tesseract OCR引擎
这是实现会计凭证自动识别的关键组件。
Windows环境 :下载Tesseract-OCR-w64-setup-5.3.0.exe,安装时务必勾选"Additional language data",选择Chinese (Simplified) 和English 语言包。假设安装路径为C:\Program Files\Tesseract-OCR,需将该路径添加到系统环境变量Path中。
Linux环境 :执行以下命令安装引擎及语言包:
```bash
sudo apt-get update
sudo apt-get install tesseract-ocr tesseract-ocr-chi-sim
```
后端服务搭建与OCR核心实现
后端负责文件接收、OCR处理及数据存储。请在本地创建一个名为archive_system的文件夹,并在其中创建backend子文件夹。
一、创建Python虚拟环境与依赖
进入backend目录,执行以下命令隔离项目依赖:
```bash
cd backend
python -m venv venv
Windows激活
venv\Scripts\activate
Linux/Mac激活
source venv/bin/activate
```
创建requirements.txt文件,并填入以下依赖版本,确保兼容性:
```text
Flask==2.3.3
Flask-CORS==4.0.0
Pillow==10.0.1
pytesseract==0.3.10
SQLAlchemy==2.0.21
```
执行安装命令:
```bash
pip install -r requirements.txt
```
二、编写核心应用代码
在backend目录下创建app.py。该文件包含完整的API接口、数据库模型定义及OCR调用逻辑。请直接复制以下完整代码:
```python
import os
import datetime
from flask import Flask, request, jsonify, send_from_directory
from flask_cors import CORS
from flask_sqlalchemy import SQLAlchemy
from PIL import Image
import pytesseract
import uuid
配置部分
app = Flask(__name__)
CORS(app) 允许跨域请求
数据库配置:自动生成db.sqlite3文件
basedir = os.path.abspath(os.path.dirname(__file__))
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.join(basedir, 'db.sqlite3')
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
文件上传配置
UPLOAD_FOLDER = os.path.join(basedir, 'uploads')
if not os.path.exists(UPLOAD_FOLDER):
os.makedirs(UPLOAD_FOLDER)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
Windows系统需手动指定tesseract路径,Linux通常在PATH中可忽略
if os.name == 'nt':
pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe'
db = SQLAlchemy(app)
数据库模型:会计档案表
class Archive(db.Model):
id = db.Column(db.Integer, primary_key=True)
filename = db.Column(db.String(100), nullable=False)
original_name = db.Column(db.String(100), nullable=False)
ocr_text = db.Column(db.Text, nullable=True)
upload_date = db.Column(db.DateTime, default=datetime.datetime.now)
file_type = db.Column(db.String(20)) 例如:凭证、发票、合同
def to_dict(self):
return {
'id': self.id,
'filename': self.filename,
'original_name': self.original_name,
'ocr_text': self.ocr_text,
'upload_date': self.upload_date.strftime('%Y-%m-%d %H:%M:%S'),
'file_type': self.file_type
}
初始化数据库
with app.app_context():
db.create_all()
OCR识别函数
def perform_ocr(image_path):
try:
使用Pillow打开图片,确保格式正确
img = Image.open(image_path)
调用tesseract,指定中英文混合识别
text = pytesseract.image_to_string(img, lang='chi_sim+eng')
return text.strip()
except Exception as e:
print(f"OCR Error: {e}")
return "识别失败"
路由:上传档案
@app.route('/api/upload', methods=['POST'])
def upload_file():
if 'file' not in request.files:
return jsonify({'error': '无文件部分'}), 400
file = request.files['file']
file_type = request.form.get('file_type', '未分类')
if file.filename == '':
return jsonify({'error': '未选择文件'}), 400
生成唯一文件名防止覆盖
ext = file.filename.rsplit('.', 1)[1].lower()
unique_filename = f"{uuid.uuid4().hex}.{ext}"
filepath = os.path.join(app.config['UPLOAD_FOLDER'], unique_filename)
file.save(filepath)
执行OCR识别
ocr_result = perform_ocr(filepath)
存入数据库
new_archive = Archive(
filename=unique_filename,
original_name=file.filename,
ocr_text=ocr_result,
file_type=file_type
)
db.session.add(new_archive)
db.session.commit()
return jsonify({'message': '上传并识别成功', 'data': new_archive.to_dict()}), 201
路由:获取档案列表
@app.route('/api/archives', methods=['GET'])
def get_archives():
keyword = request.args.get('keyword', '')
query = Archive.query
if keyword:
搜索文件名或OCR识别内容
query = query.filter(
db.or_(
Archive.original_name.contains(keyword),
Archive.ocr_text.contains(keyword)
)
)
results = query.order_by(Archive.upload_date.desc()).all()
return jsonify([item.to_dict() for item in results])
路由:下载/预览图片
@app.route('/api/image/
')
def get_image(filename):
return send_from_directory(app.config['UPLOAD_FOLDER'], filename)
if __name__ == '__main__':
app.run(debug=True, port=5000)
```
前端界面开发与交互逻辑
前端使用Vue 3配合Axios进行文件上传和结果展示。在archive_system根目录下创建前端项目。
一、初始化Vue项目
在终端执行以下命令快速构建项目:
```bash
npm create vite@latest frontend -- --template vue
cd frontend
npm install
npm install axios
```
二、编写页面组件
删除src/components下的默认文件,直接修改src/App.vue。以下代码实现了拖拽上传、分类选择、关键词搜索及档案列表展示功能:
```html
会计档案电子化管理中心
档案分类:
记账凭证
原始发票
银行回单
税务申报表
开始上传并OCR识别
检索档案
```
系统启动与功能验证
代码编写完毕后,按照以下步骤启动服务并进行验证。确保终端路径正确。
一、启动后端服务
打开第一个终端窗口,进入backend目录,激活虚拟环境并运行Flask应用:
```bash
cd backend
确保虚拟环境已激活
python app.py
```
终端显示Running on http://127.0.0.1:5000即表示后端启动成功。此时backend目录下会自动生成uploads文件夹(用于存图片)和db.sqlite3数据库文件。
二、启动前端服务
打开第二个终端窗口,进入frontend目录:
```bash
cd frontend
npm run dev
```
终端会显示Local地址,通常是http://localhost:5173。在浏览器中访问该地址。
三、实操测试流程
上传测试 :找一张包含中文和数字的会计凭证截图或扫描件。在网页界面的“档案分类”下拉框选择“记账凭证”,将图片拖入虚线框区域,点击“开始上传并OCR识别”。
识别验证 :观察页面下方列表,图片上传后应立即显示。检查“识别内容摘要”区域,是否准确提取了图片上的金额、日期和摘要文字。如果识别不准确,请检查Tesseract是否安装了中文语言包。
检索测试 :在搜索框输入刚才上传凭证上的某个关键词(例如凭证号或金额),点击“检索档案”。列表应实时过滤,仅显示匹配的档案条目。
数据持久化验证 :关闭后端终端(Ctrl+C)并重新运行python app.py。刷新前端页面,之前上传的数据依然存在,证明SQLite数据库配置正确。
至此,一套具备OCR核心能力的会计档案管理系统已搭建完成。通过扩展app.py中的模型,你可以轻松增加字段如“会计期间”、“凭证号”等,进一步完善管理颗粒度。