""" Excel/CSV file reader/writer using pandas + openpyxl. """ import os from pathlib import Path import pandas as pd from core.data_model import CoordData, CoordPoint class ExcelHandler: EXTENSIONS = {".xlsx", ".xls", ".csv"} @classmethod def read(cls, path: str, sheet: str | None = None) -> CoordData: ext = Path(path).suffix.lower() if ext == ".csv": df = pd.read_csv(path, encoding="utf-8-sig") else: df = pd.read_excel(path, sheet_name=sheet or 0, dtype_backend="numpy_nullable") if df.empty: raise ValueError(f"文件无数据: {path}") records = df.to_dict(orient="records") # Convert nan to None for r in records: for k, v in r.items(): if pd.isna(v): r[k] = None cols = list(df.columns) x_col, y_col, z_col = cls._find_coord_cols(cols) return CoordData.from_records(records, x_col=x_col, y_col=y_col, z_col=z_col) @classmethod def write(cls, data: CoordData, path: str, sheet: str = "坐标数据"): records = data.to_records() if not records: raise ValueError("无数据可写入") df = pd.DataFrame(records) ext = Path(path).suffix.lower() if ext == ".csv": df.to_csv(path, index=False, encoding="utf-8-sig") else: with pd.ExcelWriter(path, engine="openpyxl") as writer: df.to_excel(writer, sheet_name=sheet, index=False) @staticmethod def _find_coord_cols(cols: list[str]) -> tuple[str, str, str | None]: """Same logic as TxtHandler for column discovery.""" x_patterns = ["x", "lon", "经度", "lng", "easting"] y_patterns = ["y", "lat", "纬度", "northing"] z_patterns = ["z", "h", "高程", "高度", "alt"] x_col = y_col = z_col = None lower_cols = {c: c.lower().replace(" ", "").replace("_", "").replace("-","") for c in cols} for c, lc in lower_cols.items(): if any(p in lc for p in x_patterns): x_col = c elif any(p in lc for p in y_patterns): y_col = c elif any(p in lc for p in z_patterns): z_col = c if not x_col and len(cols) >= 2: x_col, y_col = cols[0], cols[1] return x_col, y_col, z_col