魔法指令:将指定sheet页中指定透视表拷贝到指定sheet页中指定单元格中。
import os
import builtins
import win32com.client as win32
from typing import *
try:
from xbot.app.logging import trace as print
except:
from xbot import print
# =======================================================
# 🚀 魔法:全局劫持并重写原生的 print 函数
# =======================================================
_original_print = builtins.print
def print(*args, sep=' ', **kwargs):
"""
无缝接管当前模块下的所有 print 语句,将输出强行重定向到影刀的日志控制台。
"""
msg = sep.join(map(str, args))
try:
import xbot
xbot.logging.info(msg)
except Exception:
_original_print(*args, sep=sep, **kwargs)
# ======================================================
def copy_excel_pivot_table_active(
file_path,
source_sheet_name,
pivot_table_name,
dest_sheet_name,
dest_cell="A3"
):
"""
title: 接管当前Excel并拷贝透视表
description: 将 %source_sheet_name% Sheet页中 %pivot_table_name% 透视表,拷贝至 %dest_sheet_name% Sheet页中的 %dest_cell% 单元格中。
inputs:
- file_path (str): Excel文件的绝对路径(用于匹配当前打开的窗口),eg: "C:\\测试\\业务分析报告.xlsx"
- source_sheet_name (str): 透视表所在的源Sheet页名称,eg: "数据看板"
- pivot_table_name (str): 要复制的透视表名称,eg: "数据透视表1"
- dest_sheet_name (str): 目标Sheet页名称,eg: "备份归档页"
- dest_cell (str): 目标起始单元格,粘贴到目标Sheet页的起始单元格位置,eg: "A3"
outputs:
- None
"""
# 1. 安全校验与提取目标文件名
if not dest_cell:
print("【错误】检测到目标单元格为空,请检查影刀传入的 dest_cell 变量!")
return
target_filename = os.path.basename(file_path)
print(f"▶ 准备接管已打开的工作簿: {target_filename}")
# 2. 尝试抓取当前活动的 Excel / WPS 进程
excel_app = None
try:
excel_app = win32.GetActiveObject("Excel.Application")
print("成功接管微软 Excel 进程。")
except Exception:
try:
excel_app = win32.GetActiveObject("et.Application")
print("未检测到微软 Excel,成功接管 WPS 表格进程。")
except Exception:
print("【错误】未检测到正在运行的 Excel 或 WPS 窗口!请确保在调用此指令前,影刀已经打开了该文件。")
return
# 正式运行时关闭警告,防止 Excel 弹窗卡死 RPA 自动化流程
excel_app.DisplayAlerts = False
wb = None
try:
# 3. 遍历当前应用内所有已经打开的工作簿,找到名字匹配的那一个
for workbook in excel_app.Workbooks:
if workbook.Name == target_filename:
wb = workbook
break
if wb is None:
print(f"【错误】应用进程正在运行,但没有找到名为 '{target_filename}' 的文件,请检查文件是否确实处于打开状态。")
return
# 4. 获取源工作表
try:
ws_source = wb.Sheets(source_sheet_name)
except Exception:
print(f"【错误】在文件中找不到源工作表: '{source_sheet_name}'")
return
# 5. 获取目标工作表(如果不存在则自动创建到最后一个)
try:
ws_dest = wb.Sheets(dest_sheet_name)
except Exception:
try:
# 【底层修复】:使用位置参数 (None, 最后一个Sheet对象) 确保绝对创建在末尾,防止错乱
ws_dest = wb.Sheets.Add(None, wb.Sheets(wb.Sheets.Count))
ws_dest.Name = dest_sheet_name
print(f"【提示】目标工作表不存在,已自动创建在末尾: '{dest_sheet_name}'")
except Exception as e:
print(f"【错误】创建工作表失败!请检查名称 '{dest_sheet_name}' 是否包含非法字符或与隐藏表重名。")
return
# 6. 获取指定的透视表对象
try:
pt = ws_source.PivotTables(pivot_table_name)
except Exception:
print(f"【错误】在工作表 '{source_sheet_name}' 中找不到名为 '{pivot_table_name}' 的透视表。")
# 安全地获取当前工作表内现有的所有透视表名称,方便用户排查
existing_pts = []
try:
pivots = ws_source.PivotTables()
for i in range(1, pivots.Count + 1):
existing_pts.append(pivots(i).Name)
except Exception:
pass
print(f" 当前 '{source_sheet_name}' 页内现有的透视表名称有: {existing_pts}")
return
# 7. 解析目标单元格并执行复制粘贴
try:
dest_range = ws_dest.Range(dest_cell)
except Exception:
print(f"【错误】目标单元格 '{dest_cell}' 格式不合法(例如包含空格或非法字符),请检查!")
return
try:
# 【底层修复】:不再走系统剪贴板,直接通过 Destination 参数在 Excel 内存中完成克隆,最稳定!
pt.TableRange2.Copy(Destination=dest_range)
except Exception as e:
# 【核心拦截】:如果粘贴位置有重叠,拦截崩溃并给出白话文提示
print(f"【拦截崩溃】粘贴失败!极可能是因为目标位置 '{dest_sheet_name}' 页的 {dest_cell} 单元格及附近,已经存在其他数据或透视表,导致了重叠冲突。请在影刀中更换一个完全空白的 dest_cell 参数!")
return
# 8. 执行保存操作
wb.Save()
print(f"【成功】已将透视表 '{pivot_table_name}' 成功拷贝至 '{dest_sheet_name}' 页面的 {dest_cell} 单元格!")
except Exception as e:
print(f"【运行异常】发生未知错误,可能脱离了常规监控范围: {e}")
finally:
if excel_app:
# 无论成功或失败,将控制权交还给用户/影刀前,务必恢复弹窗警告功能
excel_app.DisplayAlerts = True
# ==================== 测试调用示例 ====================
if __name__ == "__main__":
# 仅作脱离影刀环境时的本地代码测试用
FILE_PATH = "业务分析报告.xlsx"
SOURCE_SHEET = "数据看板"
PIVOT_NAME = "数据透视表1"
DEST_SHEET = "备份归档页"
TARGET_CELL = "B3"
copy_excel_pivot_table_active(
file_path=FILE_PATH,
source_sheet_name=SOURCE_SHEET,
pivot_table_name=PIVOT_NAME,
dest_sheet_name=DEST_SHEET,
dest_cell=TARGET_CELL,
)