xls2ddl/aidocs/xlsxData.md
2025-10-12 13:57:44 +08:00

8.8 KiB
Raw Permalink Blame History

技术文档:xlsx_data_processor.py


概述

该模块提供了一个用于处理 Excel.xlsx)文件和结构化数据的工具集,支持从 .xlsx 文件中读取数据并将其转换为结构化的字典对象。它特别适用于管理具有特定格式规范的 CRUD创建、读取、更新、删除配置表并能自动解析字段类型、主键、外键、索引等元信息。

模块主要功能包括:

  • .xlsx 文件加载数据并按工作表组织。
  • 支持自定义字段类型的自动转换(如 int, float, json 等)。
  • 支持扩展的数据格式(如 cruddata, xlsxdata)通过字符串协议调用。
  • 提供对特殊格式的 CRUD 配置文件的支持(包含 summary, fields, validation 等 sheet
  • 命令行接口可批量合并多个数据源Excel 和参数)输出 JSON。

依赖库

import os
import sys
from traceback import print_exc
from openpyxl import load_workbook
from appPublic.myjson import loadf, dumpf, dumps
from appPublic.dictObject import DictObject

⚠️ 注意:appPublic 是一个自定义公共库,需确保已安装或路径正确。


核心类与函数说明

1. TypeConvert

负责将原始值根据指定类型进行安全转换。

方法列表:

方法 描述
conv(typ, v) 根据类型名 typ 调用对应的转换方法(如 to_int),若无则返回原值。
to_int(v) 转换为整数,失败返回 0
to_float(v) 转换为浮点数,失败返回 0.0
to_str(v) 转换为字符串,失败返回空串 ''
to_json(v) 将字符串解析为 JSON 对象,空字符串保持不变,失败返回原值。⚠️ 存在 bug应使用 loads 但代码中写成了 loads(v) 实际未导入。
to_date(v), to_time(v), to_timestamp(v) 占位方法,直接返回原值(未来可扩展)。
to_cruddata(v) 解析形如 "cruddata:\"filename\".property" 的字符串,动态加载 CRUDData 并执行属性/方法访问。
to_xlsxdata(v) 类似 to_cruddata,但用于普通 XLSXData 对象。

示例输入:"cruddata:\"user.xlsx\".users" → 加载 user.xlsx 并获取其 users 表数据。

Bug 提示:to_json 中使用了未定义的 loads 函数,应改为 from json import loads 或使用 dumps 所属模块中的 loads


2. CRUDException(Exception)

自定义异常类,用于报告 .xlsx 文件处理过程中的错误。

属性:

  • xlsfile: 出错的文件名
  • errmsg: 错误描述

__str__() 返回格式:

filename:<文件名> error:<错误信息>

3. XLSXData

通用 .xlsx 文件读取器,将每个工作表解析为记录列表,并封装成 DictObject

构造函数:__init__(xlsxfile, book=None)

  • xlsxfile: Excel 文件路径
  • book: 可选的已打开的 Workbook 对象(用于性能优化或复用)

主要方法:

方法 功能
_read() 内部方法,遍历所有 sheet 并调用 readRecords() 构建 self.data
get_data() 返回最终解析后的数据对象(DictObject)。
readRecords(name, sheet) 读取单个 sheet 数据:
- 第一行作为字段定义(格式:字段名:类型
- 后续行为数据行
- 使用 TypeConvert 进行类型转换
- 返回 {name: [DictObject(...), ...]}
getFieldNames(row) 处理首行字段:
- 若为空则命名为 F_i
- 分割 name:type 形式,缺失类型设为 None
- 返回 [ [字段名, 类型], ... ]

📌 字段命名规则示例:

  • id:int → 名称 id,类型 int
  • username → 名称 username,类型 None
  • 空单元格 → 自动命名为 F_0, F_1...

4. CRUDData(XLSXData)

继承自 XLSXData,专用于处理符合 CRUD 元数据规范的 .xlsx 文件。

规范要求:

必须包含以下三个工作表:

  • summary: 表基本信息(如主键)
  • fields: 字段定义列表
  • validation: 验证规则(外键、索引等)

类方法:isMe(book)

判断给定 workbook 是否满足 CRUDData 格式(检查是否存在上述三个 sheet

重写 _read() 方法流程:

  1. 调用父类 _read() 解析所有 sheet。
  2. 验证 summary, fields, validation 存在且唯一。
  3. 执行元数据转换:
    • convPrimary(): 解析主键字段(逗号分隔)
    • convForeignkey(): 解析外键规则(格式:table:value:title
    • convIndex(): 解析索引定义(格式:idx_type:key1,key2
    • check_codes_fields(): 验证 codes 表中的字段是否存在于 fields

辅助方法:

方法 功能
check_field(fieldname) 检查字段是否在 fields 表中存在
getFieldByNmae(fields, name) 获取指定名称的字段定义(拼写错误:Nmae 应为 Name
getFKs(validation) 提取所有外键规则(oper == 'fk'
getIDXs(validation) 提取所有索引规则(oper == 'idx'

⚠️ Bug 提示:

  • getFieldByNmae 函数名拼写错误,可能导致调用失败。
  • getFKs 中条件判断写成了 'oepr' 而非 'oper',导致无法识别外键。

5. xlsxFactory(xlsxfilename) 函数

根据文件内容自动选择合适的类实例化(工厂模式)。

流程:

  1. 打开 .xlsx 文件。
  2. 遍历 XLSXData 的所有子类(递归查找),调用 isMe(book) 判断是否匹配。
  3. 匹配成功则返回 CRUDData 实例,否则返回默认 XLSXData 实例。
  4. 异常捕获并打印堆栈。

支持插件式扩展:可通过新增子类实现其他专用格式识别。


6. ValueConvert(s) 函数

解析特殊前缀字符串,支持外部资源引用。

前缀 行为
xlsfile::path/to/file.xlsx 使用 xlsxFactory 加载并返回 .get_data()
jsonfile::path/to/data.json 使用 loadf() 读取 JSON 文件
其他 直接返回原字符串

7. paramentHandle(ns) 函数

对参数字典中的每个值应用 ValueConvert,实现参数注入时的自动资源加载。

示例:

python script.py data=xlsfile::config.xlsx user=jsonfile::user.json

→ 自动加载 Excel 和 JSON 文件内容。


主程序入口(if __name__ == '__main__':

支持命令行运行,用法如下:

参数格式:

  • key=value:设置命名参数(支持 xlsfile::, jsonfile::
  • filepath:直接加载数据文件(仅限 .xlsx, .xls

执行流程:

  1. 解析命令行参数,分离 ns(命名空间)和 datafiles(文件列表)。
  2. 处理 ns 中的值(调用 paramentHandle)。
  3. 遍历 datafiles,使用 xlsxFactory 加载每个 Excel 文件。
  4. 合并所有数据到 retData
  5. 输出合并后的 JSON 结果(使用 dumps 格式化)。

示例命令:

python xlsx_data_processor.py \
    config=xlsfile::app_config.xlsx \
    user=jsonfile::default_user.json \
    roles.xlsx \
    permissions.xlsx

输出结果为整合所有来源数据的 JSON 对象。


已知问题与改进建议

问题 描述 建议修复
to_json 使用 loads 未定义 导致 JSON 解析失败 改为 from json import loads 或使用 dumps.loads()
getFieldByNmae 拼写错误 方法名错误 更正为 getFieldByName
getFKs 条件判断错误 'oepr' == 'fk' 永不成立 改为 'oper'
check_field(f for f in ...) 语法错误,不能传生成器 改为循环逐一检查每个字段
vs < 3split 后无效 vs 是 list比较 < 3 不合理 应改为 len(vs) < 3
to_cruddata / to_xlsxdatavs[2] is None split 不会返回 None 元素 应改为 len(vs) <= 2 判断是否有命令部分

使用示例

示例 Excel 结构(users.xlsx

Sheet: users

id:int,name:str,age:int
1,Alice,25
2,Bob,30

Sheet: summary

table:primary
users:id

Sheet: fields

name,type,desc
id,int,用户ID
name,str,用户名
age,int,年龄

调用方式:

d = xlsxFactory('users.xlsx')
data = d.get_data()
print(data.users[0].name)  # 输出: Alice
print(data.summary[0].primary)  # 输出: ['id']

总结

本模块是一个轻量级但功能丰富的 .xlsx 数据处理器,适合用于配置中心、元数据管理、自动化脚本等场景。结合自定义前缀协议和工厂模式,具备良好的扩展性。

尽管存在少量 bug 和命名问题,整体设计清晰,层次分明,易于维护和二次开发。


作者Auto-generated Technical Documentation
版本1.0
最后更新2025-04-05