Metadata-Version: 2.4
Name: Excel_Split_and_fill_merged_cells
Version: 0.1.0
Summary: 输入 Excel 路径即可自动识别、拆分合并单元格并填充对应内容；支持覆盖原文件、另存 xlsx/csv、输出 pandas/polars DataFrame。
Author: 辉哥 & 旺财
License-Expression: MIT
Project-URL: Homepage, https://github.com/你的用户名/Excel_Split_and_fill_merged_cells
Project-URL: Repository, https://github.com/你的用户名/Excel_Split_and_fill_merged_cells
Project-URL: Issues, https://github.com/你的用户名/Excel_Split_and_fill_merged_cells/issues
Keywords: excel,xlsx,merge-cells,unmerge,split,fill,pandas,polars,csv,data-cleaning,spreadsheet
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Office/Business :: Office Suites
Classifier: Topic :: Scientific/Engineering
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: File Formats
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: openpyxl>=3.0
Provides-Extra: pandas
Requires-Dist: pandas>=1.3; extra == "pandas"
Provides-Extra: polars
Requires-Dist: polars>=0.18; extra == "polars"
Provides-Extra: all
Requires-Dist: pandas>=1.3; extra == "all"
Requires-Dist: polars>=0.18; extra == "all"
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pandas>=1.3; extra == "dev"
Requires-Dist: polars>=0.18; extra == "dev"
Requires-Dist: build>=1.0; extra == "dev"
Requires-Dist: twine>=4.0; extra == "dev"
Dynamic: license-file

# Excel_Split_and_fill_merged_cells

> 输入 Excel 文件路径，自动识别合并单元格、拆分并填入对应内容。

一个专注于"拆分合并单元格并填充"的轻量 Python 库。基于 openpyxl + 线程池，纯 Python 实现，无需编译，装上即用。

## 特性

- ✅ **自动识别**：自动检测 Excel 中所有合并单元格区域
- ✅ **拆分并填充**：取消合并，把原左上角的值回填到区域内每个单元格
- ✅ **多种输出**：覆盖原文件 / 另存 xlsx / 另存 CSV / 输出 DataFrame
- ✅ **pandas / polars 友好**：一行代码拿到 DataFrame，直接进分析流程
- ✅ **多工作表支持**：可按索引、名称选择，也可一次处理全部工作表
- ✅ **并发回填**：线程池加速大批量合并单元格的填充
- ✅ **纯 Python**：无需 C/C++ 编译器，跨平台

## 安装

```bash
pip install Excel_Split_and_fill_merged_cells
```

如需 pandas / polars 支持，安装对应的可选依赖：

```bash
pip install "Excel_Split_and_fill_merged_cells[pandas]"   # 仅 pandas
pip install "Excel_Split_and_fill_merged_cells[polars]"   # 仅 polars
pip install "Excel_Split_and_fill_merged_cells[all]"      # 两者都要
```

## 快速开始

```python
from Excel_Split_and_fill_merged_cells import (
    split_and_fill, to_csv, to_pandas, to_polars, to_data, get_sheet_names
)
```

### 1. 拆分并覆盖原文件

```python
split_and_fill("data.xlsx")
```

### 2. 另存为新 Excel 文件

```python
split_and_fill("data.xlsx", output="clean.xlsx")
```

### 3. 另存为 CSV

```python
to_csv("data.xlsx", output="out.csv")
# 不指定 output，自动生成同名 .csv
to_csv("data.xlsx")
```

### 4. 输出 pandas DataFrame

```python
df = to_pandas("data.xlsx")
print(df.head())
```

### 5. 输出 polars DataFrame

```python
df = to_polars("data.xlsx")
print(df)
```

### 6. 输出原生 dict（不依赖任何第三方库）

```python
data = to_data("data.xlsx")
print(data["headers"])   # ['姓名', '部门', '工资']
print(data["rows"][0])   # ['张三', '技术部', 9500]

# 也可以自己喂给 pandas
import pandas as pd
df = pd.DataFrame(data["rows"], columns=data["headers"])
```

### 7. 查看工作表名称

```python
print(get_sheet_names("data.xlsx"))   # ['Sheet1', '汇总', '明细']
```

## API 一览

| 函数 | 作用 | 返回 |
|------|------|------|
| `split_and_fill(filepath, output=None, sheet=None, max_workers=8)` | 拆分填充并保存 | 输出文件路径 |
| `to_csv(filepath, output=None, sheet=0, max_workers=8, encoding='utf-8-sig')` | 拆分填充后存为 CSV | CSV 文件路径 |
| `to_pandas(filepath, sheet=0, header=True, max_workers=8)` | 拆分填充后返回 DataFrame | `pandas.DataFrame` |
| `to_polars(filepath, sheet=0, header=True, max_workers=8)` | 拆分填充后返回 DataFrame | `polars.DataFrame` |
| `to_data(filepath, sheet=0, header=True, max_workers=8)` | 拆分填充后返回原生数据 | `dict(headers, rows, sheet_name)` |
| `get_sheet_names(filepath)` | 读取工作表名称 | `list[str]` |

### 参数说明

- **`filepath`**：Excel 文件路径，支持 `.xlsx` / `.xlsm`。
- **`output`**：
  - `None`：覆盖原文件（`split_and_fill`）；
  - `*.xlsx` / `*.xlsm`：另存为新 Excel；
  - `*.csv`：另存为 CSV（此时 `sheet` 只能指向单个工作表）。
- **`sheet`**：工作表选择。
  - `None`：处理所有工作表（`split_and_fill` 默认）；
  - `int`：按索引选择，0 开始；
  - `str`：按名称选择；
  - `list`：多选。
- **`header`**：`True` 时把第一行作为列名（`to_pandas` / `to_polars` / `to_data`）。
- **`max_workers`**：线程池大小，控制并发回填的线程数；`<=1` 表示单线程。
- **`encoding`**：CSV 编码，默认 `utf-8-sig`（带 BOM，Excel 直接打开不乱码）。

## 工作原理

```
原始 Excel（有合并单元格）          处理后（已拆分并填充）
┌─────────┬─────────┐              ┌─────┬─────┐
│  部门   │  工资   │              │部门 │工资 │
├─────────┼─────────┤              ├─────┼─────┤
│ 技术部  │         │    ───▶      │技术部│9500 │
│         │  9500   │              │技术部│9500 │
│         │         │              │技术部│9500 │
└─────────┴─────────┘              └─────┴─────┘
```

1. 用 `openpyxl` 打开工作簿，定位目标工作表；
2. 快照所有合并区域及其左上角值（在取消合并前读取）；
3. 调用 `unmerge_cells` 取消合并；
4. 用线程池把左上角值回填到区域内每个单元格（写操作加锁，保证线程安全）；
5. 按选择的输出方式保存或返回。

## 注意事项

- 仅支持 `.xlsx` / `.xlsm` 格式；旧的 `.xls` 格式请先在 Excel 中另存为 `.xlsx`。
- `openpyxl` 在保存时会丢失部分高级元素（如图表、数据透视表、部分 VBA 项目）。如果文件包含这些内容，建议用 `output` 另存为新文件，保留原始文件。
- 公式单元格默认读取其缓存值（`data_only=True`）；如果文件从未被 Excel 打开保存过，公式结果可能为 `None`。
- `max_workers` 在纯 Python 环境下受 GIL 限制，主要价值在于批量场景下的 I/O 调度；数据量小时设为 1 即可。

## 开发

```bash
# 克隆仓库后
pip install -e ".[dev]"

# 运行测试
pytest tests/ -v

# 构建
python -m build

# 上传 PyPI
twine upload dist/*
```

## License

MIT © 辉哥 & 旺财
