python暴力破解excel_如何用Python定位Excel工作表,暴力又简单!效率提升五倍!...

这篇博客介绍了如何使用Python的openpyxl库来定位和操作Excel工作表。首先,通过`load_workbook`加载工作簿并使用`active`属性获取活动工作表。其次,通过索引方式获取指定位置的工作表。最后,直接通过工作表名称来定位。这些方法对于Excel数据的读取和写入非常实用。
部署运行你感兴趣的模型镜像

一,定位Excel工作表(3种方法)

First:

import openpyxlzw=openpyxl.load_workbook("我的工作表.xlsx")z1=zw.activeprint(z1)

1,引入数据库

2,加载你新建的工作表

3,获取活动工作表。(在每一个工作簿的下面,都有工作表名称列表,默认的是sheet1、sheet2、sheet3等,点击某个工作表的名称,就可以将这个工作表变为当前的活动工作表。)

4,运行,输出结果如下,我的当前活动单元格是sheet1

Second:

1,引入数据库

2,加载你新建的工作表

3,以索引方式获取活动工作表,括号里的数字是从0算起的,也就是代表我的第一个sheet页。

4,运行,输出结果如下,我的当前活动单元格是sheet1

5,这是我新建的表格

Third:

import openpyxlzw=openpyxl.load_workbook("我的工作表.xlsx")z3=zw["Sheet6"]print(z3)

1,引入数据库。

2,加载你新建的工作表。

3,以固定sheet页的名字来定位。

4,运行,输出结果如下。

您可能感兴趣的与本文相关的镜像

Python3.10

Python3.10

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

# ui_main_window.py # 在 ui_main_window.py 文件开头添加 import datetime import sys from power.power_sync import PowerTableSynchronizer import os from PyQt6.QtWidgets import ( QWidget, QVBoxLayout, QHBoxLayout, QLabel, QLineEdit, QPushButton, QTextEdit, QFileDialog, QComboBox, QGroupBox, QApplication, QMessageBox, QDialog, QCheckBox ) from PyQt6.QtCore import QObject, pyqtSignal import logging from pathlib import Path from utils import get_output_dir print(f" 当前工作目录: {os.getcwd()}") print(f" 文件所在目录: {Path(__file__).resolve()}") from excel_to_clm import ExcelToCLMConverter from channel.range_sync import CLMRangeSynchronizer # 使用统一模块 # ============= 日志重定向器 ============== class LogEmitter(QObject): log_signal = pyqtSignal(str) # ============= 主窗口类 ============== class CLMGeneratorUI(QWidget): def __init__(self, generator=None): super().__init__() self.generator = generator or ExcelToCLMConverter() self.log_emitter = LogEmitter() self.log_emitter.log_signal.connect(self.update_log_area) # 设置日志系统以捕获同步器输出 self._setup_logging_redirect() self.setWindowTitle("Wi-Fi CLM Generator Tool v1.2") self.resize(700, 600) self.init_ui() def _setup_logging_redirect(self): """仅将 channel.* 日志转发到 UI,不写文件""" class QtStreamHandler(logging.Handler): def __init__(self, emitter): super().__init__() self.emitter = emitter self.setFormatter(logging.Formatter('%(levelname)s: %(message)s')) def emit(self, record): try: msg = self.format(record) if msg.strip(): self.emitter.log_signal.emit(msg.strip()) except Exception: self.handleError(record) logger = logging.getLogger("channel") logger.setLevel(logging.INFO) if logger.hasHandlers(): logger.handlers.clear() handler = QtStreamHandler(self.log_emitter) logger.addHandler(handler) logger.propagate = False class LogStream: """伪装成文件对象的日志流,用于 logging.Handler""" def __init__(self, emitter): self.emitter = emitter def write(self, msg): if msg.strip(): self.emitter.log_signal.emit(msg.strip()) def flush(self): pass def init_ui(self): layout = QVBoxLayout() # === 输入区:Excel & Config === input_group = QGroupBox("输入配置") input_layout = QVBoxLayout() # Excel 文件 excel_row = QHBoxLayout() excel_row.addWidget(QLabel("Excel 文件:")) self.excel_path = QLineEdit("input/Archer BE900US 2.xlsx") self.btn_browse_excel = QPushButton(" 浏览...") self.btn_browse_excel.clicked.connect(self.select_excel) excel_row.addWidget(self.excel_path) excel_row.addWidget(self.btn_browse_excel) input_layout.addLayout(excel_row) # Config 文件 config_row = QHBoxLayout() config_row.addWidget(QLabel("Config 文件:")) self.config_path = QLineEdit("config/config.json") self.btn_browse_config = QPushButton(" 浏览...") self.btn_browse_config.clicked.connect(self.select_config_file) config_row.addWidget(self.config_path) config_row.addWidget(self.btn_browse_config) input_layout.addLayout(config_row) # Locale locale_row = QHBoxLayout() locale_row.addWidget(QLabel("Locale ID:")) self.locale_combo = QComboBox() self.locale_combo.addItems(["US", "FCC", "EU", "JP", "CN"]) locale_row.addWidget(self.locale_combo) input_layout.addLayout(locale_row) input_group.setLayout(input_layout) layout.addWidget(input_group) # === CLM 同步区 === sync_group = QGroupBox("CLM 范围同步") sync_layout = QVBoxLayout() # C 文件 cfile_row = QHBoxLayout() cfile_row.addWidget(QLabel("C 源文件:")) self.c_file_path = QLineEdit("input/wlc_clm_data_6726b0.c") self.btn_browse_cfile = QPushButton(" 浏览...") self.btn_browse_cfile.clicked.connect(self.select_c_file) cfile_row.addWidget(self.c_file_path) cfile_row.addWidget(self.btn_browse_cfile) sync_layout.addLayout(cfile_row) sync_group.setLayout(sync_layout) layout.addWidget(sync_group) # === 操作流程按钮组 === btn_group = QGroupBox("操作流程控制") btn_layout = QHBoxLayout() self.btn_parse = QPushButton(" 解析 Excel") self.btn_dry_run = QPushButton(" 预览同步") self.btn_sync = QPushButton(" 执行同步") self.btn_full_run = QPushButton(" 一键生成并同步") self.btn_parse.clicked.connect(self.run_parse) self.btn_dry_run.clicked.connect(lambda: self.run_range_sync(dry_run=True)) self.btn_sync.clicked.connect(lambda: self.run_range_sync(dry_run=False)) self.btn_full_run.clicked.connect(self.run_full_process) btn_layout.addWidget(self.btn_parse) btn_layout.addWidget(self.btn_dry_run) btn_layout.addWidget(self.btn_sync) btn_layout.addWidget(self.btn_full_run) btn_group.setLayout(btn_layout) layout.addWidget(btn_group) # === 功率表同步区 === power_sync_group = QGroupBox("功率表 & 国家码同步") power_sync_layout = QVBoxLayout() # 添加预览模式开关 self.chk_dry_run = QCheckBox(" 启用预览模式(不修改文件)") self.chk_dry_run.setChecked(True) # 默认开启预览,更安全 power_sync_layout.addWidget(self.chk_dry_run) # Locale 枚举选择(可多选) locale_power_row = QHBoxLayout() locale_power_row.addWidget(QLabel("默认Locale:")) self.power_locale_combo = QComboBox() self.power_locale_combo.addItems(["DEFAULT", "FCC", "ETSI", "JP", "CN"]) locale_power_row.addWidget(self.power_locale_combo) power_sync_layout.addLayout(locale_power_row) # 执行按钮 self.btn_sync_power = QPushButton("⚡ 注入功率表与国家码") self.btn_sync_power.clicked.connect(self.run_power_sync) power_sync_layout.addWidget(self.btn_sync_power) power_sync_group.setLayout(power_sync_layout) layout.addWidget(power_sync_group) # === 日志输出 === self.log_area = QTextEdit() self.log_area.setReadOnly(True) self.log_area.append(" CLM Generator 已启动,等待输入...") layout.addWidget(self.log_area) self.setLayout(layout) def run_power_sync(self): from datetime import datetime """运行功率表同步:提取 tx_limit_table.c 中的 DEFAULT 数据,注入到目标 .c 文件""" target_c_path = self.c_file_path.text().strip() if not target_c_path: self.log(" 未指定目标 C 文件,请先设置!") return generated_table_path = Path("output") / "tx_limit_table.c" config_path = self.config_path.text().strip() or "config/config.json" if not generated_table_path.exists(): self.log(f" 无法找到生成的功率表文件: {generated_table_path}") self.log(" 请先点击【开始生成】以生成 tx_limit_table.c") return # ========== 【新增】准备日志文件(仅在执行模式)========== file_handler = None log_file_path = None dry_run = self.chk_dry_run.isChecked() if not dry_run: # 只有执行模式才记录到文件 timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") log_dir = Path(get_output_dir()) / "log" log_dir.mkdir(parents=True, exist_ok=True) log_file_path = log_dir / f"power_sync_{timestamp}.log" # 创建专用 FileHandler file_handler = logging.FileHandler(log_file_path, encoding='utf-8') file_handler.setFormatter( logging.Formatter('%(asctime)s [%(levelname)s] %(name)s: %(message)s', datefmt='%H:%M:%S') ) # 添加到 power 模块 logger(与 UI 输出共存) target_logger = logging.getLogger("power") target_logger.addHandler(file_handler) self.log(f" 日志文件已创建: {log_file_path}") try: self.log(" 正在读取生成的功率表数据...") gen_content = generated_table_path.read_text(encoding='utf-8') # 提取 DEFAULT 功率表(Base 和 HT) base_block = PowerTableSynchronizer._extract_locale_block(gen_content, "DEFAULT") ht_block = PowerTableSynchronizer._extract_locale_block(gen_content, "DEFAULT_HT") if not base_block and not ht_block: self.log(" 未提取到任何 DEFAULT 功率表数据(检查是否生成了正确的 Locale)") return # 构造 locale_entries selected_locale_idx = self.power_locale_combo.currentText() idx_name = f"LOCALE_2G_IDX_{selected_locale_idx}" locale_entries = { "locale_2g_idx": idx_name } # 构造 power_tables prefix = "locales_" suffix = "[MAX_STREAMS_SUPPORTED][MODULATION_MODES]" power_tables = {} if base_block: key = "2g_base_DEFAULT" declaration = ( f"static const unsigned char {prefix}2g_base_DEFAULT[] = {{\n {base_block}\n}}" ) power_tables[key] = declaration self.log(f" 准备注入 2G Base 表") if ht_block: key = "2g_ht_DEFAULT" declaration = ( f"static const unsigned char {prefix}2g_ht_DEFAULT[] = {{\n {ht_block}\n}}" ) power_tables[key] = declaration self.log(f" 准备注入 HT 表") # 构造 country_entries(示例) country_entries = [ f'REGION("CN", {idx_name})', f'REGION("US", {idx_name})', f'REGION("EU", {idx_name})' ] self.log(f" 将为 CN/US/EU 注入国家码映射至 {idx_name}") # === 关键:从复选框获取 dry_run 状态 === dry_run = self.chk_dry_run.isChecked() # 创建同步器并执行 synchronizer = PowerTableSynchronizer( config_path=config_path, dry_run=dry_run # 可改为 True 测试 ) self.log(" 开始注入功率表和国家码...") synchronizer.sync_all( locale_entries=locale_entries, power_tables=power_tables, country_entries=country_entries ) self.log(" 功率表与国家码同步完成!") QMessageBox.information(self, "成功", "功率表与国家码已成功注入目标C文件!") self.log(f"完整日志已保存至:\n{log_file_path}") except Exception as e: self.log(f" 功率表同步失败: {str(e)}") import traceback self.log(f" 错误详情:\n{traceback.format_exc()}") QMessageBox.critical(self, "错误", f"同步过程出错:{str(e)}") def run_parse(self): """解析 Excel 并生成 manifest.json,不清除 generator 实例""" excel_path = self.excel_path.text().strip() config_path = self.config_path.text().strip() or "config/config.json" if not excel_path: self.log(" 请先选择 Excel 文件!") return try: # 复用已有 generator,仅更新参数 self.generator.config_file_path = config_path self.generator.locale_display_name = self.locale_combo.currentText() self.generator.input_file = excel_path self.log(" 清理旧数据...") self.generator.reset() # 统一调用 reset 方法 self.log(" 开始解析 Excel 文件...") self.generator.parse_excel() self.generator.generate_outputs(finalize_config=True) num_ranges = len(self.generator.used_ranges) manifest_path = self.generator.last_config self.log(f" 成功生成 {num_ranges} 个 RANGE 宏 → {manifest_path}") self.log(" 提示:现在可以点击【预览同步】查看对 .c 文件的影响") except Exception as e: self.log(f" 解析失败: {str(e)}") import traceback self.log(f" 错误详情:\n{traceback.format_exc()}") def select_excel(self): file, _ = QFileDialog.getOpenFileName( self, "选择 Excel 文件", "", "Excel Files (*.xlsx *.xls)") if file: self.excel_path.setText(file) def select_config_file(self): file, _ = QFileDialog.getOpenFileName( self, "选择配置文件", "config/", "JSON 配置文件 (*.json);;All Files (*)") if file: self.config_path.setText(file) def select_c_file(self): file, _ = QFileDialog.getOpenFileName( self, "选择 C 源文件", "input/", "C Source Files (*.c)") if file: self.c_file_path.setText(file) def log(self, msg): """发送日志消息到信号队列""" self.log_emitter.log_signal.emit(msg) def update_log_area(self, msg): """更新日志文本框""" self.log_area.append(f"> {msg}") def clear_log(self): self.log_area.clear() def show_preview(self): try: output_file = get_output_dir() with open(output_file, "r", encoding="utf-8") as f: content = f.read() dialog = QDialog(self) dialog.setWindowTitle(f"预览: {output_file}") dialog.resize(700, 500) layout = QVBoxLayout() text_edit = QTextEdit() text_edit.setReadOnly(True) text_edit.setText(content[:2000] + "\n...(后续内容已截断)") close_btn = QPushButton("关闭") close_btn.clicked.connect(dialog.accept) layout.addWidget(text_edit) layout.addWidget(close_btn) dialog.setLayout(layout) dialog.exec() except FileNotFoundError: self.log(f" 无法预览: 文件未生成 '{output_file}',请先点击【开始生成】") except Exception as e: self.log(f" 预览失败: {str(e)}") def run_range_sync(self, dry_run=False): """运行同步:使用 generator 生成的 manifest 路径自动同步到 C 文件""" from pathlib import Path import logging from datetime import datetime # 检查是否已生成 manifest if not hasattr(self.generator, 'last_config') or not self.generator.last_config: self.log(" 尚未生成任何 文件,请先点击【解析 Excel】") return # 默认使用自动生成的路径,允许用户手动覆盖 c_file_path = self.c_file_path.text().strip() if not c_file_path: self.log(" 未指定目标 C 文件路径,请在下方输入或选择") return # 验证文件存在性 if not Path(c_file_path).exists(): self.log(f" 目标 C 文件不存在: {c_file_path}") return # ========== 【新增】准备日志文件(仅在执行模式)========== file_handler = None log_file_path = None if not dry_run: # 只有执行模式才记录到文件 timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") log_dir = Path(get_output_dir()) / "log" # 先转成 Path log_dir.mkdir(parents=True, exist_ok=True) log_file_path = log_dir / f"range_sync_{timestamp}.log" # 创建专用 FileHandler file_handler = logging.FileHandler(log_file_path, encoding='utf-8') file_handler.setFormatter( logging.Formatter('%(asctime)s [%(levelname)s] %(message)s', datefmt='%H:%M:%S') ) # 添加到 channel logger(与 UI 输出共存) target_logger = logging.getLogger("channel") target_logger.addHandler(file_handler) self.log(f" 日志文件已创建: {log_file_path}") try: mode = "预览模式" if dry_run else "执行模式" self.log(f" 开始同步... ({mode})") self.log(f" 修改文件: {c_file_path}") # 创建同步器实例 sync = CLMRangeSynchronizer( c_file_path=c_file_path, dry_run=dry_run ) was_modified = sync.run() if dry_run: if was_modified: self.log("发现需要更新的内容,确认无误后可点击【执行同步】") else: self.log("所有 RANGE 已存在,无需修改") else: if was_modified: self.log(f"同步成功!已更新 {c_file_path}") self.log(f"备份已保存为 {c_file_path}.bak") else: self.log("文件已是最新,无需修改") except Exception as e: self.log(f"同步失败: {str(e)}") import traceback tb_msg = traceback.format_exc() self.log(f"错误详情:\n{tb_msg}") # 即使出错也要确保 file_handler 正确移除 raise finally: # ========== 【关键】清理资源:移除并关闭 FileHandler ========== if file_handler: try: # 确保缓冲区写入磁盘 file_handler.flush() file_handler.close() logging.getLogger("channel").removeHandler(file_handler) self.log("日志文件已关闭") except Exception as e: print(f"Warning: failed to close file handler: {e}") # 可选:在 UI 显示最终提示 if not dry_run and log_file_path: self.log(f"完整日志已保存至:\n{log_file_path}") def run_full_process(self): """一键完成:解析 Excel → 生成 manifest → 同步到 .c 文件""" reply = QMessageBox.question( self, "确认执行", "是否要执行【解析Excel + 更新C文件】全流程?\n\n" "建议先使用【预览同步】检查变更。", QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No ) if reply != QMessageBox.StandardButton.Yes: return self.run_parse() if hasattr(self.generator, 'last_config') and self.generator.last_config: self.run_range_sync(dry_run=False) else: self.log(" 解析失败,无法继续同步") if __name__ == '__main__': app = QApplication([]) try: window = CLMGeneratorUI() window.show() sys.exit(app.exec()) except Exception as e: msg = QMessageBox() msg.setWindowTitle("严重错误") msg.setText(f"程序启动失败:\n\n{type(e).__name__}: {e}\n\n详情查看日志或联系开发者。") msg.setIcon(QMessageBox.Critical) msg.exec() print(f"Critical error: {e}") 找到要修改的地方
10-22
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值