Freeze file header

本文介绍如何使用Oracle的ALTER TABLESPACE命令进行在线热备份,并详细解释了热备份过程中数据文件的状态变化及redo日志的生成机制。
SQL> select * from v$version where rownum=1;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
我们可以使用alter tablespace ... begin backup将表空间置于联机备份模式,然后用操作系统命令进行数据文件的物理拷贝,达到备份的目的,这个过程中数据文件还是照样联机,并进行正常的数据插入,但会导致比平常更多的REDO记录的产生。
产生较多的REDO记录是由热备引起的,因为在热备过程中,我们采用copy/ocopy命令,这个是属于操作系统的命令,他和Oracle是不相关的,不能和Oracle的内部进程如dbwr进行交互,因为操作系统读取数据文件时,他的IO尺寸并不是block size的大小,一般会更小,这样会导致一个数据块被读取多次,而每次获取的部分都不一致(数据不断更新,产生split block ),为了恢复这种断裂的热备块,Oracle进行了数据块前映象这个操作,对于backup模式的数据文件块,在第一次受到DML影响时,先将数据块整个COPY到REDO中,后续的DML在进行UNDO,正常REDO信息的记录,当恢复数据文件时,会先应用最先的数据块前映像,然后才是后续的REDO记录信息,更多的日志记录就是这个前映像产生的,这个不能和UNDO弄混淆,他是整个数据块,而不是简单的行记录,由于Oracle本身不知道在拷贝时那些块可能出现热备,所以只要是BACKUP期间有DML的块,就按照上面的情况处理,所以如果在backup期间运行大量的批处理程序,日志信息会集聚增多, 这个主要是以后数据文件做恢复的起始SCN,在BEGIN BACKUP下达后,系统要对表空间执行检查点,并将该检查点前的所有事务应用都固化到数据文件,然后冻结这个SCN,直到使用END BACKUP,使备份过程结束,再更新为新的SCN,冻结的原因是因为使用操作系统命令拷贝数据文件时,他不能保证第一个读取的块就是数据文件头,如果不冻结,则可能从备份开始,已经多次更新了文件头,而此时文件头还没有被拷贝,这样等文件头被拷贝后,他的SCN已经远远大于了数据文件中其他数据块的SCN,这样从文件头的SCN来定位恢复起点就不现实了。(http://blog.itpub.net/7728585/viewspace-545610)
下面我们模拟这个过程(以system表空间为例):
SQL> alter session set events 'immediate trace name file_hdrs  level 10';
会话已更改。
SQL> select value from v$diag_info where name='Default Trace File';
VALUE
--------------------------------------------------------------------------------
/u01/app/oracle/diag/rdbms/orcl3939/orcl3939/trace/orcl3939_ora_4862.trc

DATA FILE #1: 
  name #7: /u01/app/oracle/oradata/orcl3939/system01.dbf
creation size=0 block size=8192 status=0xe head=7 tail=7 dup=1
 tablespace 0, index=1 krfil=1 prev_file=0
 unrecoverable scn: 0x0000.00000000 01/01/1988 00:00:00
 Checkpoint cnt:1223 scn: 0x0000.0080ab79 05/22/2015 23:01:37
 Stop scn: 0xffff.ffffffff 05/21/2015 12:23:57
 Creation Checkpointed at scn:  0x0000.00000007 08/13/2009 23:00:53
 thread:0 rba:(0x0.0.0)
 ...
...
 Offline scn: 0x0000.000b8337 prev_range: 0
 Online Checkpointed at scn:  0x0000.000b8338 09/28/2014 17:41:34
 thread:1 rba:(0x1.2.0)
 ...
 ...
 Hot Backup end marker scn: 0x0000.00000000
 aux_file is NOT DEFINED 
 Plugged readony: NO
 Plugin scnscn: 0x0000.00000000
 Plugin resetlogs scn/timescn: 0x0000.00000000 01/01/1988 00:00:00
 Foreign creation scn/timescn: 0x0000.00000000 01/01/1988 00:00:00
 Foreign checkpoint scn/timescn: 0x0000.00000000 01/01/1988 00:00:00
 Online move state: 0
 V10 STYLE FILE HEADER:
Compatibility Vsn = 186646528=0xb200000
Db ID=3848072073=0xe55ceb89, Db Name='ORCL3939'
Activation ID=0=0x0
Control Seq=17079=0x42b7, File size=103680=0x19500
File Number=1, Blksiz=8192, File Type=3 DATA
Tablespace #0 - SYSTEM  rel_fn:1 
Creation   at   scn: 0x0000.00000007 08/13/2009 23:00:53
Backup taken at scn: 0x0000.00773f1c 05/05/2015 19:12:20 thread:1
 reset logs count:0x333ab14e scn: 0x0000.000b8338
 prev reset logs count:0x296a3120 scn: 0x0000.00000001
 recovered at 05/20/2015 14:09:45
 status:0x2004 root dba:0x00400208 chkpt cnt:  1223 ctl cnt:1222
begin-hot-backup file size: 103680
Checkpointed at scn:  0x0000.0080ab79 05/22/2015 23:01:37
 thread:1 rba:(0x1ee.2.10)
....
....
======================================================================
SQL> alter tablespace system begin backup;
表空间已更改。
SQL> select * from v$backup where status='ACTIVE';


     FILE# STATUS                CHANGE# TIME
---------- ------------------ ---------- --------------
         1 ACTIVE                8440239 22-5月 -15

DATA FILE #1: 
  name #7: /u01/app/oracle/oradata/orcl3939/system01.dbf
creation size=0 block size=8192 status=0xe head=7 tail=7 dup=1
 tablespace 0, index=1 krfil=1 prev_file=0
 unrecoverable scn: 0x0000.00000000 01/01/1988 00:00:00
 Checkpoint cnt:1224 scn: 0x0000.0080c9af 05/22/2015 23:58:23
 Stop scn: 0xffff.ffffffff 05/21/2015 12:23:57
 Creation Checkpointed at scn:  0x0000.00000007 08/13/2009 23:00:53
 thread:0 rba:(0x0.0.0)
....
....
 aux_file is NOT DEFINED 
 Plugged readony: NO
 Plugin scnscn: 0x0000.00000000
 Plugin resetlogs scn/timescn: 0x0000.00000000 01/01/1988 00:00:00
 Foreign creation scn/timescn: 0x0000.00000000 01/01/1988 00:00:00
 Foreign checkpoint scn/timescn: 0x0000.00000000 01/01/1988 00:00:00
 Online move state: 0
 V10 STYLE FILE HEADER:
Compatibility Vsn = 186646528=0xb200000
Db ID=3848072073=0xe55ceb89, Db Name='ORCL3939'
Activation ID=0=0x0
Control Seq=17091=0x42c3, File size=103680=0x19500
File Number=1, Blksiz=8192, File Type=3 DATA
Tablespace #0 - SYSTEM  rel_fn:1 
Creation   at   scn: 0x0000.00000007 08/13/2009 23:00:53
Backup taken at scn: 0x0000.0080c9af 05/22/2015 23:58:23 thread:1
 reset logs count:0x333ab14e scn: 0x0000.000b8338
 prev reset logs count:0x296a3120 scn: 0x0000.00000001
 recovered at 05/20/2015 14:09:45
 status:0x2001 root dba:0x00400208  chkpt cnt: 1224 ctl cnt:1223
begin-hot-backup file size: 103680
Checkpointed at scn:  V10 STYLE FILE HEADER: 05/22/2015 23:58:23
 thread:1 rba:(0x1ee.fe0c.10)
 .....
.....
============================================================
SQL> alter tablespace system end backup;
表空间已更改。
SQL> select * from v$backup where status='ACTIVE';
未选定行
DATA FILE #1: 
  name #7: /u01/app/oracle/oradata/orcl3939/system01.dbf
creation size=0 block size=8192 status=0xe head=7 tail=7 dup=1
 tablespace 0, index=1 krfil=1 prev_file=0
 unrecoverable scn: 0x0000.00000000 01/01/1988 00:00:00
 Checkpoint cnt:1225 scn: 0x0000.0080c9af 05/22/2015 23:58:23
 Stop scn: 0xffff.ffffffff 05/21/2015 12:23:57
 Creation Checkpointed at scn:  0x0000.00000007 08/13/2009 23:00:53
 thread:0 rba:(0x0.0.0)
 .....
.....
 Hot Backup end marker scn: 0x0000.00000000
 aux_file is NOT DEFINED 
 Plugged readony: NO
 Plugin scnscn: 0x0000.00000000
 Plugin resetlogs scn/timescn: 0x0000.00000000 01/01/1988 00:00:00
 Foreign creation scn/timescn: 0x0000.00000000 01/01/1988 00:00:00
 Foreign checkpoint scn/timescn: 0x0000.00000000 01/01/1988 00:00:00
 Online move state: 0
 V10 STYLE FILE HEADER:
Compatibility Vsn = 186646528=0xb200000
Db ID=3848072073=0xe55ceb89, Db Name='ORCL3939'
Activation ID=0=0x0
Control Seq=17097=0x42c9, File size=103680=0x19500
File Number=1, Blksiz=8192, File Type=3 DATA
Tablespace #0 - SYSTEM  rel_fn:1 
Creation   at   scn: 0x0000.00000007 08/13/2009 23:00:53
Backup taken at scn: 0x0000.0080c9af 05/22/2015 23:58:23 thread:1
 reset logs count:0x333ab14e scn: 0x0000.000b8338
 prev reset logs count:0x296a3120 scn: 0x0000.00000001
 recovered at 05/20/2015 14:09:45
 status:0x2004 root dba:0x00400208  chkpt cnt: 1225 ctl cnt:1224
begin-hot-backup file size: 103680
Checkpointed at scn:  0x0000.0080c9af 05/22/2015 23:58:23
 thread:1 rba:(0x1ee.fe0c.10)
 .....
.....
Backup Checkpointed at scn:  0x0000.0080c9af 05/22/2015 23:58:23
 thread:1 rba:(0x1ee.fe0c.10)
....
....
=========================================
DATA FILE #1: 
这里的内容是来自控制文件
V10 STYLE FILE HEADER:
这里的内容是来自数据文件头
数据库一致性检验也是通过比较数据文件头和控制文件里的信息,
首先是比较数据文件头里记录的ckpt cnt是否和控制文件记录的ckpt cnt相等,如果相等,则进行下一步的检验,
比较数据文件头的开始checkpoint  scn是否和控制文件的结束checkpoint scn一致,一致则打开数据库,否则进行恢复。
上面通过转储的三部分可以看出,热备后checkpoint scn到结束热备都没有发生改变,但是ckpt cnt没有被冻结,
在此过程中scn被冻结。
import pandas as pd from openpyxl import load_workbook # ✅ 修复:导入 load_workbook from openpyxl.styles import numbers import xlwings as xw import requests import time # 文件路径 file_path = r'reports\PON口码化情况清单.xlsx' file_path1 = r'reports\OBD尾纤贴码分类报表.xlsx' # 读取前两个 sheet,跳过前3行,保留表头 sheet1 = pd.read_excel(file_path, sheet_name=0, skiprows=2, header=0) sheet2 = pd.read_excel(file_path, sheet_name=1, skiprows=2, header=0) # 合并两个子表 combined_df = pd.concat([sheet1, sheet2], ignore_index=True) # 查看结果 # 保存为新的 Excel 文件 combined_df.to_excel('combined_data_with_header.xlsx', index=False) # 读取前两个 sheet,跳过前3行,保留表头 sheet_1 = pd.read_excel(file_path1, sheet_name=0, skiprows=2, header=0) sheet_2 = pd.read_excel(file_path1, sheet_name=1, skiprows=2, header=0) sheet_3 = pd.read_excel(file_path1, sheet_name=2, skiprows=2, header=0) sheet_4 = pd.read_excel(file_path1, sheet_name=3, skiprows=2, header=0) sheet_5 = pd.read_excel(file_path1, sheet_name=4, skiprows=2, header=0) sheet_6 = pd.read_excel(file_path1, sheet_name=5, skiprows=2, header=0) sheet_7 = pd.read_excel(file_path1, sheet_name=6, skiprows=2, header=0) sheet_8 = pd.read_excel(file_path1, sheet_name=7, skiprows=2, header=0) sheet_9 = pd.read_excel(file_path1, sheet_name=8, skiprows=2, header=0) sheet_10 = pd.read_excel(file_path1, sheet_name=9, skiprows=2, header=0) # 合并两个子表 combined_df_1 = pd.concat([sheet_1, sheet_2, sheet_3, sheet_4, sheet_5, sheet_6, sheet_7, sheet_8, sheet_9, sheet_10], ignore_index=True) # 查看结果 # 保存为新的 Excel 文件 combined_df_1.to_excel('combined_data_with_header_1.xlsx', index=False) #给OBD表添加添加公式=X&Y # 打开 Excel 文件 file_path = 'combined_data_with_header_1.xlsx' wb = load_workbook(file_path) ws = wb.active # 确定从第 2 行开始写入公式(假设第 1 行是标题) for row in range(2, ws.max_row + 1): ws[f'Z{row}'] = f'=X{row}&Y{row}' # 保存修改 wb.save('formula_added_file_1.xlsx') print("✅ 已OBD表添加添加公式,并保存到 'formula_added_file_1.xlsx'") time.sleep(2) # 打开 Excel 文件 file_path = 'formula_added_file_1.xlsx' wb = load_workbook(file_path) ws = wb.active # 设置单元格内容 ws['Z1'] = "合并" # 保存文件 wb.save('formula_added_file_1.xlsx') print("✅ 已添加标题,保存为 'formula_added_file_1.xlsx'") # 读取 Excel 文件 file_path = 'combined_data_with_header.xlsx' df = pd.read_excel(file_path) # 筛选第 8 列(列索引为 7)为空的行 blank_rows = df[df.iloc[:, 7].isna()] # 查看筛选结果 # 保存到新文件 blank_rows.to_excel('filtered_blank_rows.xlsx', index=False) print("✅ 已成功筛选并保留第 8 列为空的行,保存到 'filtered_blank_rows.xlsx'") #给filtered_blank_rows.xlsx添加公式 # 打开 Excel 文件 file_path = 'filtered_blank_rows.xlsx' wb = load_workbook(file_path) ws = wb.active # 确定从第 2 行开始写入公式(假设第 1 行是标题) for row in range(2, ws.max_row + 1): ws[f'K{row}'] = f'=C{row}&D{row}' ws[f'L{row}'] = f'=IF(G{row}="A","机箱异常","用户未码")' ws[f'M{row}'] = f'=XLOOKUP(K{row},机箱参考!Z:Z,机箱参考!E:E)' # 保存修改 wb.save('formula_added_file.xlsx') print("✅ 已添加公式,并保存到 'formula_added_file.xlsx'") # 打开 Excel 文件 file_path = 'formula_added_file.xlsx' wb = load_workbook(file_path) ws = wb.active # 设置单元格内容 ws['K1'] = "合并" ws['L1'] = "合并" ws['M1'] = "参考位置" # 保存文件 wb.save('merged_header_file.xlsx') print("✅ 已添加标题,保存为 'merged_header_file.xlsx'") from openpyxl import load_workbook # 文件路径 source_file = 'formula_added_file_1.xlsx' target_file = 'merged_header_file.xlsx' # 加载源文件和目标文件 source_wb = load_workbook(source_file) target_wb = load_workbook(target_file) # 获取源表数据 source_sheet = source_wb.active # 检查目标文件是否存在 "Sheet2",若不存在则创建 if "Sheet2" in target_wb.sheetnames: target_sheet = target_wb["Sheet2"] else: target_sheet = target_wb.create_sheet("Sheet2") print("⚠️ Sheet2 不存在,已自动创建") # 获取目标表最后一行的下一行 start_row = target_sheet.max_row + 1 # 将源表数据追加写入目标表 for row in source_sheet.iter_rows(values_only=True): target_sheet.append(row) # 保存目标文件 target_wb.save(target_file) print("✅ 数据已成功追加到目标文件的 Sheet2 中") from openpyxl import load_workbook # 文件路径 file_path = 'merged_header_file.xlsx' # 加载工作簿 wb = load_workbook(file_path) # 获取当前工作表名称列表 sheet_names = wb.sheetnames # 打印当前工作表名 print("当前工作簿中的工作表名称:", sheet_names) # 检查是否存在名为 "Sheet2" 的工作表 if "Sheet2" in sheet_names: # 获取该工作表 ws = wb["Sheet2"] # 重命名为 "机箱参考" ws.title = "机箱参考" print("✅ 工作表 'Sheet2' 已重命名为 '机箱参考'") else: print("❌ 错误:工作簿中不存在名为 'Sheet2' 的工作表") # 保存修改 wb.save(file_path) # 原始 .xls 文件路径 xls_file = 'reports\宽带资源情况表_旧.xlsx' xlsx_file = '宽带资源情况表_旧.xlsx' # 使用 pandas 读取 .xls 文件(依赖 xlrd) df = pd.read_excel(xls_file) # 保存为 .xlsx 文件(使用 openpyxl 引擎) df.to_excel(xlsx_file, index=False, engine='openpyxl') print("✅ .xls 文件已成功转换为 .xlsx 格式") from openpyxl import load_workbook # 文件路径 source_file = r'宽带资源情况表_旧.xlsx' target_file = 'merged_header_file.xlsx' # 加载源文件和目标文件 source_wb = load_workbook(source_file) target_wb = load_workbook(target_file) # 获取源表数据 source_sheet = source_wb.active # 检查目标文件是否存在 "Sheet2",若不存在则创建 if "Sheet2" in target_wb.sheetnames: target_sheet = target_wb["Sheet2"] else: target_sheet = target_wb.create_sheet("Sheet2") print("⚠️ Sheet2 不存在,已自动创建") # 获取目标表最后一行的下一行 start_row = target_sheet.max_row + 1 # 将源表数据追加写入目标表 for row in source_sheet.iter_rows(values_only=True): target_sheet.append(row) # 保存目标文件 target_wb.save(target_file) print("✅ 数据已成功追加到目标文件的 Sheet2 中") from openpyxl import load_workbook # 文件路径 file_path = 'merged_header_file.xlsx' # 加载工作簿 wb = load_workbook(file_path) # 获取当前工作表名称列表 sheet_names = wb.sheetnames # 打印当前工作表名 print("当前工作簿中的工作表名称:", sheet_names) # 检查是否存在名为 "Sheet2" 的工作表 if "Sheet2" in sheet_names: # 获取该工作表 ws = wb["Sheet2"] # 重命名为 "日调度表1" ws.title = "日调度表1" print("✅ 工作表 'Sheet2' 已重命名为 '日调度表1'") else: print("❌ 错误:工作簿中不存在名为 'Sheet2' 的工作表") # 保存修改 wb.save(file_path) # 原始 .xls 文件路径 xls_file = r'reports\宽带资源情况表_新.xlsx' xlsx_file = '宽带资源情况表_新.xlsx' # 使用 pandas 读取 .xls 文件(依赖 xlrd) df = pd.read_excel(xls_file) # 保存为 .xlsx 文件(使用 openpyxl 引擎) df.to_excel(xlsx_file, index=False, engine='openpyxl') print("✅ .xls 文件已成功转换为 .xlsx 格式") from openpyxl import load_workbook # 文件路径 source_file = '宽带资源情况表_新.xlsx' target_file = 'merged_header_file.xlsx' # 加载源文件和目标文件 source_wb = load_workbook(source_file) target_wb = load_workbook(target_file) # 获取源表数据 source_sheet = source_wb.active # 检查目标文件是否存在 "Sheet2",若不存在则创建 if "Sheet2" in target_wb.sheetnames: target_sheet = target_wb["Sheet2"] else: target_sheet = target_wb.create_sheet("Sheet2") print("⚠️ Sheet2 不存在,已自动创建") # 获取目标表最后一行的下一行 start_row = target_sheet.max_row + 1 # 将源表数据追加写入目标表 for row in source_sheet.iter_rows(values_only=True): target_sheet.append(row) # 保存目标文件 target_wb.save(target_file) print("✅ 数据已成功追加到目标文件的 Sheet2 中") from openpyxl import load_workbook # 文件路径 file_path = 'merged_header_file.xlsx' # 加载工作簿 wb = load_workbook(file_path) # 获取当前工作表名称列表 sheet_names = wb.sheetnames # 打印当前工作表名 print("当前工作簿中的工作表名称:", sheet_names) # 检查是否存在名为 "Sheet2" 的工作表 if "Sheet2" in sheet_names: # 获取该工作表 ws = wb["Sheet2"] # 重命名为 "日调度表2" ws.title = "日调度表2" print("✅ 工作表 'Sheet2' 已重命名为 '日调度表2'") else: print("❌ 错误:工作簿中不存在名为 'Sheet2' 的工作表") # 保存修改 wb.save(file_path) # 原始 .xls 文件路径 xls_file = r'reports\日调度表分光器.xlsx' xlsx_file = '日调度表分光器.xlsx' # 使用 pandas 读取 .xls 文件(依赖 xlrd) df = pd.read_excel(xls_file) # 保存为 .xlsx 文件(使用 openpyxl 引擎) df.to_excel(xlsx_file, index=False, engine='openpyxl') print("✅ .xls 文件已成功转换为 .xlsx 格式") from openpyxl import load_workbook # 文件路径 source_file = '日调度表分光器.xlsx' target_file = 'merged_header_file.xlsx' # 加载源文件和目标文件 source_wb = load_workbook(source_file) target_wb = load_workbook(target_file) # 获取源表数据 source_sheet = source_wb.active # 检查目标文件是否存在 "Sheet2",若不存在则创建 if "Sheet2" in target_wb.sheetnames: target_sheet = target_wb["Sheet2"] else: target_sheet = target_wb.create_sheet("Sheet2") print("⚠️ Sheet2 不存在,已自动创建") # 获取目标表最后一行的下一行 start_row = target_sheet.max_row + 1 # 将源表数据追加写入目标表 for row in source_sheet.iter_rows(values_only=True): target_sheet.append(row) # 保存目标文件 target_wb.save(target_file) print("✅ 数据已成功追加到目标文件的 Sheet2 中") from openpyxl import load_workbook # 文件路径 file_path = 'merged_header_file.xlsx' # 加载工作簿 wb = load_workbook(file_path) # 获取当前工作表名称列表 sheet_names = wb.sheetnames # 打印当前工作表名 print("当前工作簿中的工作表名称:", sheet_names) # 检查是否存在名为 "Sheet2" 的工作表 if "Sheet2" in sheet_names: # 获取该工作表 ws = wb["Sheet2"] # 重命名为 "日调度表分光器" ws.title = "日调度表分光器" print("✅ 工作表 'Sheet2' 已重命名为 '日调度表分光器'") else: print("❌ 错误:工作簿中不存在名为 'Sheet2' 的工作表") # 保存修改 wb.save(file_path) from openpyxl import load_workbook # 文件路径 source_file = 'tongbao.xlsx' target_file = 'merged_header_file.xlsx' # 加载源文件和目标文件 source_wb = load_workbook(source_file) target_wb = load_workbook(target_file) # 获取源表数据 source_sheet = source_wb.active # 检查目标文件是否存在 "Sheet2",若不存在则创建 if "Sheet2" in target_wb.sheetnames: target_sheet = target_wb["Sheet2"] else: target_sheet = target_wb.create_sheet("Sheet2") print("⚠️ Sheet2 不存在,已自动创建") # 获取目标表最后一行的下一行 start_row = target_sheet.max_row + 1 # 将源表数据追加写入目标表 for row in source_sheet.iter_rows(values_only=True): target_sheet.append(row) # 保存目标文件 target_wb.save(target_file) print("✅ 数据已成功追加到目标文件的 Sheet2 中") from openpyxl import load_workbook # 文件路径 file_path = 'merged_header_file.xlsx' # 加载工作簿 wb = load_workbook(file_path) # 获取当前工作表名称列表 sheet_names = wb.sheetnames # 打印当前工作表名 print("当前工作簿中的工作表名称:", sheet_names) # 检查是否存在名为 "Sheet2" 的工作表 if "Sheet2" in sheet_names: # 获取该工作表 ws = wb["Sheet2"] # 重命名为 "通报" ws.title = "通报" print("✅ 工作表 'Sheet2' 已重命名为 '通报'") else: print("❌ 错误:工作簿中不存在名为 'Sheet2' 的工作表") # 保存修改 wb.save(file_path) from openpyxl import load_workbook from openpyxl.styles import NamedStyle # 文件路径 file_path = 'merged_header_file.xlsx' # 加载工作簿 wb = load_workbook(file_path) # 检查并创建百分比样式 percent_style_name = 'Percent 2 Decimal' if percent_style_name not in wb.named_styles: percent_style = NamedStyle(name=percent_style_name) percent_style.number_format = '0.00%' wb.add_named_style(percent_style) # 获取名为 "通报" 的工作表 ws = wb['通报'] # 假设从第3行开始插入公式 start_row = 3 max_row = ws.max_row # 插入公式并设置格式 for row in range(start_row, max_row + 1): ws[f'C{row}'] = f'=XLOOKUP(A{row},日调度表分光器!A:A,日调度表分光器!C:C)' ws[f'D{row}'] = f'=XLOOKUP(A{row},日调度表分光器!A:A,日调度表分光器!E:E)' ws[f'B{row}'] = f'=XLOOKUP(A{row},日调度表分光器!A:A,日调度表分光器!B:B)' ws[f'E{row}'] = f'=XLOOKUP(A{row},日调度表2!B:B,日调度表2!F:F)' ws[f'F{row}'] = f'=XLOOKUP(A{row},日调度表1!B:B,日调度表1!F:F)' ws[f'H{row}'] = f'=COUNTIF(Sheet1!B:B, A{row})' # G列:插入公式并设置百分比格式 cell = ws[f'G{row}'] cell.value = f'=E{row}-F{row}' cell.style = percent_style_name # 在最后一行写入 SUM 公式(在 H 列) last_row = max_row ws[f'H{last_row}'] = f'=SUM(H{start_row}:H{max_row-1})' # 保存修改 wb.save(file_path) print("✅ 公式已成功插入到 '通报' 表,G 列设置为百分比格式,H 列最后一行为 SUM 公式") from openpyxl import load_workbook from openpyxl.styles import Font, Alignment, Border, Side, PatternFill # 文件路径 file_path = r'C:\Users\Lt\Desktop\test\merged_header_file.xlsx' # 原始文件路径 output_path = r'C:\Users\Lt\Desktop\test\通报_美化后.xlsx' # 输出文件路径 # 加载工作簿和子表 wb = load_workbook(file_path) sheet = wb["通报"] # 选择名为“通报”的子表 # 定义通用样式 normal_font = Font(name='微软雅黑', size=11) title_font = Font(name='微软雅黑', size=11, bold=True, color="FFFFFF") # 白色字体 alignment_center = Alignment(horizontal='center', vertical='center') thin_border = Border( left=Side(style='thin'), right=Side(style='thin'), top=Side(style='thin'), bottom=Side(style='thin') ) title_fill = PatternFill(start_color='4F94CD', end_color='4F94CD', fill_type='solid') # 蓝灰色背景 # 1. 设置标题行样式(假设标题在第1行) for cell in sheet[1]: cell.font = title_font cell.alignment = alignment_center cell.fill = title_fill cell.border = thin_border # 2. 设置其余单元格样式 for row in sheet.iter_rows(min_row=2): # 从第2行开始 for cell in row: cell.font = normal_font cell.alignment = alignment_center cell.border = thin_border #3. 设置所有列的宽度为 20 个字符 for col in sheet.columns: column_letter = col[0].column_letter # 获取列的字母(如 A, B, C) sheet.column_dimensions[column_letter].width = 20 # 4. 设置统一行高 for row in sheet.iter_rows(): sheet.row_dimensions[row[0].row].height = 18 # 行高设为18 # 5. 冻结首行(冻结第一行) sheet.freeze_panes = 'A2' # 保存美化后的文件 wb.save(output_path) print(f"✅ 美化完成,文件已保存至:{output_path}") from openpyxl import load_workbook from openpyxl.styles import Border, Side # 加载 Excel 文件 file_path = r'C:\Users\Lt\Desktop\test\通报_美化后.xlsx' # 替换为你的文件路径 wb = load_workbook(file_path) sheet = wb["Sheet1"] # 指定工作表名称 # 设置列宽 column_widths = { 'A': 7, 'B': 7, 'C': 14, 'D': 9, 'E': 38, 'F': 38, 'G': 14, 'H': 14, 'I': 14, 'J': 30, 'K': 22, 'L': 12, 'M': 85 } for col, width in column_widths.items(): sheet.column_dimensions[col].width = width # 定义统一的边框样式(细实线) thin_border = Border( left=Side(style='thin'), right=Side(style='thin'), top=Side(style='thin'), bottom=Side(style='thin') ) # 为所有已使用的单元格添加边框 for row in sheet.iter_rows(): for cell in row: cell.border = thin_border # 保存文件 output_path = r'your_excel_file_fixed_width_with_border.xlsx' wb.save(output_path) print(f"✅ 列宽已设置,边框已添加,文件已保存至:{output_path}") import win32com.client as win32 from PIL import ImageGrab import os import time # 启动 Excel 应用程序 excel = win32.Dispatch("Excel.Application") excel.Visible = True # 必须设为 True 才能截图 excel.DisplayAlerts = False # 禁止弹窗 # 打开工作簿 file_path = r'C:\Users\Lt\Desktop\test\your_excel_file_fixed_width_with_border.xlsx' wb = excel.Workbooks.Open(file_path) sheet = wb.Sheets("Sheet1") sheet.Activate() # 启用筛选并筛选 B 列中 "港南区" sheet.Rows(1).AutoFilter() # 启用筛选(第一行为标题) filter_values = ["港南区"] sheet.Range("B1").AutoFilter(Field=2, Criteria1=filter_values, Operator=7) # OR 多条件 # 等待刷新界面 time.sleep(1) # === 动态获取筛选后的可见范围(关键改进)=== # 使用 SpecialCells 获取所有可见单元格 try: # 获取列 A 中有内容的范围,然后找出其可见部分 used_col_A = sheet.Columns("A").SpecialCells(11) # 11 = xlCellTypeVisible # used_col_A 是一个 Range 对象,包含所有 A 列中可见的单元格 # 获取该范围的外接矩形(最小包围盒) first_row = used_col_A.Row # 第一个可见数据行(可能是第2行) last_row = used_col_A.Row + used_col_A.Rows.Count - 1 if used_col_A.Rows.Count > 1 else used_col_A.Row # 但我们通常要从标题行开始截图(第1行) header_row = 1 visible_last_row = max(header_row + 1, last_row) # 至少包含一行数据 except Exception as e: print(f"⚠️ 无法准确获取可见范围,回退到默认方式: {e}") visible_last_row = 100 # 回退值 # 定义列范围(A 到 M) col_start = "A" col_end = "M" # 构建最终截图区域:从 A1 到 M{visible_last_row} range_to_capture = sheet.Range(f"{col_start}1:{col_end}{visible_last_row}") print(f"✅ 截图范围已设置为: {range_to_capture.Address}") # 输出如 $A$1:$M$23 # 将区域复制为图片 range_to_capture.CopyPicture( Appearance=1, # xlScreen Format=2 # xlPicture ) # 等待剪贴板就绪 time.sleep(0.5) # 获取剪贴板图像 image = ImageGrab.grabclipboard() if image is None: print("❌ 剪贴板无图像!请确认 CopyPicture 是否成功。") else: # 保存图片 output_folder = r'C:\Users\Lt\Desktop\test\tuisong' os.makedirs(output_folder, exist_ok=True) image_path = os.path.join(output_folder, '港南区.png') image.save(image_path, "PNG") print(f"✅ 图片已保存至: {image_path}") # 保存工作簿副本(可选) output_xlsx_path = r'C:\Users\Lt\Desktop\test\tuisong\港南区.xlsx' wb.SaveAs(output_xlsx_path) wb.Close() excel.Quit() print(f"✅ 筛选港南区并截图完成,结果已粘贴至 Excel 文件。") import win32com.client as win32 from PIL import ImageGrab import os import time # 启动 Excel 应用程序 excel = win32.Dispatch("Excel.Application") excel.Visible = True # 必须设为 True 才能截图 excel.DisplayAlerts = False # 禁止弹窗 # 打开工作簿 file_path = r'C:\Users\Lt\Desktop\test\your_excel_file_fixed_width_with_border.xlsx' wb = excel.Workbooks.Open(file_path) sheet = wb.Sheets("Sheet1") sheet.Activate() # 启用筛选并筛选 B 列中 "港北区" sheet.Rows(1).AutoFilter() # 启用筛选(第一行为标题) filter_values = ["港北区"] sheet.Range("B1").AutoFilter(Field=2, Criteria1=filter_values, Operator=7) # OR 多条件 # 等待刷新界面 time.sleep(1) # === 动态获取筛选后的可见范围(关键改进)=== # 使用 SpecialCells 获取所有可见单元格 try: # 获取列 A 中有内容的范围,然后找出其可见部分 used_col_A = sheet.Columns("A").SpecialCells(11) # 11 = xlCellTypeVisible # used_col_A 是一个 Range 对象,包含所有 A 列中可见的单元格 # 获取该范围的外接矩形(最小包围盒) first_row = used_col_A.Row # 第一个可见数据行(可能是第2行) last_row = used_col_A.Row + used_col_A.Rows.Count - 1 if used_col_A.Rows.Count > 1 else used_col_A.Row # 但我们通常要从标题行开始截图(第1行) header_row = 1 visible_last_row = max(header_row + 1, last_row) # 至少包含一行数据 except Exception as e: print(f"⚠️ 无法准确获取可见范围,回退到默认方式: {e}") visible_last_row = 100 # 回退值 # 定义列范围(A 到 M) col_start = "A" col_end = "M" # 构建最终截图区域:从 A1 到 M{visible_last_row} range_to_capture = sheet.Range(f"{col_start}1:{col_end}{visible_last_row}") print(f"✅ 截图范围已设置为: {range_to_capture.Address}") # 输出如 $A$1:$M$23 # 将区域复制为图片 range_to_capture.CopyPicture( Appearance=1, # xlScreen Format=2 # xlPicture ) # 等待剪贴板就绪 time.sleep(0.5) # 获取剪贴板图像 image = ImageGrab.grabclipboard() if image is None: print("❌ 剪贴板无图像!请确认 CopyPicture 是否成功。") else: # 保存图片 output_folder = r'C:\Users\Lt\Desktop\test\tuisong' os.makedirs(output_folder, exist_ok=True) image_path = os.path.join(output_folder, '港北区.png') image.save(image_path, "PNG") print(f"✅ 图片已保存至: {image_path}") # 保存工作簿副本(可选) output_xlsx_path = r'C:\Users\Lt\Desktop\test\tuisong\港北区.xlsx' wb.SaveAs(output_xlsx_path) wb.Close() excel.Quit() print(f"✅ 筛选港北区并截图完成,结果已粘贴至 Excel 文件。") import win32com.client as win32 from PIL import ImageGrab import os import time # 启动 Excel 应用程序 excel = win32.Dispatch("Excel.Application") excel.Visible = True # 必须设为 True 才能截图 excel.DisplayAlerts = False # 禁止弹窗 # 打开工作簿 file_path = r'C:\Users\Lt\Desktop\test\your_excel_file_fixed_width_with_border.xlsx' wb = excel.Workbooks.Open(file_path) sheet = wb.Sheets("Sheet1") sheet.Activate() # 启用筛选并筛选 B 列中 "覃塘区" sheet.Rows(1).AutoFilter() # 启用筛选(第一行为标题) filter_values = ["覃塘区"] sheet.Range("B1").AutoFilter(Field=2, Criteria1=filter_values, Operator=7) # OR 多条件 # 等待刷新界面 time.sleep(1) # === 动态获取筛选后的可见范围(关键改进)=== # 使用 SpecialCells 获取所有可见单元格 try: # 获取列 A 中有内容的范围,然后找出其可见部分 used_col_A = sheet.Columns("A").SpecialCells(11) # 11 = xlCellTypeVisible # used_col_A 是一个 Range 对象,包含所有 A 列中可见的单元格 # 获取该范围的外接矩形(最小包围盒) first_row = used_col_A.Row # 第一个可见数据行(可能是第2行) last_row = used_col_A.Row + used_col_A.Rows.Count - 1 if used_col_A.Rows.Count > 1 else used_col_A.Row # 但我们通常要从标题行开始截图(第1行) header_row = 1 visible_last_row = max(header_row + 1, last_row) # 至少包含一行数据 except Exception as e: print(f"⚠️ 无法准确获取可见范围,回退到默认方式: {e}") visible_last_row = 100 # 回退值 # 定义列范围(A 到 M) col_start = "A" col_end = "M" # 构建最终截图区域:从 A1 到 M{visible_last_row} range_to_capture = sheet.Range(f"{col_start}1:{col_end}{visible_last_row}") print(f"✅ 截图范围已设置为: {range_to_capture.Address}") # 输出如 $A$1:$M$23 # 将区域复制为图片 range_to_capture.CopyPicture( Appearance=1, # xlScreen Format=2 # xlPicture ) # 等待剪贴板就绪 time.sleep(0.5) # 获取剪贴板图像 image = ImageGrab.grabclipboard() if image is None: print("❌ 剪贴板无图像!请确认 CopyPicture 是否成功。") else: # 保存图片 output_folder = r'C:\Users\Lt\Desktop\test\tuisong' os.makedirs(output_folder, exist_ok=True) image_path = os.path.join(output_folder, '覃塘区.png') image.save(image_path, "PNG") print(f"✅ 图片已保存至: {image_path}") # 保存工作簿副本(可选) output_xlsx_path = r'C:\Users\Lt\Desktop\test\tuisong\覃塘区.xlsx' wb.SaveAs(output_xlsx_path) wb.Close() excel.Quit() print(f"✅ 筛选覃塘区并截图完成,结果已粘贴至 Excel 文件。") import win32com.client as win32 from PIL import ImageGrab import os import time # 启动 Excel 应用程序 excel = win32.Dispatch("Excel.Application") excel.Visible = True # 必须设为 True 才能截图 excel.DisplayAlerts = False # 禁止弹窗 # 打开工作簿 file_path = r'C:\Users\Lt\Desktop\test\your_excel_file_fixed_width_with_border.xlsx' wb = excel.Workbooks.Open(file_path) sheet = wb.Sheets("Sheet1") sheet.Activate() # 启用筛选并筛选 B 列中 "平南县" sheet.Rows(1).AutoFilter() # 启用筛选(第一行为标题) filter_values = ["平南县"] sheet.Range("B1").AutoFilter(Field=2, Criteria1=filter_values, Operator=7) # OR 多条件 # 等待刷新界面 time.sleep(1) # === 动态获取筛选后的可见范围(关键改进)=== # 使用 SpecialCells 获取所有可见单元格 try: # 获取列 A 中有内容的范围,然后找出其可见部分 used_col_A = sheet.Columns("A").SpecialCells(11) # 11 = xlCellTypeVisible # used_col_A 是一个 Range 对象,包含所有 A 列中可见的单元格 # 获取该范围的外接矩形(最小包围盒) first_row = used_col_A.Row # 第一个可见数据行(可能是第2行) last_row = used_col_A.Row + used_col_A.Rows.Count - 1 if used_col_A.Rows.Count > 1 else used_col_A.Row # 但我们通常要从标题行开始截图(第1行) header_row = 1 visible_last_row = max(header_row + 1, last_row) # 至少包含一行数据 except Exception as e: print(f"⚠️ 无法准确获取可见范围,回退到默认方式: {e}") visible_last_row = 100 # 回退值 # 定义列范围(A 到 M) col_start = "A" col_end = "M" # 构建最终截图区域:从 A1 到 M{visible_last_row} range_to_capture = sheet.Range(f"{col_start}1:{col_end}{visible_last_row}") print(f"✅ 截图范围已设置为: {range_to_capture.Address}") # 输出如 $A$1:$M$23 # 将区域复制为图片 range_to_capture.CopyPicture( Appearance=1, # xlScreen Format=2 # xlPicture ) # 等待剪贴板就绪 time.sleep(0.5) # 获取剪贴板图像 image = ImageGrab.grabclipboard() if image is None: print("❌ 剪贴板无图像!请确认 CopyPicture 是否成功。") else: # 保存图片 output_folder = r'C:\Users\Lt\Desktop\test\tuisong' os.makedirs(output_folder, exist_ok=True) image_path = os.path.join(output_folder, '平南县.png') image.save(image_path, "PNG") print(f"✅ 图片已保存至: {image_path}") # 保存工作簿副本(可选) output_xlsx_path = r'C:\Users\Lt\Desktop\test\tuisong\平南县.xlsx' wb.SaveAs(output_xlsx_path) wb.Close() excel.Quit() print(f"✅ 筛选平南县并截图完成,结果已粘贴至 Excel 文件。") import win32com.client as win32 from PIL import ImageGrab import os import time # 启动 Excel 应用程序 excel = win32.Dispatch("Excel.Application") excel.Visible = True # 必须设为 True 才能截图 excel.DisplayAlerts = False # 禁止弹窗 # 打开工作簿 file_path = r'C:\Users\Lt\Desktop\test\your_excel_file_fixed_width_with_border.xlsx' wb = excel.Workbooks.Open(file_path) sheet = wb.Sheets("Sheet1") sheet.Activate() # 启用筛选并筛选 B 列中 "桂平市" sheet.Rows(1).AutoFilter() # 启用筛选(第一行为标题) filter_values = ["桂平市"] sheet.Range("B1").AutoFilter(Field=2, Criteria1=filter_values, Operator=7) # OR 多条件 # 等待刷新界面 time.sleep(1) # === 动态获取筛选后的可见范围(关键改进)=== # 使用 SpecialCells 获取所有可见单元格 try: # 获取列 A 中有内容的范围,然后找出其可见部分 used_col_A = sheet.Columns("A").SpecialCells(11) # 11 = xlCellTypeVisible # used_col_A 是一个 Range 对象,包含所有 A 列中可见的单元格 # 获取该范围的外接矩形(最小包围盒) first_row = used_col_A.Row # 第一个可见数据行(可能是第2行) last_row = used_col_A.Row + used_col_A.Rows.Count - 1 if used_col_A.Rows.Count > 1 else used_col_A.Row # 但我们通常要从标题行开始截图(第1行) header_row = 1 visible_last_row = max(header_row + 1, last_row) # 至少包含一行数据 except Exception as e: print(f"⚠️ 无法准确获取可见范围,回退到默认方式: {e}") visible_last_row = 100 # 回退值 # 定义列范围(A 到 M) col_start = "A" col_end = "M" # 构建最终截图区域:从 A1 到 M{visible_last_row} range_to_capture = sheet.Range(f"{col_start}1:{col_end}{visible_last_row}") print(f"✅ 截图范围已设置为: {range_to_capture.Address}") # 输出如 $A$1:$M$23 # 将区域复制为图片 range_to_capture.CopyPicture( Appearance=1, # xlScreen Format=2 # xlPicture ) # 等待剪贴板就绪 time.sleep(0.5) # 获取剪贴板图像 image = ImageGrab.grabclipboard() if image is None: print("❌ 剪贴板无图像!请确认 CopyPicture 是否成功。") else: # 保存图片 output_folder = r'C:\Users\Lt\Desktop\test\tuisong' os.makedirs(output_folder, exist_ok=True) image_path = os.path.join(output_folder, '桂平市.png') image.save(image_path, "PNG") print(f"✅ 图片已保存至: {image_path}") # 保存工作簿副本(可选) output_xlsx_path = r'C:\Users\Lt\Desktop\test\tuisong\桂平市.xlsx' wb.SaveAs(output_xlsx_path) wb.Close() excel.Quit() print(f"✅ 筛选桂平市并截图完成,结果已粘贴至 Excel 文件。") try: # 启动 Excel 应用 excel = win32.Dispatch("Excel.Application") excel.Visible = False excel.DisplayAlerts = False excel.ScreenUpdating = False # 打开 Excel 文件(请根据实际路径修改) file_path = r'C:\Users\Lt\Desktop\test\通报_美化后.xlsx' workbook = excel.Workbooks.Open(file_path) # 获取 "通报" 子表 sheet = workbook.Sheets("通报") # 获取数据区域 used_range = sheet.UsedRange # 复制数据区域为图片(xlScreen = 1, xlPicture = 2) used_range.CopyPicture(Appearance=1, Format=2) # 创建临时图表用于粘贴图片 chart_obj = sheet.ChartObjects().Add( Left=0, Top=0, Width=used_range.Width, Height=used_range.Height ) chart = chart_obj.Chart chart.Paste() # 粘贴图片到图表 # 设置图片保存路径(请根据实际路径修改) output_path = r'C:\Users\Lt\Desktop\test\tuisong\通报_截图.png' # 导出图表为图片 chart.Export(output_path, "PNG") # 清理资源 chart_obj.Delete() workbook.Close(SaveChanges=False) excel.Quit() print(f"✅ 数据截图已成功保存为:{output_path}") except Exception as e: print("❌ 出现错误:", str(e))提升运行速度并输出可运行
最新发布
09-24
import pandas as pd from openpyxl import load_workbook # ✅ 修复:导入 load_workbook from openpyxl.styles import numbers import xlwings as xw import requests import time # 文件路径 file_path = r'reports\PON口码化情况清单.xlsx' file_path1 = r'reports\OBD尾纤贴码分类报表.xlsx' # 读取前两个 sheet,跳过前3行,保留表头 sheet1 = pd.read_excel(file_path, sheet_name=0, skiprows=2, header=0) sheet2 = pd.read_excel(file_path, sheet_name=1, skiprows=2, header=0) # 合并两个子表 combined_df = pd.concat([sheet1, sheet2], ignore_index=True) # 查看结果 print("合并后的表格前5行:") print(combined_df.head()) # 保存为新的 Excel 文件 combined_df.to_excel('combined_data_with_header.xlsx', index=False) # 读取前两个 sheet,跳过前3行,保留表头 sheet_1 = pd.read_excel(file_path1, sheet_name=0, skiprows=2, header=0) sheet_2 = pd.read_excel(file_path1, sheet_name=1, skiprows=2, header=0) sheet_3 = pd.read_excel(file_path1, sheet_name=2, skiprows=2, header=0) sheet_4 = pd.read_excel(file_path1, sheet_name=3, skiprows=2, header=0) sheet_5 = pd.read_excel(file_path1, sheet_name=4, skiprows=2, header=0) sheet_6 = pd.read_excel(file_path1, sheet_name=5, skiprows=2, header=0) sheet_7 = pd.read_excel(file_path1, sheet_name=6, skiprows=2, header=0) sheet_8 = pd.read_excel(file_path1, sheet_name=7, skiprows=2, header=0) sheet_9 = pd.read_excel(file_path1, sheet_name=8, skiprows=2, header=0) sheet_10 = pd.read_excel(file_path1, sheet_name=9, skiprows=2, header=0) # 合并两个子表 combined_df_1 = pd.concat([sheet_1, sheet_2, sheet_3, sheet_4, sheet_5, sheet_6, sheet_7, sheet_8, sheet_9, sheet_10], ignore_index=True) # 查看结果 print("合并后的表格前5行:") print(combined_df_1.head()) # 保存为新的 Excel 文件 combined_df_1.to_excel('combined_data_with_header_1.xlsx', index=False) # 读取 Excel 文件 file_path = 'combined_data_with_header.xlsx' df = pd.read_excel(file_path) # 筛选第 8 列(列索引为 7)为空的行 blank_rows = df[df.iloc[:, 7].isna()] # 查看筛选结果 print("筛选出的第 8 列为空的行:") print(blank_rows) # 保存到新文件 blank_rows.to_excel('filtered_blank_rows.xlsx', index=False) print("✅ 已成功筛选并保留第 8 列为空的行,保存到 'filtered_blank_rows.xlsx'") from openpyxl import load_workbook # 打开 Excel 文件 file_path = 'combined_data_with_header_1.xlsx' wb = load_workbook(file_path) ws = wb.active # 确定从第 2 行开始写入公式(假设第 1 行是标题) for row in range(2, ws.max_row + 1): ws[f'Z{row}'] = f'=X{row}&Y{row}' # 保存修改 wb.save('formula_added_file_1.xlsx') print("✅ 已添加公式,并保存到 'formula_added_file_1.xlsx'") # 打开 Excel 文件 file_path = 'filtered_blank_rows.xlsx' wb = load_workbook(file_path) ws = wb.active # 确定从第 2 行开始写入公式(假设第 1 行是标题) for row in range(2, ws.max_row + 1): ws[f'K{row}'] = f'=C{row}&D{row}' ws[f'L{row}'] = f'=IF(G{row}="A","机箱异常","用户未码")' ws[f'M{row}'] = f'=XLOOKUP(K{row},机箱参考!Z:Z,机箱参考!E:E)' # 保存修改 wb.save('formula_added_file.xlsx') print("✅ 已添加公式,并保存到 'formula_added_file.xlsx'") from openpyxl import load_workbook from openpyxl.styles import Alignment # 打开 Excel 文件 file_path = 'formula_added_file.xlsx' wb = load_workbook(file_path) ws = wb.active # 设置单元格内容 ws['K1'] = "合并" ws['L1'] = "合并" ws['M1'] = "参考位置" # 保存文件 wb.save('merged_header_file.xlsx') print("✅ 已添加标题,保存为 'merged_header_file.xlsx'") from openpyxl import load_workbook # 文件路径 source_file = 'formula_added_file_1.xlsx' target_file = 'merged_header_file.xlsx' # 加载源文件和目标文件 source_wb = load_workbook(source_file) target_wb = load_workbook(target_file) # 获取源表数据 source_sheet = source_wb.active # 检查目标文件是否存在 "Sheet2",若不存在则创建 if "Sheet2" in target_wb.sheetnames: target_sheet = target_wb["Sheet2"] else: target_sheet = target_wb.create_sheet("Sheet2") print("⚠️ Sheet2 不存在,已自动创建") # 获取目标表最后一行的下一行 start_row = target_sheet.max_row + 1 # 将源表数据追加写入目标表 for row in source_sheet.iter_rows(values_only=True): target_sheet.append(row) # 保存目标文件 target_wb.save(target_file) print("✅ 数据已成功追加到目标文件的 Sheet2 中") from openpyxl import load_workbook # 文件路径 file_path = 'merged_header_file.xlsx' # 加载工作簿 wb = load_workbook(file_path) # 获取当前工作表名称列表 sheet_names = wb.sheetnames # 打印当前工作表名 print("当前工作簿中的工作表名称:", sheet_names) # 检查是否存在名为 "Sheet2" 的工作表 if "Sheet2" in sheet_names: # 获取该工作表 ws = wb["Sheet2"] # 重命名为 "机箱参考" ws.title = "机箱参考" print("✅ 工作表 'Sheet2' 已重命名为 '机箱参考'") else: print("❌ 错误:工作簿中不存在名为 'Sheet2' 的工作表") # 保存修改 wb.save(file_path) # 原始 .xls 文件路径 xls_file = 'reports\宽带资源情况表_旧.xlsx' xlsx_file = '宽带资源情况表_旧.xlsx' # 使用 pandas 读取 .xls 文件(依赖 xlrd) df = pd.read_excel(xls_file) # 保存为 .xlsx 文件(使用 openpyxl 引擎) df.to_excel(xlsx_file, index=False, engine='openpyxl') print("✅ .xls 文件已成功转换为 .xlsx 格式") from openpyxl import load_workbook # 文件路径 source_file = r'宽带资源情况表_旧.xlsx' target_file = 'merged_header_file.xlsx' # 加载源文件和目标文件 source_wb = load_workbook(source_file) target_wb = load_workbook(target_file) # 获取源表数据 source_sheet = source_wb.active # 检查目标文件是否存在 "Sheet2",若不存在则创建 if "Sheet2" in target_wb.sheetnames: target_sheet = target_wb["Sheet2"] else: target_sheet = target_wb.create_sheet("Sheet2") print("⚠️ Sheet2 不存在,已自动创建") # 获取目标表最后一行的下一行 start_row = target_sheet.max_row + 1 # 将源表数据追加写入目标表 for row in source_sheet.iter_rows(values_only=True): target_sheet.append(row) # 保存目标文件 target_wb.save(target_file) print("✅ 数据已成功追加到目标文件的 Sheet2 中") from openpyxl import load_workbook # 文件路径 file_path = 'merged_header_file.xlsx' # 加载工作簿 wb = load_workbook(file_path) # 获取当前工作表名称列表 sheet_names = wb.sheetnames # 打印当前工作表名 print("当前工作簿中的工作表名称:", sheet_names) # 检查是否存在名为 "Sheet2" 的工作表 if "Sheet2" in sheet_names: # 获取该工作表 ws = wb["Sheet2"] # 重命名为 "日调度表1" ws.title = "日调度表1" print("✅ 工作表 'Sheet2' 已重命名为 '日调度表1'") else: print("❌ 错误:工作簿中不存在名为 'Sheet2' 的工作表") # 保存修改 wb.save(file_path) # 原始 .xls 文件路径 xls_file = r'reports\宽带资源情况表_新.xlsx' xlsx_file = '宽带资源情况表_新.xlsx' # 使用 pandas 读取 .xls 文件(依赖 xlrd) df = pd.read_excel(xls_file) # 保存为 .xlsx 文件(使用 openpyxl 引擎) df.to_excel(xlsx_file, index=False, engine='openpyxl') print("✅ .xls 文件已成功转换为 .xlsx 格式") from openpyxl import load_workbook # 文件路径 source_file = '宽带资源情况表_新.xlsx' target_file = 'merged_header_file.xlsx' # 加载源文件和目标文件 source_wb = load_workbook(source_file) target_wb = load_workbook(target_file) # 获取源表数据 source_sheet = source_wb.active # 检查目标文件是否存在 "Sheet2",若不存在则创建 if "Sheet2" in target_wb.sheetnames: target_sheet = target_wb["Sheet2"] else: target_sheet = target_wb.create_sheet("Sheet2") print("⚠️ Sheet2 不存在,已自动创建") # 获取目标表最后一行的下一行 start_row = target_sheet.max_row + 1 # 将源表数据追加写入目标表 for row in source_sheet.iter_rows(values_only=True): target_sheet.append(row) # 保存目标文件 target_wb.save(target_file) print("✅ 数据已成功追加到目标文件的 Sheet2 中") from openpyxl import load_workbook # 文件路径 file_path = 'merged_header_file.xlsx' # 加载工作簿 wb = load_workbook(file_path) # 获取当前工作表名称列表 sheet_names = wb.sheetnames # 打印当前工作表名 print("当前工作簿中的工作表名称:", sheet_names) # 检查是否存在名为 "Sheet2" 的工作表 if "Sheet2" in sheet_names: # 获取该工作表 ws = wb["Sheet2"] # 重命名为 "日调度表2" ws.title = "日调度表2" print("✅ 工作表 'Sheet2' 已重命名为 '日调度表2'") else: print("❌ 错误:工作簿中不存在名为 'Sheet2' 的工作表") # 保存修改 wb.save(file_path) # 原始 .xls 文件路径 xls_file = r'reports\日调度表分光器.xlsx' xlsx_file = '日调度表分光器.xlsx' # 使用 pandas 读取 .xls 文件(依赖 xlrd) df = pd.read_excel(xls_file) # 保存为 .xlsx 文件(使用 openpyxl 引擎) df.to_excel(xlsx_file, index=False, engine='openpyxl') print("✅ .xls 文件已成功转换为 .xlsx 格式") from openpyxl import load_workbook # 文件路径 source_file = '1757905734429_admin.xlsx' target_file = 'merged_header_file.xlsx' # 加载源文件和目标文件 source_wb = load_workbook(source_file) target_wb = load_workbook(target_file) # 获取源表数据 source_sheet = source_wb.active # 检查目标文件是否存在 "Sheet2",若不存在则创建 if "Sheet2" in target_wb.sheetnames: target_sheet = target_wb["Sheet2"] else: target_sheet = target_wb.create_sheet("Sheet2") print("⚠️ Sheet2 不存在,已自动创建") # 获取目标表最后一行的下一行 start_row = target_sheet.max_row + 1 # 将源表数据追加写入目标表 for row in source_sheet.iter_rows(values_only=True): target_sheet.append(row) # 保存目标文件 target_wb.save(target_file) print("✅ 数据已成功追加到目标文件的 Sheet2 中") from openpyxl import load_workbook # 文件路径 file_path = 'merged_header_file.xlsx' # 加载工作簿 wb = load_workbook(file_path) # 获取当前工作表名称列表 sheet_names = wb.sheetnames # 打印当前工作表名 print("当前工作簿中的工作表名称:", sheet_names) # 检查是否存在名为 "Sheet2" 的工作表 if "Sheet2" in sheet_names: # 获取该工作表 ws = wb["Sheet2"] # 重命名为 "日调度表分光器" ws.title = "日调度表分光器" print("✅ 工作表 'Sheet2' 已重命名为 '日调度表分光器'") else: print("❌ 错误:工作簿中不存在名为 'Sheet2' 的工作表") # 保存修改 wb.save(file_path) from openpyxl import load_workbook # 文件路径 source_file = 'tongbao.xlsx' target_file = 'merged_header_file.xlsx' # 加载源文件和目标文件 source_wb = load_workbook(source_file) target_wb = load_workbook(target_file) # 获取源表数据 source_sheet = source_wb.active # 检查目标文件是否存在 "Sheet2",若不存在则创建 if "Sheet2" in target_wb.sheetnames: target_sheet = target_wb["Sheet2"] else: target_sheet = target_wb.create_sheet("Sheet2") print("⚠️ Sheet2 不存在,已自动创建") # 获取目标表最后一行的下一行 start_row = target_sheet.max_row + 1 # 将源表数据追加写入目标表 for row in source_sheet.iter_rows(values_only=True): target_sheet.append(row) # 保存目标文件 target_wb.save(target_file) print("✅ 数据已成功追加到目标文件的 Sheet2 中") from openpyxl import load_workbook # 文件路径 file_path = 'merged_header_file.xlsx' # 加载工作簿 wb = load_workbook(file_path) # 获取当前工作表名称列表 sheet_names = wb.sheetnames # 打印当前工作表名 print("当前工作簿中的工作表名称:", sheet_names) # 检查是否存在名为 "Sheet2" 的工作表 if "Sheet2" in sheet_names: # 获取该工作表 ws = wb["Sheet2"] # 重命名为 "通报" ws.title = "通报" print("✅ 工作表 'Sheet2' 已重命名为 '通报'") else: print("❌ 错误:工作簿中不存在名为 'Sheet2' 的工作表") # 保存修改 wb.save(file_path) from openpyxl import load_workbook from openpyxl.styles import NamedStyle # 文件路径 file_path = 'merged_header_file.xlsx' # 加载工作簿 wb = load_workbook(file_path) # 检查并创建百分比样式 percent_style_name = 'Percent 2 Decimal' if percent_style_name not in wb.named_styles: percent_style = NamedStyle(name=percent_style_name) percent_style.number_format = '0.00%' wb.add_named_style(percent_style) # 获取名为 "通报" 的工作表 ws = wb['通报'] # 假设从第3行开始插入公式 start_row = 3 max_row = ws.max_row # 插入公式并设置格式 for row in range(start_row, max_row + 1): ws[f'C{row}'] = f'=XLOOKUP(A{row},日调度表分光器!A:A,日调度表分光器!C:C)' ws[f'D{row}'] = f'=XLOOKUP(A{row},日调度表分光器!A:A,日调度表分光器!E:E)' ws[f'B{row}'] = f'=XLOOKUP(A{row},日调度表分光器!A:A,日调度表分光器!B:B)' ws[f'E{row}'] = f'=XLOOKUP(A{row},日调度表2!B:B,日调度表2!F:F)' ws[f'F{row}'] = f'=XLOOKUP(A{row},日调度表1!B:B,日调度表1!F:F)' ws[f'H{row}'] = f'=COUNTIF(Sheet1!B:B, A{row})' # G列:插入公式并设置百分比格式 cell = ws[f'G{row}'] cell.value = f'=E{row}-F{row}' cell.style = percent_style_name # 在最后一行写入 SUM 公式(在 H 列) last_row = max_row ws[f'H{last_row}'] = f'=SUM(H{start_row}:H{max_row-1})' # 保存修改 wb.save(file_path) print("✅ 公式已成功插入到 '通报' 表,G 列设置为百分比格式,H 列最后一行为 SUM 公式") from openpyxl import load_workbook from openpyxl.styles import Font, Alignment, Border, Side, PatternFill # 文件路径 file_path = r'C:\Users\Lt\Desktop\test\merged_header_file.xlsx' # 原始文件路径 output_path = r'C:\Users\Lt\Desktop\test\通报_美化后.xlsx' # 输出文件路径 # 加载工作簿和子表 wb = load_workbook(file_path) sheet = wb["通报"] # 选择名为“通报”的子表 # 定义通用样式 normal_font = Font(name='微软雅黑', size=11) title_font = Font(name='微软雅黑', size=11, bold=True, color="FFFFFF") # 白色字体 alignment_center = Alignment(horizontal='center', vertical='center') thin_border = Border( left=Side(style='thin'), right=Side(style='thin'), top=Side(style='thin'), bottom=Side(style='thin') ) title_fill = PatternFill(start_color='4F94CD', end_color='4F94CD', fill_type='solid') # 蓝灰色背景 # 1. 设置标题行样式(假设标题在第1行) for cell in sheet[1]: cell.font = title_font cell.alignment = alignment_center cell.fill = title_fill cell.border = thin_border # 2. 设置其余单元格样式 for row in sheet.iter_rows(min_row=2): # 从第2行开始 for cell in row: cell.font = normal_font cell.alignment = alignment_center cell.border = thin_border #3. 设置所有列的宽度为 20 个字符 for col in sheet.columns: column_letter = col[0].column_letter # 获取列的字母(如 A, B, C) sheet.column_dimensions[column_letter].width = 20 # 4. 设置统一行高 for row in sheet.iter_rows(): sheet.row_dimensions[row[0].row].height = 18 # 行高设为18 # 5. 冻结首行(冻结第一行) sheet.freeze_panes = 'A2' # 保存美化后的文件 wb.save(output_path) print(f"✅ 美化完成,文件已保存至:{output_path}") from openpyxl import load_workbook from openpyxl.styles import Border, Side # 加载 Excel 文件 file_path = r'C:\Users\Lt\Desktop\test\通报_美化后.xlsx' # 替换为你的文件路径 wb = load_workbook(file_path) sheet = wb["Sheet1"] # 指定工作表名称 # 设置列宽 column_widths = { 'A': 7, 'B': 7, 'C': 14, 'D': 9, 'E': 38, 'F': 38, 'G': 14, 'H': 14, 'I': 14, 'J': 30, 'K': 22, 'L': 12, 'M': 85 } for col, width in column_widths.items(): sheet.column_dimensions[col].width = width # 定义统一的边框样式(细实线) thin_border = Border( left=Side(style='thin'), right=Side(style='thin'), top=Side(style='thin'), bottom=Side(style='thin') ) # 为所有已使用的单元格添加边框 for row in sheet.iter_rows(): for cell in row: cell.border = thin_border # 保存文件 output_path = r'your_excel_file_fixed_width_with_border.xlsx' wb.save(output_path) print(f"✅ 列宽已设置,边框已添加,文件已保存至:{output_path}") import win32com.client as win32 import time from PIL import ImageGrab import os # 启动 Excel 应用程序 excel = win32.Dispatch("Excel.Application") excel.Visible = True # 必须设为 True 才能截图 excel.DisplayAlerts = False # 禁止弹窗 # 打开工作簿 file_path = r'C:\Users\Lt\Desktop\test\your_excel_file_fixed_width_with_border.xlsx' # 替换为你的文件路径 wb = excel.Workbooks.Open(file_path) sheet = wb.Sheets("Sheet1") # 获取 Sheet1 # 确保当前是 Sheet1 激活状态 sheet.Activate() # 对 B 列进行自动筛选 sheet.Rows(1).AutoFilter() # 假设第一行是标题行 # 筛选 B 列中指定内容(港南区、平南县等) filter_values = ["港南区"] sheet.Range("B1").AutoFilter(Field=2, Criteria1=filter_values, Operator=7) # Operator=7 表示 OR 多条件筛选 # 等待 Excel 刷新界面(截图前确保筛选完成) time.sleep(1) # 定义截图区域(如 A1:M100) range_to_capture = sheet.Range("A1:M100") # 根据你的实际表格范围修改 # 将区域复制为图片 range_to_capture.CopyPicture( Appearance=1, # xlScreen Format=2 # xlPicture ) # 新建一个工作表粘贴图片(或可以使用其他方式导出为图片文件) sheet.Paste() image = ImageGrab.grabclipboard() # 保存图片到本地 output_folder = r'C:\Users\Lt\Desktop\test\tuisong' # 替换为你想保存图片的路径 os.makedirs(output_folder, exist_ok=True) image_path = os.path.join(output_folder, '港南区.png') image.save(image_path) # 可选:将图片导出为图片文件(需要额外操作) # 由于 win32com 无法直接保存剪贴板图片为文件,建议手动复制保存或使用 pywin32 + PIL 从屏幕截图 # 保存并关闭 output_path = r'C:\Users\Lt\Desktop\test\tuisong\港南区.xlsx' wb.SaveAs(output_path) wb.Close() excel.Quit() print(f"✅ 筛选港南区并截图完成,结果已粘贴至 Excel 文件。") # 启动 Excel 应用程序 excel = win32.Dispatch("Excel.Application") excel.Visible = True # 必须设为 True 才能截图 excel.DisplayAlerts = False # 禁止弹窗 # 打开工作簿 file_path = r'C:\Users\Lt\Desktop\test\your_excel_file_fixed_width_with_border.xlsx' # 替换为你的文件路径 wb = excel.Workbooks.Open(file_path) sheet = wb.Sheets("Sheet1") # 获取 Sheet1 # 确保当前是 Sheet1 激活状态 sheet.Activate() # 对 B 列进行自动筛选 sheet.Rows(1).AutoFilter() # 假设第一行是标题行 # 筛选 B 列中指定内容(港南区、平南县等) filter_values = ["港北区"] sheet.Range("B1").AutoFilter(Field=2, Criteria1=filter_values, Operator=7) # Operator=7 表示 OR 多条件筛选 # 等待 Excel 刷新界面(截图前确保筛选完成) time.sleep(1) # 定义截图区域(如 A1:M100) range_to_capture = sheet.Range("A1:M100") # 根据你的实际表格范围修改 # 将区域复制为图片 range_to_capture.CopyPicture( Appearance=1, # xlScreen Format=2 # xlPicture ) # 新建一个工作表粘贴图片(或可以使用其他方式导出为图片文件) sheet.Paste() image = ImageGrab.grabclipboard() # 保存图片到本地 output_folder = r'C:\Users\Lt\Desktop\test\tuisong' # 替换为你想保存图片的路径 os.makedirs(output_folder, exist_ok=True) image_path = os.path.join(output_folder, '港北区.png') image.save(image_path) # 可选:将图片导出为图片文件(需要额外操作) # 由于 win32com 无法直接保存剪贴板图片为文件,建议手动复制保存或使用 pywin32 + PIL 从屏幕截图 # 保存并关闭 output_path = r'C:\Users\Lt\Desktop\test\tuisong\港北区.xlsx' wb.SaveAs(output_path) wb.Close() excel.Quit() print(f"✅ 筛选港北区并截图完成,结果已粘贴至 Excel 文件。") # 启动 Excel 应用程序 excel = win32.Dispatch("Excel.Application") excel.Visible = True # 必须设为 True 才能截图 excel.DisplayAlerts = False # 禁止弹窗 # 打开工作簿 file_path = r'C:\Users\Lt\Desktop\test\your_excel_file_fixed_width_with_border.xlsx' # 替换为你的文件路径 wb = excel.Workbooks.Open(file_path) sheet = wb.Sheets("Sheet1") # 获取 Sheet1 # 确保当前是 Sheet1 激活状态 sheet.Activate() # 对 B 列进行自动筛选 sheet.Rows(1).AutoFilter() # 假设第一行是标题行 # 筛选 B 列中指定内容(港南区、平南县等) filter_values = ["覃塘区"] sheet.Range("B1").AutoFilter(Field=2, Criteria1=filter_values, Operator=7) # Operator=7 表示 OR 多条件筛选 # 等待 Excel 刷新界面(截图前确保筛选完成) time.sleep(1) # 定义截图区域(如 A1:M100) range_to_capture = sheet.Range("A1:M100") # 根据你的实际表格范围修改 # 将区域复制为图片 range_to_capture.CopyPicture( Appearance=1, # xlScreen Format=2 # xlPicture ) # 新建一个工作表粘贴图片(或可以使用其他方式导出为图片文件) sheet.Paste() image = ImageGrab.grabclipboard() # 保存图片到本地 output_folder = r'C:\Users\Lt\Desktop\test\tuisong' # 替换为你想保存图片的路径 os.makedirs(output_folder, exist_ok=True) image_path = os.path.join(output_folder, '覃塘区.png') image.save(image_path) # 可选:将图片导出为图片文件(需要额外操作) # 由于 win32com 无法直接保存剪贴板图片为文件,建议手动复制保存或使用 pywin32 + PIL 从屏幕截图 # 保存并关闭 output_path = r'C:\Users\Lt\Desktop\test\tuisong\覃塘区.xlsx' wb.SaveAs(output_path) wb.Close() excel.Quit() print(f"✅ 筛选覃塘区并截图完成,结果已粘贴至 Excel 文件。") # 启动 Excel 应用程序 excel = win32.Dispatch("Excel.Application") excel.Visible = True # 必须设为 True 才能截图 excel.DisplayAlerts = False # 禁止弹窗 # 打开工作簿 file_path = r'C:\Users\Lt\Desktop\test\your_excel_file_fixed_width_with_border.xlsx' # 替换为你的文件路径 wb = excel.Workbooks.Open(file_path) sheet = wb.Sheets("Sheet1") # 获取 Sheet1 # 确保当前是 Sheet1 激活状态 sheet.Activate() # 对 B 列进行自动筛选 sheet.Rows(1).AutoFilter() # 假设第一行是标题行 # 筛选 B 列中指定内容(港南区、平南县等) filter_values = ["平南县"] sheet.Range("B1").AutoFilter(Field=2, Criteria1=filter_values, Operator=7) # Operator=7 表示 OR 多条件筛选 # 等待 Excel 刷新界面(截图前确保筛选完成) time.sleep(1) # 定义截图区域(如 A1:M100) range_to_capture = sheet.Range("A1:M100") # 根据你的实际表格范围修改 # 将区域复制为图片 range_to_capture.CopyPicture( Appearance=1, # xlScreen Format=2 # xlPicture ) # 新建一个工作表粘贴图片(或可以使用其他方式导出为图片文件) sheet.Paste() image = ImageGrab.grabclipboard() # 保存图片到本地 output_folder = r'C:\Users\Lt\Desktop\test\tuisong' # 替换为你想保存图片的路径 os.makedirs(output_folder, exist_ok=True) image_path = os.path.join(output_folder, '平南县.png') image.save(image_path) # 可选:将图片导出为图片文件(需要额外操作) # 由于 win32com 无法直接保存剪贴板图片为文件,建议手动复制保存或使用 pywin32 + PIL 从屏幕截图 # 保存并关闭 output_path = r'C:\Users\Lt\Desktop\test\tuisong\平南县.xlsx' wb.SaveAs(output_path) wb.Close() excel.Quit() print(f"✅ 筛选平南县并截图完成,结果已粘贴至 Excel 文件。") # 启动 Excel 应用程序 excel = win32.Dispatch("Excel.Application") excel.Visible = True # 必须设为 True 才能截图 excel.DisplayAlerts = False # 禁止弹窗 # 打开工作簿 file_path = r'C:\Users\Lt\Desktop\test\your_excel_file_fixed_width_with_border.xlsx' # 替换为你的文件路径 wb = excel.Workbooks.Open(file_path) sheet = wb.Sheets("Sheet1") # 获取 Sheet1 # 确保当前是 Sheet1 激活状态 sheet.Activate() # 对 B 列进行自动筛选 sheet.Rows(1).AutoFilter() # 假设第一行是标题行 # 筛选 B 列中指定内容(港南区、平南县等) filter_values = ["桂平市"] sheet.Range("B1").AutoFilter(Field=2, Criteria1=filter_values, Operator=7) # Operator=7 表示 OR 多条件筛选 # 等待 Excel 刷新界面(截图前确保筛选完成) time.sleep(1) # 定义截图区域(如 A1:M100) range_to_capture = sheet.Range("A1:M100") # 根据你的实际表格范围修改 # 将区域复制为图片 range_to_capture.CopyPicture( Appearance=1, # xlScreen Format=2 # xlPicture ) # 新建一个工作表粘贴图片(或可以使用其他方式导出为图片文件) sheet.Paste() image = ImageGrab.grabclipboard() # 保存图片到本地 output_folder = r'C:\Users\Lt\Desktop\test\tuisong' # 替换为你想保存图片的路径 os.makedirs(output_folder, exist_ok=True) image_path = os.path.join(output_folder, '桂平市.png') image.save(image_path) # 可选:将图片导出为图片文件(需要额外操作) # 由于 win32com 无法直接保存剪贴板图片为文件,建议手动复制保存或使用 pywin32 + PIL 从屏幕截图 # 保存并关闭 output_path = r'C:\Users\Lt\Desktop\test\tuisong\桂平市.xlsx' wb.SaveAs(output_path) wb.Close() excel.Quit() print(f"✅ 筛选桂平市并截图完成,结果已粘贴至 Excel 文件。") try: # 启动 Excel 应用 excel = win32.Dispatch("Excel.Application") excel.Visible = False excel.DisplayAlerts = False excel.ScreenUpdating = False # 打开 Excel 文件(请根据实际路径修改) file_path = r'C:\Users\Lt\Desktop\test\通报_美化后.xlsx' workbook = excel.Workbooks.Open(file_path) # 获取 "通报" 子表 sheet = workbook.Sheets("通报") # 获取数据区域 used_range = sheet.UsedRange # 复制数据区域为图片(xlScreen = 1, xlPicture = 2) used_range.CopyPicture(Appearance=1, Format=2) # 创建临时图表用于粘贴图片 chart_obj = sheet.ChartObjects().Add( Left=0, Top=0, Width=used_range.Width, Height=used_range.Height ) chart = chart_obj.Chart chart.Paste() # 粘贴图片到图表 # 设置图片保存路径(请根据实际路径修改) output_path = r'C:\Users\Lt\Desktop\test\tuisong\通报_截图.png' # 导出图表为图片 chart.Export(output_path, "PNG") # 清理资源 chart_obj.Delete() workbook.Close(SaveChanges=False) excel.Quit() print(f"✅ 数据截图已成功保存为:{output_path}") except Exception as e: print("❌ 出现错误:", str(e)) import os import requests # 企业微信 Webhook Key KEY = '496ab8f1-8b4f-4162-8528-ea0542f18fdc' # 文件夹路径 folder_path = r'C:\Users\Lt\Desktop\test\tuisong' # 上传媒体文件接口 upload_url = f'https://qyapi.weixin.qq.com/cgi-bin/webhook/upload_media?key={KEY}&type=file' # 发送 Webhook 消息接口 webhook_url = f'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key={KEY}' # 遍历文件夹 for filename in os.listdir(folder_path): file_path = os.path.join(folder_path, filename) # 跳过目录,只处理文件 if not os.path.isfile(file_path): continue print(f"正在上传文件:{filename}") # 上传文件获取 media_id try: with open(file_path, 'rb') as f: files = {'media': f} upload_response = requests.post(upload_url, files=files) result = upload_response.json() if result.get('errcode') != 0: print(f"❌ 文件上传失败:{result}") continue media_id = result['media_id'] print(f"✅ 文件上传成功,media_id: {media_id}") # 构造 Webhook 消息体 msg_data = { "msgtype": "file", "file": { "media_id": media_id } } # 发送 Webhook 消息 send_response = requests.post(webhook_url, json=msg_data) send_result = send_response.json() if send_result.get('errcode') == 0: print(f"✅ 文件 {filename} 已成功推送到企业微信机器人") else: print(f"❌ 文件 {filename} 推送失败:{send_result}") except Exception as e: print(f"⚠️ 处理文件 {filename} 时出错:{e}") # =================================================================================== # 新增:最后发送一条文字消息,读取通报_美化后.xlsx 的“通报”子表数据 # =================================================================================== print("\n📝 正在生成并发送文字通报消息...") file_path = r'C:\Users\Lt\Desktop\test\通报_美化后.xlsx' sheet_name = '通报' def refresh_and_read_excel(file_path, sheet_name='通报'): app = None try: app = xw.App(visible=False) app.calculation = 'automatic' print("🔧 正在打开文件...") wb = app.books.open(file_path) print("🔄 正在刷新公式...") wb.api.Application.Calculate() time.sleep(1) ws = wb.sheets[sheet_name] # 使用 header=2:前两行为表头,第三行开始是数据 df = ws.used_range.options(pd.DataFrame, header=2, index=False).value # 清洗列名:从元组中提取最后一层有效字符串 new_columns = [] for col in df.columns: if isinstance(col, tuple): # 过滤出非 nan 的 str 类型部分,取最后一个 parts = [c for c in col if pd.notna(c) and isinstance(c, str)] name = parts[-1] if parts else "Unnamed" else: name = str(col) # 统一处理 name = name.strip().replace('\n', '').replace(' ', '').replace(' ', '') new_columns.append(name) df.columns = new_columns df.dropna(how='all', inplace=True) # 删除全空行 wb.save() print("✅ 数据读取完成") return df except Exception as e: print(f"❌ 读取失败:{e}") return None finally: if app: app.quit() # 主程序 if __name__ == "__main__": try: df = refresh_and_read_excel(file_path, sheet_name) if df is None: exit() print("✅ 实际列名:", df.columns.tolist()) required_cols = ['区县', 'PON口验收A率', '今日清单数'] missing = [col for col in required_cols if col not in df.columns] if missing: print(f"❌ 缺失列:{missing}") exit() # 构建多个 Series 字典 rate_dict = pd.Series(df['PON口验收A率'].values, index=df['区县']).to_dict() count_dict = pd.Series(df['今日清单数'].values, index=df['区县']).to_dict() # 获取各区域数据 areas = ["贵港", "覃塘区", "桂平市", "平南县"] area_data = [] for area in areas: rate = rate_dict.get(area, "未知") count = count_dict.get(area, "未知") area_data.append((area, rate, count)) # 构造消息 text_message = "📊 最新PON口验收进度通报:\n\n" for area, rate, count in area_data: text_message += f"{area}:验收A率 {rate},今日清单数 {count}\n" text_message += f"\n📌 数据来源:自动化报表\n⏱ {pd.Timestamp.now().strftime('%Y-%m-%d %H:%M')}" # 发送至企业微信 payload = { "msgtype": "text", "text": { "content": text_message } } response = requests.post(webhook_url, json=payload) result = response.json() if result.get('errcode') == 0: print("✅ 消息发送成功") else: print(f"❌ 发送失败:{result}") except Exception as e: print(f"❌ 执行出错:{e}") 优化
09-22
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值