作者:昼夜
关键词:Excel、RGB值
最近客户在使用影刀操作Excel过程中,遇到了如下几个问题:
(1)我需要对某一列从标题下的第一行进行填充,且标题的填充颜色为某种确定的颜色(例如黄色),但是现在无法确定该列在哪个位置,如何通过对比各个单元格与给定填充颜色的RGB值来确定需要填充列的位置?
(2)对于某列中多个不同的重复值,在给定的表格中已经通过菜单栏中的“条件格式->突出显示单元格规则->重复值->重复值填充”操作完成(具体实现方法如下图演示)。但是由于这个操作下的背景颜色无法直接在Excel中获取到RGB值,又需要在使用影刀的过程中通过“筛选颜色”的指令去筛选出来这些重复的单元格项,这个时候该如何去获取到这个RGB配合“筛选颜色”指令完成对应的功能?


那么针对这两个问题,本文中会提到一些方法,来完成高亮块背景颜色以及填充颜色RGB值的提取。
(1)对于这类填充背景色的问题,我们可以通过python代码获取到单元格的格式对象,然后将其中背景颜色的索引值转换成为颜色的RGB来实现。具体的逻辑与实现代码如下:
1.以保留单元格格式信息的方式,打开对应的Excel文件并指定到对应的Sheet页
2.使用cell方法,通过行索引与列索引锁定到对应的单元格,并使用fill获取其填充样式,然后通过start_color属性获取填充样式的起始颜色
3.将ARGB十六进制的颜色值转换为RGB格式的元组
from xlrd import open_workbook
from webcolors import rgb_to_name
from openpyxl import load_workbook
def getBGColor(book, sheet, row, col):
# 打开指定的excel文件
wb = load_workbook(book)
# 通过Sheet页名称指定到对应的工作表
sh = wb[sheet]
# 通过指定行列单元格的fill属性获取到填充颜色,并返回ARGB格式的十六进制字符串
bg_color_hex = sh.cell(row=row, column=col).fill.start_color.rgb
print(bg_color_hex)
# 将十六进制颜色(后六位)转换为RGB格式
bg_color_rgb = tuple(int(bg_color_hex[i:i+2], 16) for i in (2, 4, 6))
return bg_color_rgb在影刀中解决该问题的逻辑如下:
1.新建模块,将上述代码写入模块当中
2.新建一个流程,打开Excel表格
3.使用无限循环,在循环体内调用模块,设定行号为0(这个索引的行号值与列表相似,都是从0开始的),列号为循环的次数项index
4.进行判断,如果模块返回的RGB值等于我们设定的对应的颜色值,例如黄色(255,255,0),则index+1就为对应Excel表格中需要向下填充的列号
5.使用填充指令对该列内容向下填充

(2)针对这种高亮块的背景颜色,我们无法像情况(1)一样直接获取到背景颜色的RGB值去完成对应筛选操作,因为他这个时候的背景颜色已经填充进去的,并不设置在单元格的格式中。

对于这种问题我们给出一种提取RGB值的方法:先对Excel进行截图,截图之后使用python代码提取图像中主要的几种颜色,然后依次对几种颜色进行筛选,看哪种颜色能筛选出数据。首先使用代码提取图像中的颜色的逻辑与代码如下:
1.首先定义我们要提取颜色种类的数量
2.打开对应的图片,并将其转换成为RGB格式
3.将RGB格式的图片转换成为数组,并进一步转化数组维度
4.使用KMeans算法进行数值聚类,经过数次迭代之后生成固定数量的中心点,即图像主要颜色的RGB值
from PIL import Image
import numpy as np
from sklearn.cluster import KMeans
def get_colors(image_path):
# 定义提取颜色种类的数量
n_colors=3
# 打开图片,并将其转换为RGB格式
image = Image.open(image_path)
image = image.convert("RGB")
# 将图片转换成为numpy的数组
data = np.array(image)
data = data.reshape((-1,3))
print("转换之后的data:",data)
# 使用KMeans对转换后的数组进行聚类分析
kmeans = KMeans(n_clusters=n_colors)
kmeans.fit(data)
# 提取指定数量的主要颜色
main_colors = kmeans.cluster_centers_
print("main_colors:", main_colors)
return [tuple(round(_color) for _color in color) for color in main_colors]在影刀中解决该问题的逻辑与代码如下:
1.打开Excel文件,并设定一个路径名称用来存放稍后截图下来的文件
2.使用区域截图方法,对于指定区域进行截图
3.调用模块获取主要的RGB值,结果返回一个列表
4.循环遍历列表,使用每个RGB值都去筛选一下,记录判断筛选值是否为空,若读取筛选数据不为空的,则是我们需要的RGB值,可以对筛选出来的值进行下一步的操作

(1)目前有两列数据需要做计算并写入对应的列,但是写入列的列号由于格式的原因一直会变动,唯一不变的是要写入的那一列标题的背景填充颜色是黄色的,现在根据背景填充色找到对应列进行填充计算。

(2)读取A列中的所有重复值的高亮颜色RGB值(重复值的高亮色设置在前面已经提到过),然后根据RGB值为背景对这些重复的数据进行筛选删除操作。

在问题(2)的解决方法中,由于使用到了KMeans算法,所以我们在实际使用的时候,还需要根据我们自己的实际情况多进行调试一下,增加或减少随机种子的数量,达到我们想要的效果。对于KMeans有兴趣的也可以参考一下如下的文档:
https://blog.csdn.net/weixin_43212535/article/details/122397471