import os import pandas as pd from openpyxl import load_workbook def _merge_read_config(config): defaults = { "columns_to_preview": 3, "green_colors": {"FF92D050", "FF00B050"}, "blue_colors": {"FF00B0F0", "FF0070C0"}, "orange_colors": {"FFC55B11", "FFC55C10", "FFB45F06"}, "pink_colors": {"FFEF949F", "FFFF99FF"}, "log_file": "w.log", } if not config: return defaults for key, value in config.items(): if value is not None: defaults[key] = value return defaults def _load_map_dataframe(file_path, sheet_name, start_i): if not os.path.exists(file_path): print(f"错误:文件未找到,请检查路径。Path: {file_path}") return None try: df = pd.read_excel(file_path, sheet_name=sheet_name, engine="openpyxl") except Exception as e: print(f"读取 XLSX 文件时发生错误: {e}") if "No module named 'openpyxl'" in str(e): print("\n请确保您已经安装了 openpyxl 库:pip install openpyxl") return None if len(df.columns) < 2: print("错误:表格至少需要两列 (地图编号与 Y 坐标)。") return None map_col = df.columns[0] y_col = df.columns[1] grid_columns = df.columns[1:27] i = start_i for row in df.itertuples(): if pd.isna(row[1]): df.at[row.Index, map_col] = i else: i = row[1] return df, map_col, y_col, grid_columns def _write_color_output(filename, rows, columns, success_msg, empty_msg): if os.path.exists(filename): os.remove(filename) if rows: pd.DataFrame(rows, columns=columns).to_excel(filename, index=False) print(success_msg) else: print(empty_msg) def find_cells_with_currency_xlsx(file_path, sheet_name="Sheet1", start_i=90091, search_term="币", config=None): """ 读取 XLSX 文件,查找包含指定词语(默认为“币”)的单元格, 并返回这些单元格的 (地图号, X, Y[, 方向]),结果同时保存为 found_xxx.xlsx。 """ print(f"--- 正在处理文件: {os.path.basename(file_path)} ---") df_info = _load_map_dataframe(file_path, sheet_name, start_i) if df_info is None: return [] cfg = _merge_read_config(config) df, map_col, y_col, grid_columns = df_info results = [] # 2. 遍历 B~AA 每一列,在地图区域里搜索 币 / p / v for column in grid_columns: column_series = df[column].astype(str).fillna("") if search_term in ["p", "v"]: # p/v 支持后缀方向 suffixes = ["W", "S", "N", "E", "w", "s", "n", "e"] search_terms = [search_term] + [search_term + s for s in suffixes] matching_rows = column_series.apply( lambda x: any(term in x for term in search_terms) ) else: search_terms = [search_term] matching_rows = column_series.str.contains(search_term, regex=False, na=False) matching_indices = df[matching_rows].index.tolist() if not matching_indices: continue for idx in matching_indices: # 地图号和坐标:直接从 A、B 列取值 map_no = df.at[idx, map_col] # A 列 = 地图编号 y_no = df.at[idx, y_col] # B 列 = Y 坐标 x_no = column # 列名本身 = X 坐标(-12 ~ 12) # 提取方向(只对 p / v 有意义) direction = "" if search_term in ["p", "v"]: cell_text = str(df.loc[idx, column]) direction = cell_text[len(search_term):] if len(cell_text) > len(search_term) else "" if search_term in ["p", "v"]: results.append((map_no, x_no, y_no, direction)) else: results.append((map_no, x_no, y_no)) # 4. 保存币 / p / v 结果到 Excel output_file = f"found_{search_term}.xlsx" if search_term in ["p", "v"]: results_df = pd.DataFrame( results, columns=["地图号 (Map No)", "X坐标 (X No)", "Y坐标 (Y No)", "方向 (Direction)"] ) else: results_df = pd.DataFrame( results, columns=["地图号 (Map No)", "X坐标 (X No)", "Y坐标 (Y No)"] ) results_df.to_excel(output_file, index=False) print(f"\n🔖 已将结果保存到文件: {output_file}") return results def scan_color_blocks(file_path, sheet_name="Sheet1", start_i=90091, config=None): """扫描地图区域内的颜色格子,并把结果写入对应的 Excel 文件。""" print("\n开始扫描颜色图案格子…") df_info = _load_map_dataframe(file_path, sheet_name, start_i) if df_info is None: return {} cfg = _merge_read_config(config) df, map_col, y_col, grid_columns = df_info try: wb = load_workbook(file_path, data_only=True) except Exception as e: print(f"读取 XLSX 文件时发生错误: {e}") return {} try: ws = wb[sheet_name] except KeyError: active_sheet = wb.active print(f"未找到工作表 {sheet_name},使用活动表 {active_sheet.title}。") ws = active_sheet block_results = [] water_results = [] wall_results = [] jump_results = [] excel_row_offset = 2 # DataFrame 行索引 0 对应 Excel 的第 2 行 import logging logging.basicConfig(filename=cfg["log_file"], level=logging.INFO) log = logging.getLogger(__name__) for idx in df.index: map_no = df.at[idx, map_col] y_val = df.at[idx, y_col] try: y_int = int(y_val) except (TypeError, ValueError): continue if y_int < -12 or y_int > 12: continue excel_row = idx + excel_row_offset for col in grid_columns[1:]: # 从 C 列开始(跳过 Y 轴列) col_idx = df.columns.get_loc(col) + 1 # openpyxl 的列号从 1 开始 cell = ws.cell(row=excel_row, column=col_idx) fill = cell.fill if fill is None or fill.patternType in (None, "none"): continue fg = fill.fgColor rgb = getattr(fg, "rgb", None) index = getattr(fg, "index", None) color_code = rgb or index if color_code is None: continue c = str(color_code).upper() if c.startswith("FF"): log.info("Cell at Row %s, Column %s has color code: %s", excel_row, col_idx, c) if c in cfg["green_colors"]: block_results.append((map_no, col, y_val)) if c in cfg["blue_colors"]: water_results.append((map_no, col, y_val)) if c in cfg["orange_colors"]: wall_results.append((map_no, col, y_val)) if c in cfg["pink_colors"]: jump_results.append((map_no, col, y_val)) columns = ["地图号 (Map No)", "X坐标 (X No)", "Y坐标 (Y No)"] _write_color_output( "found_方块.xlsx", block_results, columns, "🔖 已将所有绿色图案格子的坐标保存到文件: found_方块.xlsx", "未发现任何绿色图案格子。", ) _write_color_output( "found_water.xlsx", water_results, columns, "🔖 已将蓝色 (water) 格子保存到文件: found_water.xlsx", "未发现蓝色 (water) 格子。", ) _write_color_output( "found_wall.xlsx", wall_results, columns, "🔖 已将橙色 (wall) 格子保存到文件: found_wall.xlsx", "未发现橙色 (wall) 格子。", ) _write_color_output( "found_jump.xlsx", jump_results, columns, "🔖 已将粉色 (jump) 格子保存到文件: found_jump.xlsx", "未发现粉色 (jump) 格子。", ) return { "block": block_results, "water": water_results, "wall": wall_results, "jump": jump_results, }