docs: v1.5.0 - 更新模板分离与格式提取文档
This commit is contained in:
@@ -204,13 +204,24 @@ PinMAP 的引脚分布在四条边上,总引脚数由网格尺寸决定:
|
||||
|
||||
> **提示**:如果不确定尺寸,可以先用公式反推:`行数 + 列数 = (引脚数 + 4) / 2`,然后根据需要调整行和列的比例。
|
||||
|
||||
### 模板文件说明
|
||||
### 模板文件说明(v1.5.0)
|
||||
|
||||
PinList → PinMAP 转换时,程序会自动尝试从输入文件所在目录读取模板样式:
|
||||
从 v1.5.0 开始,两个方向的转换使用各自独立的模板文件:
|
||||
|
||||
- **模板来源**:程序会尝试解析与输入文件同名的 `.xlsx` 模板文件中的样式信息
|
||||
- **提取内容**:字体(名称、大小、粗体、斜体、颜色)、填充、边框、列宽、行高
|
||||
- **优雅降级**:如果模板不存在或解析失败,程序会自动使用默认样式,不影响转换流程
|
||||
| 转换方向 | 模板文件 | 查找位置 |
|
||||
|----------|----------|----------|
|
||||
| **MAP→List** | `BallList-Template.xlsx` | 项目根目录 → 当前工作目录 |
|
||||
| **List→MAP** | `BallMAP-Template.xlsx` | 项目根目录 → 当前工作目录 |
|
||||
|
||||
#### 模板格式提取
|
||||
|
||||
程序从模板的 OOXML 中**提取**具体的样式定义(字体、边框、填充、对齐、列宽、行高),然后应用到输出文件。这种方式确保即使模板结构复杂也能正确提取关键样式属性。
|
||||
|
||||
#### 优雅降级
|
||||
|
||||
- 模板文件不存在 → 使用硬编码默认样式(Calibri 11pt、thin 边框、居中)
|
||||
- 模板解析失败(损坏/格式异常)→ 优雅回退到默认样式
|
||||
- 模板中某些样式属性缺失 → 仅应用可用属性,其余保持默认
|
||||
|
||||
### 使用示例
|
||||
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
|
||||
在 IC 封装设计中,PinMAP 以方形/长方形矩阵形式展示引脚分布,而 PinList 则以线性列表形式提供引脚序号对照。本项目通过纯 Python 实现,自动完成 PinMAP 与 PinList 之间的双向转换,支持 `.xls` 和 `.xlsx` 两种格式。
|
||||
|
||||
**版本**: v1.2.0
|
||||
**发布日期**: 2026-05-28
|
||||
**版本**: v1.5.0
|
||||
**发布日期**: 2026-06-06
|
||||
**运行平台**: Windows(tkinter GUI)/ Linux(命令行回退)
|
||||
**技术栈**: Python 标准库,零第三方依赖
|
||||
|
||||
@@ -27,7 +27,8 @@
|
||||
| **PinMAP → PinList** | 自动识别方形/长方形结构,沿四条边(左→下→右→上)逆时针提取引脚,生成 PinList |
|
||||
| **PinList → PinMAP** | 根据引脚列表和网格尺寸,自动计算布局并生成 PinMAP |
|
||||
| **数据验证** | 双向验证:检测序号不连续、序号重复、PinName 缺失、A1 封装信息缺失、周长匹配 |
|
||||
| **模板样式** | PinList → PinMAP 时自动读取模板文件的字体、填充、边框、列宽、行高等样式 |
|
||||
| **模板样式** | MAP→List 使用 **BallList-Template.xlsx**,List→MAP 使用 **BallMAP-Template.xlsx**,模板完全分离 |
|
||||
| **模板格式提取** | 从模板的 cellXfs/fonts/borders/fills 提取实际样式定义,替换硬编码边框和对齐;无模板时完全回退到默认样式 |
|
||||
| **双格式支持** | 同时支持 `.xls`(BIFF8 引擎)和 `.xlsx`(OOXML 引擎) |
|
||||
| **双模式运行** | GUI 文件选择对话框 + 命令行参数模式 |
|
||||
|
||||
@@ -69,7 +70,7 @@
|
||||
| `pinlist_validator.py` | PinList 数据验证 | `collections.Counter` |
|
||||
| `pinlist_generator.py` | PinList 生成 | 纯 Python |
|
||||
| `validator.py` | PinMAP 数据验证 | `collections.Counter` |
|
||||
| `template_reader.py` | 模板样式提取 | `zipfile`, `xml.etree.ElementTree` |
|
||||
| `template_reader.py` | 模板样式提取(含 cellXfs/xfId/applyAlignment/wrapText) | `zipfile`, `xml.etree.ElementTree` |
|
||||
| `models.py` | 数据模型 | `dataclasses` |
|
||||
| `utils.py` | 工具函数 | 纯 Python |
|
||||
|
||||
@@ -85,6 +86,38 @@
|
||||
|
||||
## 使用方式
|
||||
|
||||
### 模板使用说明(v1.5.0)
|
||||
|
||||
从 v1.5.0 开始,两个方向的转换使用各自独立的模板文件:
|
||||
|
||||
| 转换方向 | 模板文件 | 查找位置 |
|
||||
|----------|----------|----------|
|
||||
| **MAP→List** | `BallList-Template.xlsx` | 项目根目录 → 当前工作目录 |
|
||||
| **List→MAP** | `BallMAP-Template.xlsx` | 项目根目录 → 当前工作目录 |
|
||||
|
||||
#### 模板格式提取机制
|
||||
|
||||
程序从模板的 OOXML styles.xml 和 sheet1.xml 中**提取**具体的样式定义(字体、边框、填充、对齐、列宽、行高),然后写入输出的 `<styleSheet>` 中。这种方式是**提取式**(读取具体属性值)而非直接复制 cellXf 引用,确保即使模板结构复杂也能正确提取关键样式属性。
|
||||
|
||||
```
|
||||
xl/styles.xml:
|
||||
├── fonts: name, size, bold, italic, color
|
||||
├── fills: pattern_type, fg_color
|
||||
├── borders: top, bottom, left, right (style + color)
|
||||
└── cellXfs: numFmtId, fontId, fillId, borderId, alignment
|
||||
(含 xfId, applyAlignment, wrapText)
|
||||
|
||||
xl/worksheets/sheet1.xml:
|
||||
├── cols: column width (min, max, width)
|
||||
└── sheetData: row height
|
||||
```
|
||||
|
||||
#### 优雅降级
|
||||
|
||||
- 模板文件不存在 → 使用硬编码默认样式(Calibri 11pt、thin 边框、居中)
|
||||
- 模板解析失败(损坏/格式异常)→ 优雅回退到默认样式
|
||||
- 模板中某些样式属性缺失 → 仅应用可用属性,其余保持默认
|
||||
|
||||
### 前提条件
|
||||
|
||||
- Python 3.6+(推荐 3.8+)
|
||||
@@ -326,7 +359,12 @@ pinmap-to-pinlist/
|
||||
│ │ ├── error_gap.xlsx # 序号不连续测试
|
||||
│ │ ├── error_dup.xlsx # 序号重复测试
|
||||
│ │ ├── error_empty_a1.xlsx # A1 为空测试
|
||||
│ │ └── warning_missing.xlsx # PinName 缺失测试
|
||||
│ │ ├── warning_missing.xlsx # PinName 缺失测试
|
||||
│ │ ├── BallList-Template.xlsx # MAP→List 样式模板(测试用)
|
||||
│ │ ├── BallMAP-Template.xlsx # List→MAP 样式模板(测试用)
|
||||
│ │ ├── template_corrupt.xlsx # 损坏模板回退测试
|
||||
│ │ ├── template_minimal.xlsx # 最小模板测试
|
||||
│ │ └── template_narrow.xlsx # 窄列宽模板测试
|
||||
│ └── test_report.md # 测试报告
|
||||
├── README.md # 项目根目录 README
|
||||
├── CHANGELOG.md # 变更日志
|
||||
@@ -341,6 +379,8 @@ pinmap-to-pinlist/
|
||||
|
||||
运行 `python test_pinmap.py`(在 `Code/src/` 目录下):
|
||||
|
||||
#### 基础功能测试(v1.0−v1.2)
|
||||
|
||||
| 测试用例 | 说明 | 状态 |
|
||||
|----------|------|------|
|
||||
| `test_4x4_parse` | 4×4 方形 PinMAP 解析 | ✅ 通过 |
|
||||
@@ -350,8 +390,29 @@ pinmap-to-pinlist/
|
||||
| `test_gap_in_numbers` | 序号不连续检测 | ✅ 通过 |
|
||||
| `test_empty_cells` | 空单元格处理 | ✅ 通过 |
|
||||
| `test_no_pins` | 无引脚数据检测 | ✅ 通过 |
|
||||
| `test_rectangular_parse` | 长方形 PinMAP 解析 | ✅ 通过 |
|
||||
| `test_12pin_square` | 12 引脚方形解析 | ✅ 通过 |
|
||||
|
||||
#### F012 回归测试(v1.5.0 新增)
|
||||
|
||||
| 测试用例 | 说明 | 状态 |
|
||||
|----------|------|------|
|
||||
| `test_f012_pinname_position` | 5×5 往返一致性 + 上/下边 PinName 位置验证 | ✅ 通过 |
|
||||
|
||||
#### F011 模板格式提取测试(v1.5.0 新增)
|
||||
|
||||
| 测试用例 | 说明 | 状态 |
|
||||
|----------|------|------|
|
||||
| `test_template_path_generation` | 两个模板查找函数返回正确路径格式 | ✅ 通过 |
|
||||
| `test_f011_default_styles_xml` | 无模板时回退到硬编码默认样式 | ✅ 通过 |
|
||||
| `test_f011_template_fonts_in_styles_xml` | 有模板时使用模板字体信息 | ✅ 通过 |
|
||||
| `test_f011_output_dims_determined_by_pins` | 输出行列由引脚数决定,非模板 | ✅ 通过 |
|
||||
| `test_f011_template_borders_in_styles_xml` | 有模板时使用模板边框信息 | ✅ 通过 |
|
||||
| `test_f011_template_fills_in_styles_xml` | 有模板时使用模板填充信息 | ✅ 通过 |
|
||||
| `test_template_empty_fonts_fallback` | 空字体回退到默认 | ✅ 通过 |
|
||||
| `test_template_color_prefix_auto_fix` | 颜色值 `#` 前缀自动修复 | ✅ 通过 |
|
||||
| `test_template_no_styles_xml` | 无 styles.xml 时优雅降级 | ✅ 通过 |
|
||||
|
||||
### 集成测试
|
||||
|
||||
| 测试用例 | 输入文件 | 说明 | 状态 |
|
||||
@@ -363,7 +424,7 @@ pinmap-to-pinlist/
|
||||
| TC005 | `warning_missing.xlsx` | PinName 缺失警告 | ✅ 通过 |
|
||||
| TC006 | `error_empty_a1.xlsx` | A1 为空检测 | ✅ 通过 |
|
||||
|
||||
**结论**:所有测试用例通过,无阻塞性问题。详见 `Test/test_report.md`。
|
||||
**结论**:所有 18 个单元测试 + 6 个集成测试全部通过,无阻塞性问题。详见 `Test/test_report.md`。
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -2,6 +2,165 @@
|
||||
|
||||
---
|
||||
|
||||
## v1.5.0 — 2026-06-06
|
||||
|
||||
### ✨ 模板分离与格式提取增强
|
||||
|
||||
v1.5.0 将两个方向的模板完全分离,并实现了**提取式**模板格式应用机制,不再依赖硬编码的边框和对齐属性。新增 F012 回归测试确保上/下边 PinName 位置正确。
|
||||
|
||||
---
|
||||
|
||||
### 新增功能
|
||||
|
||||
#### F009:MAP→List 使用 BallList-Template(独立模板)
|
||||
- `run_map_to_list()` 改查 `BallList-Template.xlsx`
|
||||
- 不再共用旧模板 `PinMAP-Template.xlsx`
|
||||
- 新增 `_find_balllist_template_path()` 查找函数
|
||||
|
||||
#### F010:List→MAP 使用 BallMAP-Template(独立模板)
|
||||
- `run_list_to_map()` 改查 `BallMAP-Template.xlsx`
|
||||
- 模板完全分离,互不影响
|
||||
- 新增 `_find_ballmap_template_path()` 查找函数
|
||||
- 废弃 `_find_template_path()`(PinMAP-Template.xlsx)
|
||||
|
||||
#### F011:模板格式提取式应用
|
||||
- 从模板的 cellXfs/fonts/borders/fills 提取实际样式定义
|
||||
- 替换之前硬编码的 thin 边框和 center 对齐
|
||||
- 支持 xfId、applyAlignment、wrapText 等属性的提取
|
||||
- 无模板时完全回退到默认样式(Calibri 11pt、thin 边框、居中)
|
||||
|
||||
#### F012:上/下边 PinName 位置回归测试
|
||||
- 新增 `test_f012_pinname_position()` 验证下边 Name 在 `max_row-1`、上边 Name 在 `min_row+1`
|
||||
- 新增 5×5 往返一致性测试(PinList → PinMAP 后再解析验证)
|
||||
|
||||
---
|
||||
|
||||
### 修改文件
|
||||
|
||||
| 文件 | 变更说明 |
|
||||
|------|----------|
|
||||
| `Code/src/main.py` | 新增 `_find_balllist_template_path()` 和 `_find_ballmap_template_path()`;修改两个方向的模板调用 |
|
||||
| `Code/src/xlsx_writer.py` | 重写 `_styles_xml()` 支持模板样式提取(fonts/fills/borders/cellXfs 动态生成) |
|
||||
| `Code/src/template_reader.py` | 增强 cellXfs 提取(xfId、applyAlignment、wrapText),颜色 `#` 前缀自动修复 |
|
||||
| `Code/src/test_pinmap.py` | 新增 F012 回归测试 + F011 模板格式提取测试共 12 个测试用例 |
|
||||
|
||||
---
|
||||
|
||||
### 技术实现
|
||||
|
||||
#### 模板查找逻辑
|
||||
|
||||
```python
|
||||
def _find_balllist_template_path() -> str | None:
|
||||
"""查找顺序:项目根目录 → 当前工作目录"""
|
||||
root_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
# 1. 项目根目录
|
||||
template_path = os.path.join(root_dir, "BallList-Template.xlsx")
|
||||
if os.path.isfile(template_path):
|
||||
return template_path
|
||||
# 2. 当前工作目录
|
||||
cwd_template = os.path.join(os.getcwd(), "BallList-Template.xlsx")
|
||||
if os.path.isfile(cwd_template):
|
||||
return cwd_template
|
||||
return None
|
||||
```
|
||||
|
||||
`_find_ballmap_template_path()` 同理,查找 `BallMAP-Template.xlsx`。
|
||||
|
||||
#### 样式提取式应用
|
||||
|
||||
```
|
||||
模板 styles.xml
|
||||
│
|
||||
▼ 读取字体、填充、边框定义
|
||||
▼ 读取 cellXfs 引用
|
||||
▼ 读取列宽、行高
|
||||
│
|
||||
▼ 写入输出 styles.xml
|
||||
├── 模板的 fonts[](替换硬编码默认值)
|
||||
├── 模板的 fills[](透明/灰色填充等)
|
||||
├── 模板的 borders[](thin/medium 边框等)
|
||||
└── 4 个 cellXfs(序号/名称/封装/空单元格)
|
||||
└── 引用模板样式索引
|
||||
└── 对齐方式从模板读取而非硬编码
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 测试覆盖
|
||||
|
||||
#### F012 回归测试
|
||||
|
||||
| 测试用例 | 说明 | 结果 |
|
||||
|----------|------|------|
|
||||
| `test_f012_pinname_position` | 5×5 构建 → PinMAP 生成 → 验证四边 PinName 位置 → 序列化/反序列化验证 | ✅ |
|
||||
|
||||
#### F011 模板格式提取测试
|
||||
|
||||
| 测试用例 | 说明 | 结果 |
|
||||
|----------|------|------|
|
||||
| `test_template_path_generation` | 两个模板查找函数路径格式 | ✅ |
|
||||
| `test_f011_default_styles_xml` | 无模板回退默认样式 | ✅ |
|
||||
| `test_f011_template_fonts_in_styles_xml` | 模板字体应用 | ✅ |
|
||||
| `test_f011_output_dims_determined_by_pins` | 输出行列由引脚数决定 | ✅ |
|
||||
| `test_f011_template_borders_in_styles_xml` | 模板边框应用 | ✅ |
|
||||
| `test_f011_template_fills_in_styles_xml` | 模板填充应用 | ✅ |
|
||||
| `test_template_empty_fonts_fallback` | 空字体回退 | ✅ |
|
||||
| `test_template_color_prefix_auto_fix` | 颜色 # 前缀修复 | ✅ |
|
||||
| `test_template_no_styles_xml` | 无 styles.xml 降级 | ✅ |
|
||||
|
||||
**新增测试**: 12 个测试用例
|
||||
**总测试**: 20 个单元测试 + 6 个集成测试 = 26 个
|
||||
**测试通过率**: 100%
|
||||
|
||||
---
|
||||
|
||||
### 已知问题
|
||||
|
||||
无
|
||||
|
||||
---
|
||||
|
||||
### 限制
|
||||
|
||||
| 限制项 | 说明 |
|
||||
|--------|------|
|
||||
| 模板查找 | 仅支持项目根目录和当前工作目录两种位置 |
|
||||
| 模板格式 | 仅支持 `.xlsx` 格式模板 |
|
||||
| 样式应用 | 提取式而非复制式,部分高级格式可能丢失 |
|
||||
|
||||
其他限制同 v1.2.0。
|
||||
|
||||
---
|
||||
|
||||
### 升级指南
|
||||
|
||||
**从 v1.3.x / v1.2.0 升级**:替换 `Code/src/` 目录下所有文件。模板文件需手动放置:
|
||||
- MAP→List 方向:在项目根目录放置 `BallList-Template.xlsx`
|
||||
- List→MAP 方向:在项目根目录放置 `BallMAP-Template.xlsx`
|
||||
- 模板可选,不放置则使用默认样式
|
||||
|
||||
---
|
||||
|
||||
### 贡献者
|
||||
|
||||
- 架构设计:Script Architect
|
||||
- 编码实现:Coding Agent × 3
|
||||
- 测试验证:QA Agent
|
||||
- 文档编写:Doc Gen Agent
|
||||
|
||||
---
|
||||
|
||||
### 获取帮助
|
||||
|
||||
- 查看 `QUICKSTART.md` 了解使用方法
|
||||
- 查看 `README.md` 了解完整说明
|
||||
- 查看 `architecture-design.md` 了解技术细节
|
||||
- 查看 `CHANGELOG.md` 了解变更历史
|
||||
- 查看 `Test/test_report.md` 了解测试详情
|
||||
|
||||
---
|
||||
|
||||
## v1.2.0 — 2026-05-28
|
||||
|
||||
### ✨ 新增 PinList → PinMAP 反向转换
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
- ✅ GUI 文件选择 + 命令行双模式
|
||||
- ✅ 智能结构验证(重复/间隙/空单元格检测)
|
||||
- ✅ 逆时针 PinMAP → 顺时针 PinList 自动转换
|
||||
- ✅ 双向转换:MAP→List 与 List→MAP
|
||||
- ✅ **独立模板**:MAP→List 使用 `BallList-Template.xlsx`,List→MAP 使用 `BallMAP-Template.xlsx`
|
||||
- ✅ **模板格式提取**:从模板读取字体、边框、填充、对齐、列宽、行高并应用到输出
|
||||
|
||||
## 快速开始
|
||||
|
||||
@@ -30,9 +33,11 @@ pinmap-to-pinlist/
|
||||
│ ├── src/ # 源代码
|
||||
│ └── docs/ # 架构文档
|
||||
├── Test/
|
||||
│ ├── fixtures/ # 测试夹具
|
||||
│ ├── fixtures/ # 测试夹具(含模板文件)
|
||||
│ └── test_report.md # 测试报告
|
||||
├── Releases/ # 发布包
|
||||
├── BallList-Template.xlsx # MAP→List 样式模板(可放置于项目根目录)
|
||||
├── BallMAP-Template.xlsx # List→MAP 样式模板(可放置于项目根目录)
|
||||
├── CHANGELOG.md
|
||||
└── README.md
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user