小更新,但是是比较完善的版本,加油
This commit is contained in:
parent
4a8169ff63
commit
9b2007a995
344
README.md
344
README.md
@ -1,298 +1,80 @@
|
||||
# OCR订单处理系统 v1.0
|
||||
# 益选-OCR订单处理系统
|
||||
|
||||
基于百度OCR API的订单处理系统,用于识别采购订单图片并生成Excel采购单。
|
||||
## 项目简介
|
||||
益选-OCR订单处理系统是一款基于Python的图形化本地订单自动化处理工具,支持采购单图片OCR识别、Excel数据处理、采购单合并、烟草订单专用处理等功能,适用于中小型企业、商超、烟草公司等场景。
|
||||
|
||||
## 版本信息
|
||||
## 主要功能
|
||||
- 图片采购单OCR识别,自动生成标准Excel采购单
|
||||
- Excel采购单智能处理与格式转换
|
||||
- 多采购单合并为总单,支持批量处理
|
||||
- 烟草公司订单明细专用处理与格式转换
|
||||
- 条码映射与单位转换规则自定义
|
||||
- 图形化界面,支持批量、单文件、完整流程一键处理
|
||||
- 系统设置界面,支持API、路径、性能等参数自定义
|
||||
- 日志管理与处理结果预览
|
||||
- 键盘快捷键支持
|
||||
|
||||
- **当前版本**: v1.5
|
||||
- **发布日期**: 2025-05-09
|
||||
- **作者**: OCR订单处理团队
|
||||
|
||||
## 功能特点
|
||||
|
||||
- **图像OCR识别**:支持对采购单图片进行OCR识别并生成Excel文件
|
||||
- **Excel数据处理**:读取OCR识别的Excel文件并提取商品信息
|
||||
- **采购单生成**:按照模板格式生成标准采购单Excel文件
|
||||
- **采购单合并**:支持多个采购单合并为一个总单
|
||||
- **批量处理**:支持批量处理多张图片
|
||||
- **图形界面**:提供简洁直观的图形界面,方便操作
|
||||
- **命令行支持**:支持命令行方式调用,便于自动化处理
|
||||
- **OCR识别**: 支持图片中表格的自动识别和提取
|
||||
- **Excel处理**: 将OCR识别结果处理为规范的Excel表格
|
||||
- **订单合并**: 将多个采购单自动合并为一个总表
|
||||
- **完整流程**: 一键执行从OCR识别到订单合并的完整处理流程
|
||||
- **烟草订单处理**: 专门处理烟草公司特定格式的订单明细文件,生成银豹采购单
|
||||
|
||||
## 系统架构
|
||||
|
||||
### 目录结构
|
||||
|
||||
```
|
||||
orc-order-v2/
|
||||
│
|
||||
├── app/ # 应用主目录
|
||||
│ ├── config/ # 配置目录
|
||||
│ │ ├── settings.py # 配置管理
|
||||
│ │ └── defaults.py # 默认配置值
|
||||
│ │
|
||||
│ ├── core/ # 核心功能
|
||||
│ │ ├── ocr/ # OCR相关功能
|
||||
│ │ │ ├── baidu_ocr.py # 百度OCR接口
|
||||
│ │ │ └── table_ocr.py # 表格OCR处理
|
||||
│ │ │
|
||||
│ │ ├── excel/ # Excel处理
|
||||
│ │ │ ├── processor.py # Excel处理核心
|
||||
│ │ │ ├── merger.py # 订单合并功能
|
||||
│ │ │ └── converter.py # 单位转换与规格处理
|
||||
│ │ │
|
||||
│ │ └── utils/ # 工具函数
|
||||
│ │ ├── file_utils.py # 文件处理工具
|
||||
│ │ └── log_utils.py # 日志工具
|
||||
│ │
|
||||
│ └── services/ # 服务层
|
||||
│ ├── ocr_service.py # OCR服务
|
||||
│ └── excel_service.py # Excel处理服务
|
||||
│
|
||||
├── data/ # 数据目录
|
||||
│ ├── input/ # 输入图片目录
|
||||
│ ├── output/ # 处理结果输出目录
|
||||
│ ├── temp/ # 临时文件目录
|
||||
│ └── backup/ # 备份目录
|
||||
│
|
||||
├── logs/ # 日志目录
|
||||
│
|
||||
├── templates/ # 模板目录
|
||||
│ └── 银豹-采购单模板.xls # Excel模板文件
|
||||
│
|
||||
├── config.ini # 配置文件
|
||||
├── run.py # 命令行入口脚本
|
||||
├── 启动器.py # 图形界面启动器
|
||||
└── README.md # 项目说明文档
|
||||
```
|
||||
|
||||
## 安装与配置
|
||||
|
||||
### 环境要求
|
||||
|
||||
- Python 3.8+
|
||||
- 百度OCR API账号及密钥
|
||||
|
||||
### 安装依赖
|
||||
## 安装与运行
|
||||
### 1. 环境准备
|
||||
- 推荐Python 3.8及以上版本
|
||||
- Windows 10/11(推荐),支持部分Linux发行版
|
||||
|
||||
### 2. 安装依赖
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
### 配置文件
|
||||
|
||||
在`config.ini`中配置以下信息:
|
||||
|
||||
```ini
|
||||
[OCR]
|
||||
api_key = 你的百度OCR API Key
|
||||
secret_key = 你的百度OCR Secret Key
|
||||
|
||||
[Paths]
|
||||
input_folder = data/input
|
||||
output_folder = data/output
|
||||
template_file = templates/银豹-采购单模板.xls
|
||||
### 3. 启动程序
|
||||
- 图形界面启动:
|
||||
```bash
|
||||
python 启动器.py
|
||||
```
|
||||
- 命令行模式:
|
||||
```bash
|
||||
python run.py --help
|
||||
```
|
||||
|
||||
## 使用方法
|
||||
|
||||
1. **启动系统**
|
||||
- 双击运行 `启动器.py` 文件,启动图形界面
|
||||
- 或者通过命令行运行 `python run.py <命令> [选项]`
|
||||
|
||||
2. **图形界面操作**
|
||||
- **处理Excel文件**: 处理指定的Excel文件或最新的Excel文件
|
||||
- **OCR批量识别**: 批量处理input目录下的所有图片
|
||||
- **完整处理流程**: 一键执行OCR识别、Excel处理和订单合并
|
||||
- **处理单个图片**: 处理指定的单张图片
|
||||
- **合并采购单**: 合并多个采购单为一个总表
|
||||
- **处理烟草订单**: 处理烟草公司特定格式的订单明细文件,生成银豹采购单格式
|
||||
- **整理项目文件**: 整理项目文件结构
|
||||
- **清除处理缓存**: 清除处理缓存,使系统重新处理所有文件
|
||||
- **清理文件**: 清理所有数据文件
|
||||
- **切换主题**: 在浅色和深色主题之间切换
|
||||
|
||||
## 命令行使用
|
||||
|
||||
系统支持通过命令行操作,基本用法:
|
||||
## 依赖环境
|
||||
- Python 3.8+
|
||||
- 主要依赖库:tkinter、pandas、numpy、xlrd、xlwt、xlutils、requests、openpyxl 等
|
||||
- 详见 requirements.txt
|
||||
|
||||
## 目录结构
|
||||
```
|
||||
python run.py <命令> [选项]
|
||||
├── app/ # 主程序模块
|
||||
│ ├── config/ # 配置管理
|
||||
│ ├── core/ # 核心功能(OCR、Excel、工具等)
|
||||
│ ├── services/ # 服务层(业务逻辑)
|
||||
│ └── ...
|
||||
├── data/ # 输入输出与缓存目录
|
||||
├── templates/ # Excel模板文件
|
||||
├── logs/ # 日志文件
|
||||
├── run.py # 命令行主入口
|
||||
├── 启动器.py # 图形界面主入口
|
||||
├── requirements.txt # 依赖包列表
|
||||
├── README.md # 使用说明
|
||||
├── 更新日志.md # 更新日志
|
||||
└── ...
|
||||
```
|
||||
|
||||
支持的命令:
|
||||
|
||||
1. **ocr**: OCR识别
|
||||
```
|
||||
python run.py ocr [--input 图片路径] [--batch] [--batch-size 批大小] [--max-workers 最大线程数]
|
||||
```
|
||||
|
||||
2. **excel**: Excel处理
|
||||
```
|
||||
python run.py excel [--input Excel文件路径]
|
||||
```
|
||||
|
||||
3. **merge**: 订单合并
|
||||
```
|
||||
python run.py merge [--input 采购单文件路径列表,以逗号分隔]
|
||||
```
|
||||
|
||||
4. **pipeline**: 完整流程
|
||||
```
|
||||
python run.py pipeline [--input 图片路径]
|
||||
```
|
||||
|
||||
5. **tobacco**: 烟草订单处理
|
||||
```
|
||||
python run.py tobacco [--input 烟草订单明细文件路径]
|
||||
```
|
||||
|
||||
## 单位处理规则
|
||||
|
||||
系统支持多种单位的智能处理,自动识别和转换不同的计量单位。单位处理逻辑如下:
|
||||
|
||||
### 标准单位处理
|
||||
|
||||
| 单位 | 处理规则 | 示例 |
|
||||
|------|----------|------|
|
||||
| 件 | 数量×包装数量<br>单价÷包装数量<br>单位转换为"瓶" | 1件(规格1*12) → 12瓶<br>单价108元/件 → 9元/瓶 |
|
||||
| 箱 | 数量×包装数量<br>单价÷包装数量<br>单位转换为"瓶" | 2箱(规格1*24) → 48瓶<br>单价120元/箱 → 5元/瓶 |
|
||||
| 包 | 保持原数量和单位不变 | 3包 → 3包 |
|
||||
| 其他单位 | 保持原数量和单位不变 | 5瓶 → 5瓶 |
|
||||
|
||||
### 单位自动推断规则
|
||||
|
||||
系统能够在缺少单位信息时,根据规格和其他信息自动推断单位:
|
||||
|
||||
1. 当单位为空,并且同时具备以下条件时:
|
||||
- 有商品编码
|
||||
- 有规格信息
|
||||
- 有数量信息
|
||||
- 有单价信息
|
||||
- 规格符合容量*数量格式(如"500ml*15"、"1L*12"等)或简单的数量*数量格式(如"1*12")
|
||||
|
||||
系统会:
|
||||
- 自动将单位设置为"件"
|
||||
- 然后按照件的处理规则进行转换
|
||||
|
||||
示例:
|
||||
- 商品编码: 6954767400129
|
||||
- 名称: 美汁源果粒橙1.8L*8瓶
|
||||
- 规格: 1.8L*8
|
||||
- 数量: 1
|
||||
- 单价: 65
|
||||
- 单位: (空)
|
||||
|
||||
处理后:
|
||||
- 单位被推断为"件"
|
||||
- 数量: 1 * 8 = 8
|
||||
- 单价: 65 / 8 = 8.125
|
||||
- 单位: 瓶
|
||||
|
||||
### 提和盒单位特殊处理
|
||||
|
||||
系统对"提"和"盒"单位有特殊的处理逻辑:
|
||||
|
||||
1. 当规格是三级格式(如1*5*12)时:
|
||||
- 按照件的计算方式处理
|
||||
- 数量 = 原始数量 × 包装数量
|
||||
- 单位转换为"瓶"
|
||||
- 单价 = 原始单价 ÷ 包装数量
|
||||
|
||||
示例:3提(规格1*5*12) → 36瓶
|
||||
|
||||
2. 当规格是二级格式(如1*16)时:
|
||||
- **保持原数量不变**
|
||||
- **保持原单位不变**
|
||||
|
||||
示例:3提(规格1*16) → 仍然是3提
|
||||
|
||||
### 特殊条码处理
|
||||
|
||||
系统支持对特定条码进行特殊处理,这些条码的处理规则会覆盖上述的标准单位处理规则:
|
||||
|
||||
1. 特殊条码配置:
|
||||
```python
|
||||
special_barcodes = {
|
||||
'6925019900087': {
|
||||
'multiplier': 10, # 数量乘以10
|
||||
'target_unit': '瓶', # 目标单位
|
||||
'description': '特殊处理:数量*10,单位转换为瓶'
|
||||
},
|
||||
# 条码映射配置
|
||||
'6920584471055': {
|
||||
'map_to': '6920584471017', # 映射到新条码
|
||||
'description': '条码映射:6920584471055 -> 6920584471017'
|
||||
}
|
||||
# 可以添加更多特殊条码的配置
|
||||
}
|
||||
```
|
||||
|
||||
2. 条码映射规则:
|
||||
- 当遇到特定条码时,自动将其映射为对应的目标条码
|
||||
- 条码映射完成后,会继续按照标准单位处理规则处理数量和单价的转换
|
||||
- 如果映射的条码单位是"件"或"箱",会按照件/箱的规则展开处理
|
||||
- 系统内置的条码映射规则包括:
|
||||
1. 6920584471055 → 6920584471017
|
||||
2. 6925861571159 → 69021824
|
||||
3. 6923644268923 → 6923644268480
|
||||
|
||||
3. 其他特殊处理规则:
|
||||
- 当遇到特殊条码时,无论规格是二级还是三级
|
||||
- 无论单位是提还是盒还是件
|
||||
- 都按照特殊条码配置进行处理
|
||||
- 数量乘以配置的倍数
|
||||
- 单位转换为配置的目标单位
|
||||
- 如果有单价,单价除以配置的倍数
|
||||
|
||||
## 智能规格推断
|
||||
|
||||
当规格信息为空时,系统能从商品名称自动推断规格:
|
||||
|
||||
1. 匹配"xx入"格式:
|
||||
- 如"445水溶C血橙15入纸箱" → 规格推断为 1*15
|
||||
|
||||
2. 匹配直接包含规格的格式:
|
||||
- 如"500-东方树叶-绿茶1*15-纸箱装" → 规格推断为 1*15
|
||||
|
||||
3. 匹配容量格式:
|
||||
- 如"12.9L桶装水" → 规格推断为 12.9L*1
|
||||
|
||||
4. 其他商品命名模式:
|
||||
- 如"900树叶茉莉花茶12入纸箱" → 规格推断为 1*12
|
||||
- 如"500茶π蜜桃乌龙15纸箱" → 规格推断为 1*15
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. 确保输入文件格式正确,支持jpg、png等图片格式
|
||||
2. 处理结果将输出到data/output目录下
|
||||
3. 定期清理临时文件和日志文件
|
||||
4. 及时更新百度OCR API密钥
|
||||
5. 为避免数据丢失,可使用清理功能前的备份选项
|
||||
|
||||
## 错误排查
|
||||
|
||||
- **OCR识别失败**:检查API密钥是否正确,图片是否符合要求
|
||||
- **Excel处理失败**:检查OCR识别结果是否包含必要的列(条码、数量、单价等)
|
||||
- **模板填充错误**:确保模板文件存在且格式正确
|
||||
|
||||
## 开发说明
|
||||
|
||||
如需进行二次开发或扩展功能,请参考以下说明:
|
||||
|
||||
1. 核心逻辑位于`app/core`目录
|
||||
2. 添加新功能建议遵循已有的模块化结构
|
||||
3. 使用`app/services`目录中的服务类调用核心功能
|
||||
4. 日志记录已集成到各模块,便于调试
|
||||
|
||||
## 许可证
|
||||
|
||||
MIT License
|
||||
## 常见问题
|
||||
- **Q: 启动时报错缺少依赖?**
|
||||
A: 请先运行 `pip install -r requirements.txt` 安装所有依赖。
|
||||
- **Q: OCR识别失败或API报错?**
|
||||
A: 请在系统设置中正确填写API Key和Secret Key,并确保网络畅通。
|
||||
- **Q: 处理结果找不到?**
|
||||
A: 默认输出在 `data/output/` 目录,可在系统设置中自定义。
|
||||
- **Q: 如何自定义条码映射和单位规则?**
|
||||
A: 通过"编辑条码映射"按钮进入图形化编辑界面。
|
||||
- **Q: 其他问题?**
|
||||
A: 请查看日志窗口或logs目录下日志文件,或联系作者。
|
||||
|
||||
## 联系方式
|
||||
- 作者:欢欢欢
|
||||
- 邮箱:huanhuanhuan@example.com
|
||||
- QQ:123456789
|
||||
- Issues反馈:请在项目仓库提交Issue
|
||||
|
||||
如有问题,请提交Issue或联系开发者。
|
||||
---
|
||||
|
||||
© 2025 益选-OCR订单处理系统 by 欢欢欢
|
||||
48
启动器.py
48
启动器.py
@ -683,6 +683,27 @@ def create_collapsible_frame(parent, title, initial_state=True):
|
||||
|
||||
return content_frame, state_var
|
||||
|
||||
def process_single_image_with_status(log_widget, status_bar):
|
||||
status_bar.set_status("选择图片中...")
|
||||
file_path = select_file(log_widget)
|
||||
if file_path:
|
||||
status_bar.set_status("开始处理图片...")
|
||||
run_command_with_logging(["python", "run.py", "ocr", "--input", file_path], log_widget, status_bar)
|
||||
else:
|
||||
status_bar.set_status("操作已取消")
|
||||
add_to_log(log_widget, "未选择文件,操作已取消\n", "warning")
|
||||
|
||||
def process_excel_file_with_status(log_widget, status_bar):
|
||||
status_bar.set_status("选择Excel文件中...")
|
||||
file_path = select_excel_file(log_widget)
|
||||
if file_path:
|
||||
status_bar.set_status("开始处理Excel文件...")
|
||||
run_command_with_logging(["python", "run.py", "excel", "--input", file_path], log_widget, status_bar)
|
||||
else:
|
||||
status_bar.set_status("开始处理最新Excel文件...")
|
||||
add_to_log(log_widget, "未选择文件,尝试处理最新的Excel文件\n", "info")
|
||||
run_command_with_logging(["python", "run.py", "excel"], log_widget, status_bar)
|
||||
|
||||
def main():
|
||||
"""主函数"""
|
||||
# 确保必要的目录结构存在并转移旧目录内容
|
||||
@ -911,33 +932,6 @@ def main():
|
||||
# 底部说明
|
||||
tk.Label(left_frame, text="© 2025 益选-OCR订单处理系统 v1.0 by 欢欢欢", font=("Arial", 9)).pack(side=tk.BOTTOM, pady=10)
|
||||
|
||||
# 修改单个图片和Excel处理函数以使用状态栏
|
||||
def process_single_image_with_status(log_widget, status_bar):
|
||||
status_bar.set_status("选择图片中...")
|
||||
file_path = select_file(log_widget)
|
||||
if file_path:
|
||||
status_bar.set_status("开始处理图片...")
|
||||
run_command_with_logging(["python", "run.py", "ocr", "--input", file_path], log_widget, status_bar)
|
||||
else:
|
||||
status_bar.set_status("操作已取消")
|
||||
add_to_log(log_widget, "未选择文件,操作已取消\n", "warning")
|
||||
|
||||
def process_excel_file_with_status(log_widget, status_bar):
|
||||
status_bar.set_status("选择Excel文件中...")
|
||||
file_path = select_excel_file(log_widget)
|
||||
if file_path:
|
||||
status_bar.set_status("开始处理Excel文件...")
|
||||
run_command_with_logging(["python", "run.py", "excel", "--input", file_path], log_widget, status_bar)
|
||||
else:
|
||||
status_bar.set_status("开始处理最新Excel文件...")
|
||||
add_to_log(log_widget, "未选择文件,尝试处理最新的Excel文件\n", "info")
|
||||
run_command_with_logging(["python", "run.py", "excel"], log_widget, status_bar)
|
||||
|
||||
# 替换原始函数引用
|
||||
global process_single_image, process_excel_file
|
||||
process_single_image = process_single_image_with_status
|
||||
process_excel_file = process_excel_file_with_status
|
||||
|
||||
# 绑定键盘快捷键
|
||||
bind_keyboard_shortcuts(root, log_text, status_bar)
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user