#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ 比较两个学生 Excel 文件的表头(列名)。 用法: python compare_student_headers.py \ --file-a 学校历史数据迁移/student1222.xls \ --file-b 学校历史数据迁移/student1127.xls 脚本会打印: - 是否完全相同(顺序及名称) - 仅在 A 中存在的列 - 仅在 B 中存在的列 - 顺序不同但内容相同的列(名称相同但位置不同) """ from __future__ import annotations import os import sys import argparse from typing import List import pandas as pd def read_headers(path: str) -> List[str]: if not os.path.exists(path): raise FileNotFoundError(path) ext = os.path.splitext(path)[1].lower() if ext == ".xls": df = pd.read_excel(path, nrows=0, engine="xlrd") else: # .xlsx or others df = pd.read_excel(path, nrows=0, engine="openpyxl") return [str(c).strip() for c in list(df.columns)] def main(): parser = argparse.ArgumentParser() parser.add_argument("--file-a", type=str, required=True) parser.add_argument("--file-b", type=str, required=True) args = parser.parse_args() try: headers_a = read_headers(args.file_a) except Exception as e: print(f"读取 {args.file_a} 表头失败: {e}") sys.exit(2) try: headers_b = read_headers(args.file_b) except Exception as e: print(f"读取 {args.file_b} 表头失败: {e}") sys.exit(2) print(f"{args.file_a} 列数: {len(headers_a)}") print(f"{args.file_b} 列数: {len(headers_b)}") if headers_a == headers_b: print("表头完全相同(顺序及名称一致)。") return set_a = set(headers_a) set_b = set(headers_b) only_a = sorted(list(set_a - set_b)) only_b = sorted(list(set_b - set_a)) if not only_a and not only_b: print("列集合相同,但顺序不同。") # show first few mismatches by position diffs = [] for i, (ca, cb) in enumerate(zip(headers_a, headers_b)): if ca != cb: diffs.append((i + 1, ca, cb)) if diffs: print("位置不一致的前若干列(位置, A列名, B列名):") for d in diffs[:20]: print(f" {d[0]:>3}: {d[1]} | {d[2]}") else: # maybe lengths differ; list remainder if len(headers_a) != len(headers_b): print("两表长度不同,下面列出多余部分:") if len(headers_a) > len(headers_b): print("A 多余:", headers_a[len(headers_b):len(headers_b)+20]) else: print("B 多余:", headers_b[len(headers_a):len(headers_a)+20]) return # print differences if only_a: print(f"仅在 A 中存在的列 ({len(only_a)}):") for c in only_a[:100]: print(" -", c) if only_b: print(f"仅在 B 中存在的列 ({len(only_b)}):") for c in only_b[:100]: print(" -", c) # also list positional mismatches up to 20 diffs = [] for i in range(min(len(headers_a), len(headers_b))): if headers_a[i] != headers_b[i]: diffs.append((i + 1, headers_a[i], headers_b[i])) if diffs: print("位置不一致的前若干列(位置, A列名, B列名):") for d in diffs[:20]: print(f" {d[0]:>3}: {d[1]} | {d[2]}") if __name__ == "__main__": main()