Metadata-Version: 2.4
Name: excel-convert
Version: 0.4.1
Summary: Combine Multiple Excel Files into a Unified Standard Layout.
License-Expression: MIT
License-File: LICENSE
Requires-Python: >=3.12
Requires-Dist: duckdb>=1.5.0
Requires-Dist: openpyxl>=3.1.5
Requires-Dist: pandas>=3.0.1
Requires-Dist: pyarrow>=23.0.1
Requires-Dist: pyyaml>=6.0.3
Requires-Dist: sqlglot>=30.2.1
Description-Content-Type: text/markdown

# Excel Convert

将多个 Excel 文件合并为统一标准格式。CLI 提供源文件结构信息供 LLM 生成 DuckDB SQL，再执行 SQL 完成列映射、数据合并和模板格式化输出。

## 功能

- **两步工作流**: `inspect` 获取元数据 → LLM 生成 SQL → `execute` 执行并输出
- **模板格式化**: 输出 Excel 保留模板的字体、颜色、边框、列宽等格式
- **表头检测**: 多维度加权算法自动识别 Excel 中的表头行（支持多行合并表头）
- **SQL 评分**: 自动评估 SQL 对模板列覆盖率和源列利用率，低于阈值时拦截
- **Parquet 缓存**: 按输入文件路径+修改时间生成确定性缓存目录，`inspect` 与 `execute` 自动共享

## 安装

```bash
uv tool install git+https://github.com/chenxinma/excel_convert.git
```

安装后 `excel-convert` 命令即全局可用，无需每次 `uv run`。

升级：

```bash
uv tool upgrade excel-convert
```

## 快速开始

### Step 1: Inspect — 获取源文件结构

```bash
excel-convert inspect data1.xlsx data2.xlsx -t template.xlsx
```

输出 JSON 包含：

| 字段 | 说明 |
|------|------|
| `template_columns` | 模板目标列名列表 |
| `info_items` | 列定义（类型、说明、近义词） |
| `playbook` | SQL 生成规则（若配置） |
| `sheets` | 各源 sheet 元数据（文件名、sheet 名、列名、行数） |
| `parquet_map` | sheet 显示名 → 绝对 parquet 路径映射，用于 `read_parquet()` |

### Step 2: Write SQL and Execute

根据 `inspect` 输出编写 DuckDB SQL，然后执行：

```bash
# 从 SQL 文件执行
excel-convert execute data1.xlsx data2.xlsx -t template.xlsx --sql merge.sql -o output.xlsx

# 从 stdin 管道执行
cat merge.sql | excel-convert execute data1.xlsx data2.xlsx -t template.xlsx -o output.xlsx
```

> **Windows 编码注意**: Windows 默认控制台编码不是 UTF-8，中文字符可能乱码。
> 在命令前加上环境变量或切换代码页：
>
> ```bash
> # 方式 A：设置环境变量（CMD / PowerShell / Git Bash 均适用）
> PYTHONIOENCODING=utf-8 excel-convert inspect ...
>
> # 方式 B：CMD 中切换代码页
> chcp 65001 && excel-convert inspect ...
> ```

执行流程：

1. 验证 SQL 语法（仅允许 SELECT / WITH，禁止 DDL/DML）
2. 评分 SQL 质量（模板列覆盖率 × 0.7 + 源列利用率 × 0.3）
3. 通过 DuckDB 执行 SQL
4. 后处理日期列，按模板格式输出 Excel

## CLI 命令参考

### `inspect` — 检查源文件结构

```bash
excel-convert inspect FILE [FILE ...] -t TEMPLATE [选项]
```

### `execute` — 执行 SQL 合并

```bash
excel-convert execute FILE [FILE ...] -t TEMPLATE [--sql FILE] [-o OUTPUT] [选项]
```

### 公共参数

| 参数 | 说明 |
|------|------|
| `-t, --template` | Excel 模板文件（必需，仅 1 个可见 sheet） |
| `-o, --output` | 输出文件路径（默认 `merged_output.xlsx`） |
| `--sql` | SQL 文件路径（省略则从 stdin 读取） |
| `--clean` | 执行前清除本次输入文件对应的 parquet 缓存 |
| `-c, --config-dir` | 配置目录（默认 `./config`） |
| `-v, --verbose` | 详细日志（含 SQL 评分详情） |
| `-q, --quiet` | 仅输出错误 |

## 配置

### SQL 规则 (`config/playbook.yaml`)

定义 DuckDB SQL 生成规则和示例，供 LLM 参考。

### Excel 模板

模板仅保留 1 个可见 sheet，首行（或前几行）定义目标列名。支持多行合并表头。

可通过单元格批注提供近义词和说明，辅助 LLM 列映射：

```
同义词: name, 员工姓名, 申请人
说明: 员工的姓名
```

模板的格式（字体、颜色、边框、列宽等）会完整保留到输出文件。

## 开发

```bash
git clone https://github.com/chenxinma/excel_convert.git
cd excel_convert
uv sync
uv run pytest              # 运行测试
uvx ruff check .           # 代码检查
uvx ruff format .          # 代码格式化
```

### 项目结构

```
src/excel_convert/
├── cli.py               # CLI 入口（inspect / execute）
├── unified_pipeline.py  # 合并 Pipeline（Excel → Parquet → SQL → Excel）
├── utils.py             # 工具函数 + SessionCache
├── analyze/
│   ├── analyzer.py      # SheetAnalyzer: Excel → Parquet，提取元数据
│   ├── scorer.py        # SQL 评分（模板覆盖率 + 源列利用率）
│   └── models.py        # SheetInfo, AnalyzeResult, PlanScore
├── read/
│   ├── converter.py     # ExcelConverter: Excel → Parquet
│   └── header_finder.py # 表头检测算法
├── mapping/
│   ├── config.py        # 配置管理（info_items / playbook）
│   ├── column_utils.py  # 列名清理与哈希
│   ├── date_utils.py    # 日期格式化
│   └── sql_validator.py # SQL 语法校验（sqlglot）
└── merge/
    └── merger.py        # FeatherMerger: 模板格式化输出
```

## License

MIT
