关于现有指令筛选颜色不支持wps(无填充颜色部分)的解决方案
评论
收藏

关于现有指令筛选颜色不支持wps(无填充颜色部分)的解决方案

经验分享
huanwodianfanbao
2025-11-17 14:58·浏览量:737
huanwodianfanbao
发布于 2025-11-17 14:58737浏览

关于影刀现有指令筛选颜色不支持wps某列无填充颜色部分的解决方案

有请出魔法指令登场!

可以告诉魔法指令通过调用excel的com接口来达到影刀官方指令同样的效果。

以下是源码(若场景适用即可直接替换魔法指令源码):


# 使用此指令前,请确保安装必要的Python库,例如使用以下命令安装:
# pip install pywin32

import win32com.client as win32

from typing import *
try:
    from xbot.app.logging import trace as print
except:
    from xbot import print


def filter_excel_no_fill_cells(file_path, sheet_name, column, start_row):
    """
    title: Excel筛选无填充色单元格
    description: 通过COM接口操作Excel(WPS),对指定列 %column% 从第 %start_row% 行开始筛选出无颜色填充的单元格。
    inputs:
        - file_path (file): Excel文件路径,eg: "C:/data/sample.xlsx"
        - sheet_name (str): 工作表名称,eg: "Sheet1"
        - column (str): 要筛选的列,eg: "A"
        - start_row (int): 开始筛选的行号,eg: "2"
    outputs:
        - None
    """

    if not file_path:
        raise ValueError("Excel文件路径不能为空")

    if not sheet_name:
        raise ValueError("工作表名称不能为空")

    if not column:
        raise ValueError("列名不能为空")

    if not isinstance(start_row, int) or start_row < 1:
        raise ValueError("起始行必须为大于0的整数")

    def _open_excel_application():
        """打开Excel应用程序"""
        try:
            # 尝试连接现有的Excel实例
            xl_app = win32.GetActiveObject("Excel.Application")
        except:
            try:
                # 如果没有现有实例,创建新的Excel应用程序
                xl_app = win32.Dispatch("Excel.Application")
            except:
                # 如果Excel不可用,尝试WPS
                xl_app = win32.Dispatch("Ket.Application")

        xl_app.Visible = True
        return xl_app

    def _get_data_range(worksheet, column, start_row):
        """获取数据范围"""
        try:
            # 找到该列的最后一行
            last_row = worksheet.Cells(worksheet.Rows.Count, column).End(-4162).Row  # xlUp = -4162
            if last_row < start_row:
                last_row = start_row

            return last_row
        except Exception as e:
            raise Exception(f"获取数据范围失败: {str(e)}")

    def _check_cell_has_fill(cell):
        """检查单元格是否有填充色 - 使用多种方法确保兼容性"""
        try:
            # 方法1:检查ColorIndex
            color_index = cell.Interior.ColorIndex
            if color_index != -4142 and color_index != 0:  # -4142是xlNone, 0也表示无颜色
                return True
        except:
            pass

        try:
            # 方法2:检查Color属性
            color_value = cell.Interior.Color
            if color_value != 16777215:  # 16777215是白色/无颜色的默认值
                return True
        except:
            pass

        try:
            # 方法3:检查Pattern
            pattern = cell.Interior.Pattern
            if pattern != -4142:  # xlNone
                return True
        except:
            pass

        # 如果所有方法都失败,默认认为无填充色
        return False

    def _manual_filter_by_color(worksheet, column, start_row, last_row):
        """手动筛选:隐藏有填充色的行"""
        try:
            hidden_count = 0
            visible_count = 0

            for row in range(start_row, last_row + 1):
                try:
                    cell = worksheet.Cells(row, column)

                    # 检查是否有填充色
                    if _check_cell_has_fill(cell):
                        # 隐藏有填充色的行
                        worksheet.Rows(row).Hidden = True
                        hidden_count += 1
                    else:
                        # 确保无填充色的行可见
                        worksheet.Rows(row).Hidden = False
                        visible_count += 1

                except Exception as e:
                    print(f"处理第{row}行时出错: {str(e)}")
                    # 出错时默认隐藏该行
                    worksheet.Rows(row).Hidden = True
                    hidden_count += 1

            print(f"筛选完成 - 隐藏行数: {hidden_count}, 显示行数: {visible_count}")

        except Exception as e:
            raise Exception(f"手动筛选失败: {str(e)}")

    def _simple_autofilter_method(worksheet, column, start_row, last_row):
        """简单自动筛选方法"""
        try:
            # 清除现有筛选
            if worksheet.AutoFilterMode:
                worksheet.AutoFilterMode = False

            # 计算列号(A=1, B=2, ...)
            col_num = ord(column.upper()) - ord('A') + 1

            # 选择包含表头的完整数据区域
            data_range = worksheet.Range(f"{column}{start_row-1}:{column}{last_row}")

            # 应用自动筛选
            data_range.AutoFilter()

            # 获取所有唯一值并手动构建筛选条件
            unique_values = []
            for row in range(start_row, last_row + 1):
                cell = worksheet.Cells(row, column)
                if not _check_cell_has_fill(cell):
                    cell_value = cell.Value
                    if cell_value not in unique_values:
                        unique_values.append(cell_value)

            if unique_values:
                # 应用筛选条件
                data_range.AutoFilter(Field=1, Criteria1=unique_values[:10])  # 限制条目数量避免错误
                print(f"使用自动筛选显示 {len(unique_values)} 个无填充色的唯一值")
            else:
                print("未找到无填充色的单元格")

        except Exception as e:
            raise Exception(f"自动筛选方法失败: {str(e)}")

    try:
        # 打开Excel应用程序
        xl_app = _open_excel_application()

        # 打开工作簿
        try:
            workbook = xl_app.Workbooks.Open(file_path)
        except Exception as e:
            raise Exception(f"无法打开Excel文件 {file_path}: {str(e)}")

        # 选择工作表
        try:
            worksheet = workbook.Worksheets(sheet_name)
        except Exception as e:
            raise Exception(f"无法找到工作表 {sheet_name}: {str(e)}")

        # 获取数据范围
        last_row = _get_data_range(worksheet, column, start_row)

        print(f"开始筛选列 {column},从第 {start_row} 行到第 {last_row} 行")

        # 优先使用手动筛选方法(更稳定)
        try:
            _manual_filter_by_color(worksheet, column, start_row, last_row)
            print(f"成功对列 {column} 从第 {start_row} 行开始筛选无填充色单元格")
        except Exception as e:
            print(f"手动筛选失败: {str(e)}")
            print("尝试自动筛选方法...")
            _simple_autofilter_method(worksheet, column, start_row, last_row)

    except Exception as e:
        raise Exception(f"Excel操作失败: {str(e)}")
      

如上!!!

直接在此进行替换,界面如此,通过直接调用com接口进行筛选,会默认筛选某列无颜色填充的部分

收藏3
全部评论(1)
最新
发布评论
评论