excel2ppt-studio 0.7.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. excel2ppt_studio-0.7.1/LICENSE +21 -0
  2. excel2ppt_studio-0.7.1/PKG-INFO +251 -0
  3. excel2ppt_studio-0.7.1/README.md +213 -0
  4. excel2ppt_studio-0.7.1/pyproject.toml +65 -0
  5. excel2ppt_studio-0.7.1/setup.cfg +4 -0
  6. excel2ppt_studio-0.7.1/src/excel2ppt_studio/__init__.py +3 -0
  7. excel2ppt_studio-0.7.1/src/excel2ppt_studio/__main__.py +3 -0
  8. excel2ppt_studio-0.7.1/src/excel2ppt_studio/cli.py +312 -0
  9. excel2ppt_studio-0.7.1/src/excel2ppt_studio/core/__init__.py +1 -0
  10. excel2ppt_studio-0.7.1/src/excel2ppt_studio/core/excel_images.py +85 -0
  11. excel2ppt_studio-0.7.1/src/excel2ppt_studio/core/excel_reader.py +256 -0
  12. excel2ppt_studio-0.7.1/src/excel2ppt_studio/core/mapping.py +176 -0
  13. excel2ppt_studio-0.7.1/src/excel2ppt_studio/core/model.py +204 -0
  14. excel2ppt_studio-0.7.1/src/excel2ppt_studio/core/preview.py +128 -0
  15. excel2ppt_studio-0.7.1/src/excel2ppt_studio/core/preview_worker.py +78 -0
  16. excel2ppt_studio-0.7.1/src/excel2ppt_studio/core/renderer.py +806 -0
  17. excel2ppt_studio-0.7.1/src/excel2ppt_studio/core/slot_detect.py +151 -0
  18. excel2ppt_studio-0.7.1/src/excel2ppt_studio/core/template_health.py +230 -0
  19. excel2ppt_studio-0.7.1/src/excel2ppt_studio/core/template_scanner.py +483 -0
  20. excel2ppt_studio-0.7.1/src/excel2ppt_studio/core/text_fit.py +60 -0
  21. excel2ppt_studio-0.7.1/src/excel2ppt_studio/core/titles.py +112 -0
  22. excel2ppt_studio-0.7.1/src/excel2ppt_studio/core/verifier.py +301 -0
  23. excel2ppt_studio-0.7.1/src/excel2ppt_studio/web/__init__.py +1 -0
  24. excel2ppt_studio-0.7.1/src/excel2ppt_studio/web/app.py +621 -0
  25. excel2ppt_studio-0.7.1/src/excel2ppt_studio/web/static/app.js +1064 -0
  26. excel2ppt_studio-0.7.1/src/excel2ppt_studio/web/static/index.html +250 -0
  27. excel2ppt_studio-0.7.1/src/excel2ppt_studio/web/static/style.css +612 -0
  28. excel2ppt_studio-0.7.1/src/excel2ppt_studio.egg-info/PKG-INFO +251 -0
  29. excel2ppt_studio-0.7.1/src/excel2ppt_studio.egg-info/SOURCES.txt +41 -0
  30. excel2ppt_studio-0.7.1/src/excel2ppt_studio.egg-info/dependency_links.txt +1 -0
  31. excel2ppt_studio-0.7.1/src/excel2ppt_studio.egg-info/entry_points.txt +2 -0
  32. excel2ppt_studio-0.7.1/src/excel2ppt_studio.egg-info/requires.txt +19 -0
  33. excel2ppt_studio-0.7.1/src/excel2ppt_studio.egg-info/top_level.txt +1 -0
  34. excel2ppt_studio-0.7.1/tests/test_chart.py +87 -0
  35. excel2ppt_studio-0.7.1/tests/test_cli.py +36 -0
  36. excel2ppt_studio-0.7.1/tests/test_excel_reader.py +118 -0
  37. excel2ppt_studio-0.7.1/tests/test_health.py +44 -0
  38. excel2ppt_studio-0.7.1/tests/test_mapping.py +69 -0
  39. excel2ppt_studio-0.7.1/tests/test_renderer.py +578 -0
  40. excel2ppt_studio-0.7.1/tests/test_scanner.py +140 -0
  41. excel2ppt_studio-0.7.1/tests/test_text_fit.py +47 -0
  42. excel2ppt_studio-0.7.1/tests/test_verifier.py +106 -0
  43. excel2ppt_studio-0.7.1/tests/test_web.py +269 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 一片风干叶
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,251 @@
1
+ Metadata-Version: 2.4
2
+ Name: excel2ppt-studio
3
+ Version: 0.7.1
4
+ Summary: 把 Excel 台账按单页 PPT 模板逐行生成多页幻灯片:克隆母版页、只换内容,排版/颜色/字体/位置零漂移。
5
+ Author-email: 一片风干叶 <104623890@qq.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/grh-cb/excel2ppt-studio
8
+ Project-URL: Issues, https://github.com/grh-cb/excel2ppt-studio/issues
9
+ Keywords: excel,powerpoint,pptx,template,report,automation,ooxml
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Environment :: Win32 (MS Windows)
12
+ Classifier: Intended Audience :: End Users/Desktop
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Topic :: Office/Business :: Office Suites
20
+ Requires-Python: >=3.10
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ Requires-Dist: python-pptx>=1.0
24
+ Requires-Dist: openpyxl>=3.1
25
+ Requires-Dist: lxml>=4.9
26
+ Requires-Dist: Pillow>=10
27
+ Provides-Extra: web
28
+ Requires-Dist: fastapi>=0.110; extra == "web"
29
+ Requires-Dist: uvicorn[standard]>=0.29; extra == "web"
30
+ Requires-Dist: python-multipart>=0.0.9; extra == "web"
31
+ Provides-Extra: preview
32
+ Requires-Dist: pywin32>=306; sys_platform == "win32" and extra == "preview"
33
+ Provides-Extra: dev
34
+ Requires-Dist: pytest>=8; extra == "dev"
35
+ Requires-Dist: pytest-cov>=5; extra == "dev"
36
+ Requires-Dist: ruff>=0.4; extra == "dev"
37
+ Dynamic: license-file
38
+
39
+ # Excel2PPT Studio
40
+
41
+ > 把 Excel 台账按「单页 PPT 模板」逐行生成多页幻灯片——**克隆母版页,只换内容**,排版、颜色、字体、位置零漂移。
42
+
43
+ [![Python](https://img.shields.io/badge/python-3.10%2B-3776AB)](https://www.python.org/)
44
+ [![License](https://img.shields.io/badge/license-MIT-green)](LICENSE)
45
+ [![Tests](https://img.shields.io/badge/tests-pytest-informational)](tests/)
46
+
47
+ ---
48
+
49
+ ## 为什么不是又一个「Excel 转 PPT」工具
50
+
51
+ 大多数工具的做法是**新建**元素:读数据 → 创建文本框 → 设坐标 → 设字体。模板一换,坐标常量就失效;元素一多,版式就散。
52
+
53
+ 本工具反其道而行:**把模板页整页克隆,再在克隆页里只替换文本节点**。格式属性(`a:rPr`)、段落属性(`a:pPr`)、位置(`a:xfrm`)、表格样式(`a:tcPr`)从头到尾没有被写入过——**不是"尽量保留",是结构上不可能被改坏**。
54
+
55
+ | 维度 | 传统生成器 | Excel2PPT Studio |
56
+ |---|---|---|
57
+ | 元素来源 | 代码新建 | 模板页 XML 深拷贝 |
58
+ | 坐标 | 硬编码常量 | 原样继承 |
59
+ | 换模板 | 改代码 | 改映射(零代码) |
60
+ | 字体/颜色 | 代码指定 | 继承模板,零改动 |
61
+ | 图片 | 重新摆放 | 换 media 字节,保留裁剪/效果 |
62
+ | 校验 | 肉眼看 | 格式指纹逐 shape 比对 |
63
+
64
+ ---
65
+
66
+ ## 核心特性
67
+
68
+ | 能力 | 状态 |
69
+ |---|---|
70
+ | 模板元素自动提取与分类(文本/表格/图片/图表/组合) | ✅ v0.1 |
71
+ | 绝对坐标换算(含组合形状 `chOff/chExt`) | ✅ v0.1 |
72
+ | 槽位探测(`{{x}}` / `${x}` / 命名形状 / 替代文字) | ✅ v0.1 |
73
+ | 零漂移克隆渲染(文本·表格·图片) | ✅ v0.1 |
74
+ | Excel 表头校验、类型推断、WPS 内嵌图片提取 | ✅ v0.1 |
75
+ | 映射 Profile 存取与自动建议 | ✅ v0.1 |
76
+ | CLI:`inspect` / `suggest` / `build` / `web` | ✅ v0.1 |
77
+ | 可视化四步向导(画布 + 映射表 + 数据预览 + Profile 导入导出) | ✅ v0.2 |
78
+ | 就地映射:点画布元素直接选列(浮层 + 详情联动) | ✅ v0.5 |
79
+ | 段落级槽位:无占位符模板也能按段映射 | ✅ v0.5.1 |
80
+ | 真实预览:按页渲染 WPS 缩略图,翻页/切分页/缓存 | ✅ v0.5 |
81
+ | AI 短标题(`e2p titles` + `value_map` 覆盖) | ✅ v0.6 |
82
+ | 页码 / 总页数 / 生成日期变量 | ✅ v0.6 |
83
+ | 便携版:双击 exe 即用,目标机无需 Python | ✅ v0.6 |
84
+ | 格式指纹校验(逐 shape 比对,把零漂移变成断言) | ✅ v0.3 |
85
+ | WPS / PowerPoint 真实渲染预览(子进程隔离,失败降级) | ✅ v0.3 |
86
+ | 文本溢出估算与告警(只告警不改字号) | ✅ v0.3 |
87
+ | 图表数据绑定(保留类型/配色/坐标轴,同步内嵌工作簿) | ✅ v0.4 |
88
+ | 分页:每行一页 / 每 N 行一页 | ✅ v0.4 |
89
+ | DSH(DeepSeek Harness)插件:3 个模型工具 + 界面入口 | ✅ v0.4 |
90
+ | 打包 exe / pip 发布 | 🚧 M5 |
91
+ | DSH(DeepSeek Harness)插件封装 | 🚧 M4 |
92
+ | 打包 exe / pip 发布 | 🚧 M5 |
93
+
94
+ > 首版明确取舍:超长文本**只告警不改**(严格保真),字号缩放需显式开启。
95
+
96
+ ### 实测效果
97
+
98
+ 模板页(`{{...}}` 占位)克隆后逐行替换,字体、颜色、表格底纹、图片位置全部原样:
99
+
100
+ ![克隆页实测:仅文本变化,格式零漂移](docs/adr/assets/clone-demo.png)
101
+
102
+ ---
103
+
104
+ ## 快速开始
105
+
106
+ ```powershell
107
+ # 开发安装(Web 界面需要 web 可选依赖)
108
+ cd excel2ppt-studio
109
+ python -m pip install -e ".[dev,web]"
110
+
111
+ # 生成示例模板与数据(3 行台账 + 单页模板)
112
+ python examples/make_sample.py
113
+
114
+ # 图形界面:启动后自动打开浏览器
115
+ e2p web
116
+
117
+ # 或纯命令行:
118
+ e2p inspect "模板.pptx" --slide 1
119
+ e2p suggest --excel "台账.xlsx" --template "模板.pptx" --out profile.json
120
+ e2p build --excel "台账.xlsx" --template "模板.pptx" --profile profile.json --out "汇报.pptx"
121
+ ```
122
+
123
+ ### 界面
124
+
125
+ 四步向导:**选文件 → 认元素 → 连映射 → 生成**。
126
+
127
+ **认元素(就地映射)**:点画布元素弹出列下拉,选完立刻显示在框上。
128
+
129
+ | 画布与详情 | 就地浮层 |
130
+ |---|---|
131
+ | ![元素与映射](docs/assets/ui-step2.png) | ![画布浮层](docs/assets/ui-step2-popover.png) |
132
+
133
+ **预览**:按页渲染 WPS 真实缩略图,可翻页、切分页、看映射摘要。
134
+
135
+ ![预览页](docs/assets/ui-step3.png)
136
+
137
+ 生成后可一键「校验零漂移」与「预览第 1 页」:
138
+
139
+ ![生成、校验与预览](docs/assets/ui-step4.png)
140
+
141
+ - 点画布元素(或左侧清单)→ 右侧详情与浮层都能直接选列;已映射元素实线并显示 `→ 列名`。
142
+ - 表格按表头逐列映射;图片可选 contain / cover / stretch;图表分别选类目列与数值列。
143
+ - 预览按「页」渲染,与最终出片一致;无 WPS 时降级为几何预览并提示。
144
+ - Profile 可导出为 JSON,下次一键导入复用(也自动存浏览器本地)。
145
+ - 校验会逐 shape 比对位置、尺寸、字体签名,并列出残留占位符。
146
+
147
+ ### 作为 DSH 插件
148
+
149
+ 仓库内 `dsh-plugin/` 是一个 DeepSeek Harness bundle:
150
+
151
+ ```text
152
+ plugin_manager install_bundle target=<仓库绝对路径>\dsh-plugin
153
+ ```
154
+
155
+ 安装后:
156
+
157
+ | 形态 | 内容 |
158
+ |---|---|
159
+ | Host 工具 | `excel2ppt_build`(按 Profile 生成)、`excel2ppt_inspect`(看模板元素)、`excel2ppt_verify`(零漂移校验) |
160
+ | Client 入口 | 输入框下方 `Excel2PPT` 按钮,打开本地 Studio |
161
+
162
+ 配置项:`pythonPath`(解释器路径)、`studioUrl`、`timeoutMs`,见 [dsh-plugin/README.md](dsh-plugin/README.md)。
163
+
164
+ ---
165
+
166
+ ## CLI
167
+
168
+ | 命令 | 作用 |
169
+ |---|---|
170
+ | `e2p inspect <template> [--slide N] [--json out.json]` | 输出模板元素清单:类型、角色、坐标(EMU/cm)、文本、槽位 |
171
+ | `e2p suggest --excel <xlsx> --template <pptx> [--out profile.json]` | 按「列名 ↔ 槽位名」相似度生成初始映射 |
172
+ | `e2p build --excel <xlsx> --template <pptx> --profile <json> --out <pptx>` | 逐行克隆生成,失败中文单行报错、非零退出 |
173
+ | `e2p web [--port 8765] [--no-browser]` | 启动本地四步向导 |
174
+ | `e2p verify --template <pptx> --output <pptx>` | 逐页比对模板与输出,报告位置/尺寸/字体差异 |
175
+
176
+ 退出码:`0` 成功;`1` 业务失败(信息可读);`2` 参数错误。
177
+
178
+ ---
179
+
180
+ ## 保真原理(技术)
181
+
182
+ 1. **部件树深拷贝**:`SlidePart` 的 XML、图片、图表、内嵌工作簿按关系树递归复制,各自的 `rId` 重新映射。
183
+ 2. **只改 `<a:t>`**:文本节点的兄弟属性(`a:rPr` 字号/加粗/颜色/字体、`a:pPr` 对齐/缩进、`a:bodyPr` 内边距)一律不写。
184
+ 3. **三种替换粒度**:run 内子串(默认,最保真)→ 段落整体 → shape 整体(显式选择,会重置格式)。
185
+ 4. **布局关系复用**:克隆页共享同一 `slideLayout`,模板改版式时全部生成页自动跟随。
186
+ 5. **格式指纹校验**(M3):归一化 XML(抹掉文本、rId、shape id)后与模板页逐 shape 同构比对,可机检。
187
+
188
+ 详见 [ADR-0001](docs/adr/0001-clone-preserving-render.md) 与 [架构说明](docs/ARCHITECTURE.md)。
189
+
190
+ ---
191
+
192
+ ## 项目结构
193
+
194
+ ```
195
+ src/excel2ppt_studio/
196
+ core/
197
+ model.py # Field / Slot / Binding / Profile 数据模型
198
+ slot_detect.py # 槽位探测规则
199
+ template_scanner.py # 模板 → Field 列表
200
+ excel_reader.py # 表头校验 / 类型推断
201
+ excel_images.py # WPS DISPIMG 图片提取
202
+ mapping.py # 自动建议 + Profile 存取
203
+ renderer.py # 克隆 + 分页 + 后处理
204
+ verifier.py # 格式指纹校验
205
+ preview.py # WPS COM 预览(子进程隔离)
206
+ text_fit.py # 文本溢出估算
207
+ web/ # FastAPI 服务 + 四步向导(static/ 原生 HTML/CSS/JS)
208
+ cli.py
209
+ examples/ # 示例模板/数据生成脚本
210
+ packaging/ # PyInstaller 打包
211
+ dsh-plugin/ # DeepSeek Harness 插件(Host 工具 + Client 入口)
212
+ tests/ # pytest:fixtures 程序化生成,无二进制依赖
213
+ docs/ # 架构、ADR、实施计划、发布指南
214
+ ```
215
+
216
+ ---
217
+
218
+ ## 兼容性
219
+
220
+ | 项 | 说明 |
221
+ |---|---|
222
+ | Python | 3.10+(开发环境 3.13.2 实测) |
223
+ | 模板 | `.pptx`(OOXML);建议 16:9,单页母版;多页模板需指定 `--slide` |
224
+ | 数据 | `.xlsx` / `.xlsm`;首行必须为表头 |
225
+ | 图片 | WPS「嵌入单元格」图片(DISPIMG)、本地路径、URL(需联网) |
226
+ | 办公软件 | WPS Office / Microsoft PowerPoint(预览能力依赖 WPS COM,可降级) |
227
+
228
+ ---
229
+
230
+ ## 路线图
231
+
232
+ | 里程碑 | 内容 | 状态 |
233
+ |---|---|---|
234
+ | M0 | 骨架 + 模板扫描器 + Excel 读取 + CLI 占位 | ✅ 已完成 |
235
+ | M1 | 克隆引擎 + 文本/表格/图片替换 + pytest | ✅ 已完成 |
236
+ | M2 | Web GUI 四步向导 + 画布映射 + Profile | ✅ 已完成 |
237
+ | M3 | WPS 预览 + 格式指纹 + 溢出告警 | ✅ 已完成 |
238
+ | M4 | 图表绑定 + 分页 + DSH 插件封装 | ✅ 已完成 |
239
+ | M5 | 打包、文档、发布准备 | ✅ 已完成 |
240
+
241
+ 详见 [docs/PLAN.md](docs/PLAN.md) 与 [docs/PUBLISHING.md](docs/PUBLISHING.md)(发布清单、GitHub/PyPI/exe 步骤)。
242
+
243
+ ---
244
+
245
+ ## 贡献
246
+
247
+ 见 [CONTRIBUTING.md](CONTRIBUTING.md)。提交前请确保 `pytest` 与 `ruff check` 通过。
248
+
249
+ ## 许可证
250
+
251
+ [MIT](LICENSE) © 2026 一片风干叶
@@ -0,0 +1,213 @@
1
+ # Excel2PPT Studio
2
+
3
+ > 把 Excel 台账按「单页 PPT 模板」逐行生成多页幻灯片——**克隆母版页,只换内容**,排版、颜色、字体、位置零漂移。
4
+
5
+ [![Python](https://img.shields.io/badge/python-3.10%2B-3776AB)](https://www.python.org/)
6
+ [![License](https://img.shields.io/badge/license-MIT-green)](LICENSE)
7
+ [![Tests](https://img.shields.io/badge/tests-pytest-informational)](tests/)
8
+
9
+ ---
10
+
11
+ ## 为什么不是又一个「Excel 转 PPT」工具
12
+
13
+ 大多数工具的做法是**新建**元素:读数据 → 创建文本框 → 设坐标 → 设字体。模板一换,坐标常量就失效;元素一多,版式就散。
14
+
15
+ 本工具反其道而行:**把模板页整页克隆,再在克隆页里只替换文本节点**。格式属性(`a:rPr`)、段落属性(`a:pPr`)、位置(`a:xfrm`)、表格样式(`a:tcPr`)从头到尾没有被写入过——**不是"尽量保留",是结构上不可能被改坏**。
16
+
17
+ | 维度 | 传统生成器 | Excel2PPT Studio |
18
+ |---|---|---|
19
+ | 元素来源 | 代码新建 | 模板页 XML 深拷贝 |
20
+ | 坐标 | 硬编码常量 | 原样继承 |
21
+ | 换模板 | 改代码 | 改映射(零代码) |
22
+ | 字体/颜色 | 代码指定 | 继承模板,零改动 |
23
+ | 图片 | 重新摆放 | 换 media 字节,保留裁剪/效果 |
24
+ | 校验 | 肉眼看 | 格式指纹逐 shape 比对 |
25
+
26
+ ---
27
+
28
+ ## 核心特性
29
+
30
+ | 能力 | 状态 |
31
+ |---|---|
32
+ | 模板元素自动提取与分类(文本/表格/图片/图表/组合) | ✅ v0.1 |
33
+ | 绝对坐标换算(含组合形状 `chOff/chExt`) | ✅ v0.1 |
34
+ | 槽位探测(`{{x}}` / `${x}` / 命名形状 / 替代文字) | ✅ v0.1 |
35
+ | 零漂移克隆渲染(文本·表格·图片) | ✅ v0.1 |
36
+ | Excel 表头校验、类型推断、WPS 内嵌图片提取 | ✅ v0.1 |
37
+ | 映射 Profile 存取与自动建议 | ✅ v0.1 |
38
+ | CLI:`inspect` / `suggest` / `build` / `web` | ✅ v0.1 |
39
+ | 可视化四步向导(画布 + 映射表 + 数据预览 + Profile 导入导出) | ✅ v0.2 |
40
+ | 就地映射:点画布元素直接选列(浮层 + 详情联动) | ✅ v0.5 |
41
+ | 段落级槽位:无占位符模板也能按段映射 | ✅ v0.5.1 |
42
+ | 真实预览:按页渲染 WPS 缩略图,翻页/切分页/缓存 | ✅ v0.5 |
43
+ | AI 短标题(`e2p titles` + `value_map` 覆盖) | ✅ v0.6 |
44
+ | 页码 / 总页数 / 生成日期变量 | ✅ v0.6 |
45
+ | 便携版:双击 exe 即用,目标机无需 Python | ✅ v0.6 |
46
+ | 格式指纹校验(逐 shape 比对,把零漂移变成断言) | ✅ v0.3 |
47
+ | WPS / PowerPoint 真实渲染预览(子进程隔离,失败降级) | ✅ v0.3 |
48
+ | 文本溢出估算与告警(只告警不改字号) | ✅ v0.3 |
49
+ | 图表数据绑定(保留类型/配色/坐标轴,同步内嵌工作簿) | ✅ v0.4 |
50
+ | 分页:每行一页 / 每 N 行一页 | ✅ v0.4 |
51
+ | DSH(DeepSeek Harness)插件:3 个模型工具 + 界面入口 | ✅ v0.4 |
52
+ | 打包 exe / pip 发布 | 🚧 M5 |
53
+ | DSH(DeepSeek Harness)插件封装 | 🚧 M4 |
54
+ | 打包 exe / pip 发布 | 🚧 M5 |
55
+
56
+ > 首版明确取舍:超长文本**只告警不改**(严格保真),字号缩放需显式开启。
57
+
58
+ ### 实测效果
59
+
60
+ 模板页(`{{...}}` 占位)克隆后逐行替换,字体、颜色、表格底纹、图片位置全部原样:
61
+
62
+ ![克隆页实测:仅文本变化,格式零漂移](docs/adr/assets/clone-demo.png)
63
+
64
+ ---
65
+
66
+ ## 快速开始
67
+
68
+ ```powershell
69
+ # 开发安装(Web 界面需要 web 可选依赖)
70
+ cd excel2ppt-studio
71
+ python -m pip install -e ".[dev,web]"
72
+
73
+ # 生成示例模板与数据(3 行台账 + 单页模板)
74
+ python examples/make_sample.py
75
+
76
+ # 图形界面:启动后自动打开浏览器
77
+ e2p web
78
+
79
+ # 或纯命令行:
80
+ e2p inspect "模板.pptx" --slide 1
81
+ e2p suggest --excel "台账.xlsx" --template "模板.pptx" --out profile.json
82
+ e2p build --excel "台账.xlsx" --template "模板.pptx" --profile profile.json --out "汇报.pptx"
83
+ ```
84
+
85
+ ### 界面
86
+
87
+ 四步向导:**选文件 → 认元素 → 连映射 → 生成**。
88
+
89
+ **认元素(就地映射)**:点画布元素弹出列下拉,选完立刻显示在框上。
90
+
91
+ | 画布与详情 | 就地浮层 |
92
+ |---|---|
93
+ | ![元素与映射](docs/assets/ui-step2.png) | ![画布浮层](docs/assets/ui-step2-popover.png) |
94
+
95
+ **预览**:按页渲染 WPS 真实缩略图,可翻页、切分页、看映射摘要。
96
+
97
+ ![预览页](docs/assets/ui-step3.png)
98
+
99
+ 生成后可一键「校验零漂移」与「预览第 1 页」:
100
+
101
+ ![生成、校验与预览](docs/assets/ui-step4.png)
102
+
103
+ - 点画布元素(或左侧清单)→ 右侧详情与浮层都能直接选列;已映射元素实线并显示 `→ 列名`。
104
+ - 表格按表头逐列映射;图片可选 contain / cover / stretch;图表分别选类目列与数值列。
105
+ - 预览按「页」渲染,与最终出片一致;无 WPS 时降级为几何预览并提示。
106
+ - Profile 可导出为 JSON,下次一键导入复用(也自动存浏览器本地)。
107
+ - 校验会逐 shape 比对位置、尺寸、字体签名,并列出残留占位符。
108
+
109
+ ### 作为 DSH 插件
110
+
111
+ 仓库内 `dsh-plugin/` 是一个 DeepSeek Harness bundle:
112
+
113
+ ```text
114
+ plugin_manager install_bundle target=<仓库绝对路径>\dsh-plugin
115
+ ```
116
+
117
+ 安装后:
118
+
119
+ | 形态 | 内容 |
120
+ |---|---|
121
+ | Host 工具 | `excel2ppt_build`(按 Profile 生成)、`excel2ppt_inspect`(看模板元素)、`excel2ppt_verify`(零漂移校验) |
122
+ | Client 入口 | 输入框下方 `Excel2PPT` 按钮,打开本地 Studio |
123
+
124
+ 配置项:`pythonPath`(解释器路径)、`studioUrl`、`timeoutMs`,见 [dsh-plugin/README.md](dsh-plugin/README.md)。
125
+
126
+ ---
127
+
128
+ ## CLI
129
+
130
+ | 命令 | 作用 |
131
+ |---|---|
132
+ | `e2p inspect <template> [--slide N] [--json out.json]` | 输出模板元素清单:类型、角色、坐标(EMU/cm)、文本、槽位 |
133
+ | `e2p suggest --excel <xlsx> --template <pptx> [--out profile.json]` | 按「列名 ↔ 槽位名」相似度生成初始映射 |
134
+ | `e2p build --excel <xlsx> --template <pptx> --profile <json> --out <pptx>` | 逐行克隆生成,失败中文单行报错、非零退出 |
135
+ | `e2p web [--port 8765] [--no-browser]` | 启动本地四步向导 |
136
+ | `e2p verify --template <pptx> --output <pptx>` | 逐页比对模板与输出,报告位置/尺寸/字体差异 |
137
+
138
+ 退出码:`0` 成功;`1` 业务失败(信息可读);`2` 参数错误。
139
+
140
+ ---
141
+
142
+ ## 保真原理(技术)
143
+
144
+ 1. **部件树深拷贝**:`SlidePart` 的 XML、图片、图表、内嵌工作簿按关系树递归复制,各自的 `rId` 重新映射。
145
+ 2. **只改 `<a:t>`**:文本节点的兄弟属性(`a:rPr` 字号/加粗/颜色/字体、`a:pPr` 对齐/缩进、`a:bodyPr` 内边距)一律不写。
146
+ 3. **三种替换粒度**:run 内子串(默认,最保真)→ 段落整体 → shape 整体(显式选择,会重置格式)。
147
+ 4. **布局关系复用**:克隆页共享同一 `slideLayout`,模板改版式时全部生成页自动跟随。
148
+ 5. **格式指纹校验**(M3):归一化 XML(抹掉文本、rId、shape id)后与模板页逐 shape 同构比对,可机检。
149
+
150
+ 详见 [ADR-0001](docs/adr/0001-clone-preserving-render.md) 与 [架构说明](docs/ARCHITECTURE.md)。
151
+
152
+ ---
153
+
154
+ ## 项目结构
155
+
156
+ ```
157
+ src/excel2ppt_studio/
158
+ core/
159
+ model.py # Field / Slot / Binding / Profile 数据模型
160
+ slot_detect.py # 槽位探测规则
161
+ template_scanner.py # 模板 → Field 列表
162
+ excel_reader.py # 表头校验 / 类型推断
163
+ excel_images.py # WPS DISPIMG 图片提取
164
+ mapping.py # 自动建议 + Profile 存取
165
+ renderer.py # 克隆 + 分页 + 后处理
166
+ verifier.py # 格式指纹校验
167
+ preview.py # WPS COM 预览(子进程隔离)
168
+ text_fit.py # 文本溢出估算
169
+ web/ # FastAPI 服务 + 四步向导(static/ 原生 HTML/CSS/JS)
170
+ cli.py
171
+ examples/ # 示例模板/数据生成脚本
172
+ packaging/ # PyInstaller 打包
173
+ dsh-plugin/ # DeepSeek Harness 插件(Host 工具 + Client 入口)
174
+ tests/ # pytest:fixtures 程序化生成,无二进制依赖
175
+ docs/ # 架构、ADR、实施计划、发布指南
176
+ ```
177
+
178
+ ---
179
+
180
+ ## 兼容性
181
+
182
+ | 项 | 说明 |
183
+ |---|---|
184
+ | Python | 3.10+(开发环境 3.13.2 实测) |
185
+ | 模板 | `.pptx`(OOXML);建议 16:9,单页母版;多页模板需指定 `--slide` |
186
+ | 数据 | `.xlsx` / `.xlsm`;首行必须为表头 |
187
+ | 图片 | WPS「嵌入单元格」图片(DISPIMG)、本地路径、URL(需联网) |
188
+ | 办公软件 | WPS Office / Microsoft PowerPoint(预览能力依赖 WPS COM,可降级) |
189
+
190
+ ---
191
+
192
+ ## 路线图
193
+
194
+ | 里程碑 | 内容 | 状态 |
195
+ |---|---|---|
196
+ | M0 | 骨架 + 模板扫描器 + Excel 读取 + CLI 占位 | ✅ 已完成 |
197
+ | M1 | 克隆引擎 + 文本/表格/图片替换 + pytest | ✅ 已完成 |
198
+ | M2 | Web GUI 四步向导 + 画布映射 + Profile | ✅ 已完成 |
199
+ | M3 | WPS 预览 + 格式指纹 + 溢出告警 | ✅ 已完成 |
200
+ | M4 | 图表绑定 + 分页 + DSH 插件封装 | ✅ 已完成 |
201
+ | M5 | 打包、文档、发布准备 | ✅ 已完成 |
202
+
203
+ 详见 [docs/PLAN.md](docs/PLAN.md) 与 [docs/PUBLISHING.md](docs/PUBLISHING.md)(发布清单、GitHub/PyPI/exe 步骤)。
204
+
205
+ ---
206
+
207
+ ## 贡献
208
+
209
+ 见 [CONTRIBUTING.md](CONTRIBUTING.md)。提交前请确保 `pytest` 与 `ruff check` 通过。
210
+
211
+ ## 许可证
212
+
213
+ [MIT](LICENSE) © 2026 一片风干叶
@@ -0,0 +1,65 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "excel2ppt-studio"
7
+ version = "0.7.1"
8
+ description = "把 Excel 台账按单页 PPT 模板逐行生成多页幻灯片:克隆母版页、只换内容,排版/颜色/字体/位置零漂移。"
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = "MIT"
12
+ license-files = ["LICENSE"]
13
+ authors = [{ name = "一片风干叶", email = "104623890@qq.com" }]
14
+ keywords = ["excel", "powerpoint", "pptx", "template", "report", "automation", "ooxml"]
15
+ classifiers = [
16
+ "Development Status :: 3 - Alpha",
17
+ "Environment :: Win32 (MS Windows)",
18
+ "Intended Audience :: End Users/Desktop",
19
+ "Operating System :: OS Independent",
20
+ "Programming Language :: Python :: 3",
21
+ "Programming Language :: Python :: 3.10",
22
+ "Programming Language :: Python :: 3.11",
23
+ "Programming Language :: Python :: 3.12",
24
+ "Programming Language :: Python :: 3.13",
25
+ "Topic :: Office/Business :: Office Suites",
26
+ ]
27
+ dependencies = [
28
+ "python-pptx>=1.0",
29
+ "openpyxl>=3.1",
30
+ "lxml>=4.9",
31
+ "Pillow>=10",
32
+ ]
33
+
34
+ [project.optional-dependencies]
35
+ web = ["fastapi>=0.110", "uvicorn[standard]>=0.29", "python-multipart>=0.0.9"]
36
+ preview = ["pywin32>=306; sys_platform == 'win32'"]
37
+ dev = ["pytest>=8", "pytest-cov>=5", "ruff>=0.4"]
38
+
39
+ [project.scripts]
40
+ e2p = "excel2ppt_studio.cli:main"
41
+
42
+ [project.urls]
43
+ Homepage = "https://github.com/grh-cb/excel2ppt-studio"
44
+ Issues = "https://github.com/grh-cb/excel2ppt-studio/issues"
45
+
46
+ [tool.setuptools.packages.find]
47
+ where = ["src"]
48
+
49
+ [tool.setuptools.package-data]
50
+ excel2ppt_studio = ["web/static/*"]
51
+
52
+ [tool.pytest.ini_options]
53
+ testpaths = ["tests"]
54
+ addopts = "-q"
55
+
56
+ [tool.ruff]
57
+ line-length = 100
58
+ target-version = "py310"
59
+
60
+ [tool.ruff.lint]
61
+ select = ["E", "F", "I", "UP", "B"]
62
+ ignore = ["E501", "B008"]
63
+
64
+ [tool.coverage.run]
65
+ source = ["excel2ppt_studio"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,3 @@
1
+ """Excel2PPT Studio 核心包。"""
2
+
3
+ __version__ = "0.7.1"
@@ -0,0 +1,3 @@
1
+ from excel2ppt_studio.cli import main
2
+
3
+ raise SystemExit(main())