将 NGO 报名 Excel 数据清洗后转换为导入文件的脚本,支持 .xls 和 .xlsx。
当前工程分成两层:
convert_v3.py:命令行入口,只负责解析参数和调用主流程excel_converter.py:核心模块,负责 Excel 读写适配、字段清洗和转换逻辑
.
├── convert_v3.py # CLI 入口
├── excel_converter.py # 核心转换逻辑
├── requirements.txt
├── README.md
└── LICENSE
- 支持读取
.xls和.xlsx - 支持导出
.xls和.xlsx - 默认导出格式跟输入格式一致
- 支持通过参数显式指定输出路径和输出格式
- 按第二个工作表中的项目名称白名单过滤数据
- 对项目名称去重,只保留首次出现的记录
- 清洗 HTML 实体和引号文本
- 解析主理人和团队成员信息
- 从通讯地址中尝试提取学校名称
- 保留“项目计划书”和“其他项目材料”的超链接
运行环境建议:
- Python 3.9+
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txtWindows PowerShell:
python -m venv .venv
.venv\Scripts\Activate.ps1
pip install -r requirements.txt依赖如下:
xlrd>=2.0.1
openpyxl>=3.1.0
xlwt>=1.3.0
各依赖的职责:
xlrd:读取.xlsopenpyxl:读取和写出.xlsxxlwt:写出.xls
python convert_v3.py INPUT_FILE
python convert_v3.py INPUT_FILE -o OUTPUT_FILE
python convert_v3.py INPUT_FILE --output-format xls
python convert_v3.py INPUT_FILE --output-format xlsx示例:
python convert_v3.py data/czy.xls
python convert_v3.py data/czy.xlsx
python convert_v3.py data/czy.xls --output-format xlsx
python convert_v3.py data/czy.xlsx -o exports/czy_cleaned.xls参数说明:
| 参数 | 说明 |
|---|---|
INPUT_FILE |
必填,源 Excel 文件路径,支持 .xls / .xlsx |
-o, --output |
可选,输出文件路径 |
--output-format |
可选,输出格式,取值为 xls 或 xlsx |
查看帮助:
python convert_v3.py -h如果不传 --output:
- 输出文件和输入文件位于同一目录
- 文件名为
<输入文件名>_output - 扩展名默认跟输入文件一致
例如:
| 输入文件 | 默认输出文件 |
|---|---|
data/czy.xls |
data/czy_output.xls |
data/czy.xlsx |
data/czy_output.xlsx |
--output 和 --output-format 的优先级如下:
- 只传
--output:以输出路径扩展名为准 - 只传
--output-format:在默认输出路径基础上切换格式 - 同时传两者:如果两者格式不一致,脚本会直接报错
例如:
python convert_v3.py data/czy.xlsx --output-format xls
python convert_v3.py data/czy.xlsx -o exports/result.xls
python convert_v3.py data/czy.xlsx -o exports/result --output-format xls脚本默认读取源工作簿的前两个工作表:
- 第 1 个工作表:主数据表
- 第 2 个工作表:项目名称白名单表
并要求第 2 个工作表第 1 列为“允许导入的项目名称”列表。
下面的“列索引”是 Python 的 0-based 索引。
| 列索引 | Excel列 | 用途 |
|---|---|---|
| 1 | B | 主理人手机号兜底值 |
| 2 | C | 项目名称 |
| 3 | D | 项目所属议题 |
| 5 | F | 通讯地址;若包含 @,兼容识别为邮箱 |
| 6 | G | 项目说明,输出到“使用的AI技术点描述” |
| 13 | N | 项目计划书文本,同时保留其超链接 |
| 14 | O | 其他项目材料文本,同时保留其超链接 |
| 15 | P | 主理人信息字符串 |
| 16-19 | Q-T | 团队成员信息字符串 |
脚本默认把人员信息解析为下面这种格式:
姓名,性别,+86,手机号,证件类型,证件号,角色,出生日期
例如:
张三,男,+86,13800138000,身份证,110101...,负责人,2001-05-20
兼容情况:
- 性别字段之前允许出现多个姓名段
- 多个姓名之间可以使用半角逗号、全角逗号或顿号
- 第一个姓名视为主理人
- 其余姓名会拆到“团队成员”列
输出工作表名固定为 Sheet1,表头如下:
| 输出列 | 说明 |
|---|---|
| 团队ID | 重新从 1 开始编号 |
| 团队名称 | 留空 |
| 项目名称 | 源项目名称,经过文本清洗 |
| 项目主理人联系方式 | 按“姓名,手机,年龄,学校,邮箱”拼接,空值跳过 |
| 团队成员 | 每行一个成员,格式为“姓名,年龄” |
| 指导老师 | 留空 |
| 项目所属议题 | 来自源表第 4 列 |
| 使用的AI技术点描述 | 来自源表第 7 列 |
| 项目计划书 | 文本保留,并迁移超链接 |
| 其他项目材料 | 文本保留,并迁移超链接 |
| 我确认已了解本活动的规则,并保证项目的原创与版权所有 | 留空 |
- 读取
.xls或.xlsx源文件。 - 从第二个工作表读取项目名称白名单。
- 遍历第一个工作表的数据行。
- 跳过项目名为空、项目名不在白名单中、或项目名重复的记录。
- 清洗文本字段,处理 HTML 实体和引号。
- 解析主理人信息,必要时回退到源表手机号字段。
- 从通讯地址中尝试提取学校名称。
- 汇总团队成员信息。
- 按目标格式写出新的
.xls或.xlsx文件,并迁移超链接。
safe_str():把 Excel 读出的值转成字符串,并把123.0变成123fix_quotes():处理"等 HTML 实体,并把成对半角引号替换为中文引号“”
extract_school() 是启发式规则,不是完整地址解析器。它会:
- 优先尝试从括号内容中提取学校名
- 识别以“大学”或“学院”结尾的名称
- 避免把“大学城”“大学路”误判为学校
- 尝试剥离省、市、区、县、镇、乡、路、山等前缀
- 仅接受 3 到 15 个汉字的纯中文学校名称
- 按项目名称原始值去重
- 仅保留第一次出现的记录
执行完成后,控制台会输出处理统计,例如:
完成!输出 X 行
跳过空行: X
跳过重复: X
跳过不在Sheet2: X
Sheet2 中无数据的项目名: X
输出文件:...
- 默认依赖固定的工作表顺序和列位
- 年龄按脚本运行当天动态计算
- “邮箱”仍然是从第 6 列内容中按是否包含
@做兼容识别 - 学校名提取采用启发式规则,不保证覆盖所有场景
.xls输出最多支持 65535 条数据行,超过时请改用.xlsx.xlsx输入按缓存值读取公式单元格;如果源文件公式未计算并保存,读到的值可能为空.xls与.xlsx的单元格底层类型可能略有不同,但输出字段内容和列结构保持一致- “团队名称”“指导老师”“确认规则”三列固定留空
- 将 Excel 读写适配和业务规则进一步拆分,降低
excel_converter.py的体积。 - 把源列映射提取成配置,减少对固定列号的依赖。
- 为学校提取、人员解析、去重规则补自动化测试。
- 把“地址字段兼容邮箱”的历史逻辑拆成显式字段处理。