# `ExcelWriter` 类技术文档 ## 概述 `ExcelWriter` 是一个基于 `xlwt` 库的 Python 工具类,用于将嵌套字典或列表结构的数据写入 Excel 文件(`.xls` 格式)。它支持递归处理复杂数据结构(如字典、列表、记录列表等),并自动展开为可读的表格形式。 该工具适用于导出配置、日志、数据库查询结果或其他结构化数据到 Excel 表格中。 --- ## 依赖库 - `xlwt`: 用于创建和写入 `.xls` 文件。 - `appPublic.strUtils.lrtrim`: 自定义字符串去空函数(左右空格去除)。 > 注意:`xlwt` 不支持 `.xlsx` 格式,仅支持旧版 `.xls`。 --- ## 类定义 ```python class ExcelWriter: def __init__(self, encoding='gb2312'): self.encoding = encoding ``` ### 构造函数 `__init__` #### 参数: - **`encoding`** (str): 输出 Excel 文件的字符编码,默认为 `'gb2312'`。 常见可选值包括 `'utf-8'`, `'gbk'` 等,需与系统兼容。 #### 示例: ```python writer = ExcelWriter(encoding='utf-8') ``` --- ## 主要方法 ### `write(excelfile, dictdata)` 将字典格式的数据写入指定的 Excel 文件,每个顶级键作为工作表名称。 #### 参数: - **`excelfile`** (str): 输出文件路径(如 `'output.xls'`)。 - **`dictdata`** (dict): 数据字典,键为工作表名,值为待写入内容(支持 dict/list)。 #### 示例: ```python data = { 'Sheet1': ['a', 'b', 'c'], 'Sheet2': {'key': 'value'} } writer.write('output.xls', data) ``` > 此方法会为每个 key 创建一个 sheet,并调用 `writeV()` 写入其值。 --- ### `writeV(sheet, x, y, v)` 递归写入任意类型值到工作表的指定位置。 #### 参数: - **`sheet`**: `xlwt.Worksheet` 对象。 - **`x`**, **`y`** (int): 起始行、列索引(从 0 开始)。 - **`v`**: 待写入的值(支持 str/int/float/list/dict)。 #### 行为逻辑: | 类型 | 处理方式 | |------|---------| | `list` | 调用 `writeList()` | | `dict` | 调用 `writeDict()` | | 其他(str/int/float) | 直接写入单元格,若为字符串则先去空格 | #### 返回值: 返回占用的行数(int)。 --- ### `writeDict(sheet, x, y, adict)` 将字典写入工作表,每项占一行,键在左,值在右,支持嵌套。 #### 参数: - `sheet`: 工作表对象 - `x`, `y`: 起始坐标 - `adict`: 字典对象 #### 输出示例: ``` __dict__ key1 value1 key2 [nested...] ``` #### 返回值: 返回所占行数。 --- ### `writeList(sheet, x, y, alist, singlecell=False)` 写入列表数据,根据内容自动判断处理方式。 #### 参数: - `alist`: 列表数据 - `singlecell`: 是否合并为单个单元格(逗号分隔) #### 分支逻辑: 1. **如果是记录列表(`isRecords(alist)` 为 True)** → 调用 `writeRecords()` 以表格形式输出。 2. **如果包含字典或嵌套结构** → 多行展开,逐项调用 `writeDict` 或 `writeMultiLineList`。 3. **普通列表** → 横向展开在同一行(列递增),除非 `singlecell=True`。 #### 返回值: 返回占用行数。 --- ### `writeRecords(sheet, x, y, alist)` 将“记录列表”(即字典列表)以表格形式写入 Excel。 #### 前提条件: 所有元素必须是字典,且值不能是嵌套复杂结构(不支持 list of dict with nested dicts/lists)。 #### 功能: - 自动生成表头(字段名) - 支持字段值为列表时标记为 `fieldname:list` - 自动对齐列位置 #### 示例输入: ```python [ {'name': 'Alice', 'tags': ['dev', 'ml']}, {'name': 'Bob', 'tags': ['qa']} ] ``` #### 输出效果: | name | tags:list | |-------|----------------| | Alice | dev,ml | | Bob | qa | #### 返回值: 返回写入的记录条数(行数 -1,不含标题行)。 --- ### `createRecordTitle(ws, x, y, title, poss, isList=False)` 和 `writeRecordTitle(ws, x, poss)` 辅助方法,用于管理记录字段的列映射。 - `poss`: 字段名 → 列索引 的字典,`__list__` 子集标记哪些字段是列表。 - `createRecordTitle`: 注册字段名及其列位置。 - `writeRecordTitle`: 在指定行写出表头。 --- ### `writeMultiLineList(sheet, x, y, alist)` 将列表纵向写入一列,第一行为 `__list__` 标记。 #### 示例输出: ``` __list__ item1 item2 item3 ``` #### 返回值: 返回占用行数。 > ⚠️ Bug 提示:代码中存在拼写错误 `os` 应为 `ox`,应修正为: ```python return x - ox # 而非 return x - os ``` --- ### `isRecords(alist)` 判断一个列表是否为“记录列表”(即字典列表,且无深层嵌套)。 #### 条件: - 所有元素是字典 - 字典的值不能是字典或包含复杂类型的列表 #### 返回值: - `True` if 符合记录格式 - `False` otherwise --- ## 使用示例 ```python from appPublic.strUtils import lrtrim import xlwt # 实例化 w = ExcelWriter(encoding='utf-8') # 准备测试数据 data = { 'my1': ['23423', '423424', 't334t3', 2332, 'erfverfefew'], 'my2': [ {'aaa': 1, 'bbb': 'bbb'}, {'aaa': 2, 'bbb': 'hello'} ], } # 写入文件 w.write(r'd:\text.xls', data) ``` ### 输出说明: - **Sheet: my1** 单行横向显示列表元素。 - **Sheet: my2** 表格形式展示两行记录,表头为 `aaa`, `bbb`。 --- ## 已知问题与改进建议 | 问题 | 描述 | 建议修复 | |------|------|----------| | ❌ `os` 未定义 | `writeMultiLineList` 中 `return x - os` 错误 | 改为 `return x - ox` | | ⚠️ 编码限制 | `gb2312` 可能无法显示中文 | 推荐使用 `'utf-8'` 或 `'gbk'` | | ⚠️ 性能问题 | 多层嵌套递归可能导致性能下降 | 添加深度限制或优化结构遍历 | | 🔄 单元格覆盖 | 启用了 `cell_overwrite_ok=True`,可能造成意外覆盖 | 明确告知用户风险 | | 💾 格式限制 | 仅支持 `.xls`,不支持 `.xlsx` | 可考虑升级为 `openpyxl` 或 `pandas` 替代 | --- ## 总结 `ExcelWriter` 提供了一种简洁的方式将 Python 中的嵌套数据结构导出为 Excel 文件,特别适合调试、配置导出、简单报表生成等场景。 尽管存在一定局限性(如格式老旧、潜在 bug),但其设计清晰、易于扩展,是一个实用的小型工具类。 --- ## 版权与维护 - **作者**: 未知(来自内部模块 `appPublic`) - **语言**: Python 2/3 兼容(建议运行于 Python 3.x + `xlwt-future`) - **用途**: 内部数据导出工具 > 建议后续迁移至 `openpyxl` 或 `pandas.DataFrame.to_excel()` 以获得更好的功能和维护支持。