# 🐍 B25｜用 Python + openpyxl 批量处理 Excel — 配套资产

> **系列**：AI 办公实战：从小白到达人
> **文章号**：B25（Track 7 办公开发 / Level 1 入门）
> **配套中文标题**：用 Python + openpyxl 批量处理 Excel
> **配套英文标题**：Batch-Process Excel with Python + openpyxl

---

## 一、这是给谁的？解决什么问题？

写给**月底要给 30 张销售表都改同一个表头、补一个"负责人"列、或者重算"完成率"**的朋友：每张表都打开、手填、保存，复制粘贴到手酸。

主教程教你**装好 Python + 第一个 openpyxl 脚本怎么跑**；本目录提供**真实可运行的最小完整流水线**：

| 文件 | 干什么 |
|------|--------|
| `数据源_sample.csv` | 6 行示例数据（部门、负责人、四季度销售额等） |
| `生成示例文件_zh.py` | 一键把上面 CSV 变成测试 Excel |
| `批量处理Excel_zh.py` | 核心脚本：读 Excel → 算合计 → 重排 → 写新表 → 美化样式 |
| `requirements.txt` | 依赖清单（就一行：`openpyxl>=3.0.0`） |

跑通本目录，你手里就有了一份"读 Excel → 处理数据 → 写新 Excel"的脚本模板——以后换自己的活儿（重命名 sheet、加新列、按某列排序、批量改样式），改改数据路径和业务逻辑即可。

---

## 二、使用方法（5 步跑通示例）

### 第一步：装 Python（务必勾 PATH）

1. 浏览器开 `python.org → Downloads`，下载最新版 Windows 安装包（`.exe`）；
2. **双击安装包，第一个界面下方务必勾选 "Add Python to PATH"**，再点 Install Now；
3. 关掉安装窗口。

> 没勾 PATH 怎么办？重跑安装包，选 "Modify"，把 "Add Python to environment variables" 勾上。

### 第二步：验证 Python 可用

按 `Win + R` → 输入 `cmd` → 回车：

```bash
python --version
```

正常输出 `Python 3.x.x` 即成功；提示"不是内部或外部命令"就回到第一步重装。

### 第三步：装 openpyxl

```bash
pip install openpyxl
```

> PATH 没配好 / 装了多版 Python 的同学，改用 **`py -m pip install openpyxl`**——`py` 是安装器默认注册的启动器，`-m` 表示"用这个 python 去跑 pip"，一定不会装错。

### 第四步：进入 B25 目录，生成测试 Excel

```bash
cd "C:\Users\cynix\WorkBuddy\VBA.net\配套资产\B25_批量Excel"
python 生成示例文件_zh.py
```

跑完会生成 `销售业绩表_原始.xlsx`（6 行数据 + 蓝底白字表头）。

### 第五步：跑核心脚本，看结果

```bash
python 批量处理Excel_zh.py
```

跑完会生成 `销售业绩表_已处理.xlsx`（多 2 列：全年合计 / 完成率；多 2 行：合计 + 平均；按全年合计降序；带边框、居中、百分比格式）。**原文件 `销售业绩表_原始.xlsx` 纹丝未动**——这是脚本的第一纪律：**永远另存为新文件**。

---

## 三、文件清单

| 文件名 | 类型 | 作用 | 行数 |
|--------|------|------|------|
| `B25_批量Excel_中文README.md` | Markdown | 本文件 | — |
| `B25_BatchExcel_EnglishREADME.md` | Markdown | 英文版 README | — |
| `批量处理Excel_zh.py` | Python | 核心脚本：读 + 算 + 写新表（中文） | ~140 |
| `批量处理Excel_en.py` | Python | 核心脚本（英文） | ~140 |
| `生成示例文件_zh.py` | Python | 一键生成测试 Excel（中文） | ~80 |
| `生成示例文件_en.py` | Python | 一键生成测试 Excel（英文） | ~80 |
| `数据源_sample.csv` | CSV | 6 行示例数据 | 7 |
| `requirements.txt` | 文本 | 依赖清单：`openpyxl>=3.0.0` | 1 |

---

## 四、实战代码（核心片段逐行解读）

### ① 读 + 写最小骨架

```python
from openpyxl import load_workbook

# 打开已有 .xlsx
wb = load_workbook("销售业绩表_原始.xlsx")
ws = wb.active                       # 取当前工作表

# 读 A1 单元格
print(ws["A1"].value)

# 写 B1 单元格（只是改内存，没存盘）
ws["B1"] = "由 openpyxl 写入"

# 另存为新文件——绝不能原地覆盖
wb.save("销售业绩表_新.xlsx")
```

**四个 API**：`load_workbook` 开旧本；`wb.active` 取当前表；`ws["A1"].value` 读；`ws["A1"] = ...` 写；`wb.save("新文件名")` 另存。

### ② 算合计 + 排序（核心业务逻辑）

```python
processed = []
for row in data_rows:
    dept, mgr, q1, q2, q3, q4, target, _ = row
    nums = [q1 or 0, q2 or 0, q3 or 0, q4 or 0]      # None / 字符串按 0 算
    y_sum = sum(nums)
    rate  = (y_sum / target) if target else 0.0       # 防除 0
    processed.append([dept, mgr, q1, q2, q3, q4, target, y_sum, rate])

# 按"全年合计"（第 8 列）降序排
processed.sort(key=lambda r: r[7], reverse=True)
```

**三个小细节**：① `or 0` 防御空值；② `if target else 0.0` 防除零；③ `sort(..., reverse=True)` 一行搞定排序。

### ③ 加样式（演示用，不是必须）

```python
from openpyxl.styles import Font, PatternFill, Alignment

# 表头：蓝底白字加粗
header_font = Font(bold=True, color="FFFFFF")
header_fill = PatternFill(start_color="4472C4", end_color="4472C4", fill_type="solid")
for col_idx in range(1, len(new_headers) + 1):
    cell = new_ws.cell(row=1, column=col_idx)
    cell.font = header_font
    cell.fill = header_fill
    cell.alignment = Alignment(horizontal="center", vertical="center")

# 给"完成率"列设百分比格式
new_ws.cell(row=row_idx, column=9).number_format = "0.0%"
```

**三种最常用样式**：`Font` 字体、`PatternFill` 填充、`number_format` 数字格式（`#,##0` 千分位 / `0.0%` 百分比）。

---

## 五、常见问题 / 避坑指南

1. **`ModuleNotFoundError: No module named 'openpyxl'`**
   库没装好，或装到了别的 Python 上。最稳：`py -m pip install openpyxl`（用 py 启动器指定当前 python）。

2. **`FileNotFoundError: 'demo.xlsx'`**
   `批量处理Excel_zh.py` 找不到 `销售业绩表_原始.xlsx`。两种办法：① 先跑 `生成示例文件_zh.py`；② 把脚本和数据放同一个目录，并 `cd` 到那个目录再跑。

3. **`BadZipFile: File is not a zip file`**
   你手上是老 `.xls` 文件。openpyxl **不支持 .xls**（本质上是 zip 格式的 .xlsx 才读得了）。先在 Excel 里"另存为 `.xlsx`"再处理。

4. **改完发现原文件被覆盖**
   `wb.save()` 会写你给的路径；只要路径写原名就被覆盖。养成习惯：**永远 save 到新文件名**；原文件只读不写。

5. **中文列名 / 中文数据乱码**
   别用记事本改 `.csv`（默认 ANSI 编码）。用 **VS Code** 或 **Excel 导出**.csv 时选 **UTF-8**；或者直接读 `.xlsx`，openpyxl 对 UTF-8 中文支持最好。

---

## 六、下一步

跑通本文档，你已经能写"读 Excel → 处理 → 写新表"的小流水线。下一步：

- **进阶 B26《用 pandas 做数据分析》**：当你要的不是"改一格"，而是"按条件筛选、分组汇总、跨表合并"时，pandas 比 openpyxl 更顺手；同一系列 T7 办公开发的下一篇。
- **想批量改 100 个文件？** 把本文核心脚本包一层 `for f in glob.glob("*.xlsx")`，就是批量版；或者直接跳到 **B18《AI 写脚本批量处理》**，用 PowerShell + COM object 一次处理几百份。
- **想用 AI 帮你改？** 看主教程 B25 第 6 节"如何用 AI 帮你看懂 / 改写代码"，以及 **A3《提示词入门》**——把代码贴给 ChatGPT，附上"逐行解释 + 改成 X + 列出会报错的场景"，它就能给你改好的版本。

---

> 📌 **快速核查清单**（跑之前再确认一次）：
> - [ ] 装了 Python 且勾了 Add Python to PATH；
> - [ ] `python --version` 能输出版本号；
> - [ ] `pip install openpyxl` 已成功（或者 `py -m pip install openpyxl`）；
> - [ ] `cd` 到 B25 目录；
> - [ ] 第一次先跑 `生成示例文件_zh.py`，再跑 `批量处理Excel_zh.py`；
> - [ ] 核心脚本只另存为 `*_已处理.xlsx`，不动原文件。