openpyxl获取单元格的主题色的颜色值

📢作者: 小小明-代码实体

📢博客主页:https://blog.csdn.net/as604049322

📢欢迎点赞 👍 收藏 ⭐留言 📝 欢迎讨论!

openpyxl 支持以下几种颜色类型:

  1. RGB (Red, Green, Blue): 这是最常用的颜色类型,允许通过指定红、绿、蓝三原色的组合来自定义颜色。RGB值通常以十六进制格式表示。
  2. Theme: Excel有一套主题颜色,可以通过指定主题颜色的索引来使用这些颜色。
  3. Indexed: 这是Excel早期版本中使用的一种颜色系统,它通过索引号来引用一组预定义的颜色。

对于RGB类型的颜色直接使用cell.fill.start_color.rgb即可获取其颜色,但是对于Theme类型的单元格获取颜色却返回一个错误。

这是因为主题色会随着主题的变化而变化,如下图:

image-20231117200205613

可以看到每个主题有10个基础色,然后受到透明度的影响,我将第一个单元格设置了上图的主题色。

我们创建Excel文件进行测试:

from openpyxl import load_workbook

wb = load_workbook("color_test.xlsx")
wbs = wb.active
cell = wbs.cell(1, 1)
cell.fill.start_color
<openpyxl.styles.colors.Color object>
Parameters:
rgb=None, indexed=None, auto=None, theme=5, tint=0.4, type='theme'

可以看到这就是一个theme类型的颜色,确实是索引5的位置,透明度40%。

我们尝试获取rgb颜色:

cell.fill.start_color.rgb

会返回Values must be of type <class 'str'>这样一个带有错误信息的字符串。

当然也可以调用index属性自动获取rgb或者在主题色中的索引:

cell.fill.start_color.index
5

如果是一个RGB 类型的颜色:

cell = wbs.cell(1, 3)
cell.fill.start_color
<openpyxl.styles.colors.Color object>
Parameters:
rgb='FFF4B382', indexed=None, auto=None, theme=None, tint=0.0, type='rgb'

此时调用index或rgb属性都可以获取rgb颜色值。

那么我们如何获取主题色对应的RGB颜色呢?这个openpyxl并没有提供一个直接的方式,我们只能自己做xml解析了。下面我封装了一个工具类:

from colorsys import rgb_to_hls, hls_to_rgb

class ThemeColorConverter:
    RGBMAX = 0xff
    HLSMAX = 240

    def __init__(self, wb):
        self.colors = self.get_theme_colors(wb)

    @staticmethod
    def tint_luminance(tint, lum):
        if tint < 0:
            return int(round(lum * (1.0 + tint)))
        return int(round((ThemeColorConverter.HLSMAX - lum) * tint)) + lum

    @staticmethod
    def ms_hls_to_rgb(hue, lightness=None, saturation=None):
        if lightness is None:
            hue, lightness, saturation = hue
        hlsmax = ThemeColorConverter.HLSMAX
        return hls_to_rgb(hue / hlsmax, lightness / hlsmax, saturation / hlsmax)

    @staticmethod
    def rgb_to_hex(red, green=None, blue=None):
        if green is None:
            red, green, blue = red
        return '{:02X}{:02X}{:02X}'.format(
            int(red * ThemeColorConverter.RGBMAX),
            int(green * ThemeColorConverter.RGBMAX),
            int(blue * ThemeColorConverter.RGBMAX)
        )

    @staticmethod
    def rgb_to_ms_hls(red, green=None, blue=None):
        if green is None:
            if isinstance(red, str):
                if len(red) > 6:
                    red = red[-6:]  # Ignore preceding '#' and alpha values
                rgbmax = ThemeColorConverter.RGBMAX
                blue = int(red[4:], 16) / rgbmax
                green = int(red[2:4], 16) / rgbmax
                red = int(red[0:2], 16) / rgbmax
            else:
                red, green, blue = red
        h, l, s = rgb_to_hls(red, green, blue)
        hlsmax = ThemeColorConverter.HLSMAX
        return (int(round(h * hlsmax)), int(round(l * hlsmax)),
                int(round(s * hlsmax)))

    @staticmethod
    def get_theme_colors(wb):
        from openpyxl.xml.functions import QName, fromstring
        xlmns = 'http://schemas.openxmlformats.org/drawingml/2006/main'
        root = fromstring(wb.loaded_theme)
        themeEl = root.find(QName(xlmns, 'themeElements').text)
        colorSchemes = themeEl.findall(QName(xlmns, 'clrScheme').text)
        firstColorScheme = colorSchemes[0]
        colors = []
        for c in ['lt1', 'dk1', 'lt2', 'dk2', 'accent1', 'accent2', 'accent3', 'accent4', 'accent5', 'accent6']:
            accent = firstColorScheme.find(QName(xlmns, c).text)
            for i in list(accent):
                if 'window' in i.attrib['val']:
                    colors.append(i.attrib['lastClr'])
                else:
                    colors.append(i.attrib['val'])
        return colors

    def theme_and_tint_to_rgb(self, theme, tint):
        rgb = self.colors[theme]
        h, l, s = self.rgb_to_ms_hls(rgb)
        return self.rgb_to_hex(self.ms_hls_to_rgb(h, self.tint_luminance(tint, l), s))

具体如何xml解析可以看上面的get_theme_colors函数。

下面我们获取一下当前Excel选中主题的10个基础色调:

theme_color = ThemeColorConverter(wb)
print(theme_color.colors)
['FFFFFF', '000000', 'E7E6E6', '44546A', '4874CB', 'EE822F', 'F2BA02', '75BD42', '30C0B4', 'E54C5E']

然后我们传入索引和透明度获取颜色:

theme_color.theme_and_tint_to_rgb(5, 0.4)
'F4B281'

但使用取色工具测量第一个单元格的颜色值为#f4b382,有微量误差,这属于正常现象,也完全不会影响视觉。这是因为hls+透明度转rgb颜色的过程中存在小数运算,四舍五入后就会造成一定误差。

人眼对低位数据变化不敏感

image-20231117204721115

在24位位图中高8位构成蓝色通道,中8位构成绿色通道,低8位构成红色通道。经测试,在删除各通道的低4位数据并加入随机噪音后,图片用肉眼无法观察到任何变化。现在展示一张图片在删除各通道的低位数据,并加入随机噪音后图片的变化。

image-20231117201646876

可以看到在每个通道低三位的数据进行随意修改,肉眼几乎看不出变化。低三位,意味着7以内的变化都不会有影响。

最后我们封装一个可以查看任何单元格颜色的函数:

from openpyxl.styles.colors import COLOR_INDEX


def get_cell_color(cell):
    color = cell.fill.start_color
    if color.type == "rgb":
        return color.rgb
    elif color.type == "indexed":
        color_index = color.indexed
        if color_index is None or color_index < len(COLOR_INDEX):
            raise Exception("Invalid indexed color")
        return COLOR_INDEX[color_index]
    elif color.type == "theme":
        return "FF" + theme_color.theme_and_tint_to_rgb(color.theme, color.tint)
    else:
        raise Exception(f"Other type: {color.type}")

下面我们将这些主题色都测一测:

image-20231117202903861

theme_color = ThemeColorConverter(wb)
wbs = wb.active
for r in range(1, 4):
    colors = [get_cell_color(wbs.cell(r, c)) for c in range(1, 8)]
    print(f"第{r}行的单元格的颜色为", colors)
第1行的单元格的颜色为 ['FFFFFFFF', 'FF000000', 'FFE7E6E6', 'FF44546A', 'FF4772CA', 'FFEE802E', 'FFF2BC02']
第2行的单元格的颜色为 ['FFF2F2F2', 'FF7F7F7F', 'FFD0CECE', 'FFD5DBE4', 'FFDAE3F4', 'FFFBE5D5', 'FFFEF2CA']
第3行的单元格的颜色为 ['FFBFBFBF', 'FF3F3F3F', 'FF757070', 'FF8496AF', 'FF90A9DF', 'FFF4B281', 'FFFDDA60']

可以看到,全部获取到低位误差小于1的RGB颜色。

附录

openpyxl获取的颜色值由四组16进制数表示,分别是:

  1. Alpha(透明度):范围也是00FF,其中FF表示完全不透明,而00表示完全透明。
  2. 红色(Red)
  3. 绿色(Green)
  4. 蓝色(Blue)

不过在wps中测试,透明度不起任何效果,不排除office或WPS未来版本支持ARGB的颜色,但目前WPS对A通道的透明度值会直接忽略。

本文链接:https://blog.csdn.net/as604049322/article/details/134470419

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/158223.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【漏洞复现】用友U8-Cloud 存在任意文件上传漏洞

漏洞描述 U8 cloud 聚焦成长型、创新型企业的云 ERP,基于全新的企业互联网应用设计理念,为企业提供集人财物客、产供销于一体的云 ERP 整体解决方案,全面支持多组织业务协同、智能财务,人力服务、构建产业链智造平台,融合用友云服务实现企业互联网资源连接、共享、协同。…

YOLO目标检测——PCB缺陷数据集下载分享【含对应voc、coco和yolo三种格式标签】

实际项目应用&#xff1a;电子制造过程的质量控制、生产线的自动化检测、以及产品可靠性验证等方面数据集说明&#xff1a;PCB缺陷检测数据集&#xff0c;真实场景的高质量图片数据&#xff0c;数据场景丰富标签说明&#xff1a;使用lableimg标注软件标注&#xff0c;标注框质量…

选择Amazon EC2,走进云端新时代

目录 前言 选择云服务器 / 海外服务器需要关注的重点 Amazon EC2 云服务器的优势所在 文末总结 前言 常言道&#xff0c;工欲善其事必先利其器&#xff0c;无论你是资深开发者&#xff0c;还是普通爱好者&#xff0c;在日常开发和学习生活中都需要用到云服务器提供的丰富的…

【978.最长湍流子数组】

目录 一、题目描述二、算法原理三、代码实现 一、题目描述 二、算法原理 三、代码实现 class Solution { public:int maxTurbulenceSize(vector<int>& arr) {int narr.size();vector<int> f(n),g(n);f[0]g[0]1;if(n1) return 1;int retmax(f[0],g[0]);for(int…

资深品酒师荆芳老师倾情力作,带你品酒选酒,读懂葡萄酒的世界

在美酒琳琅满目的今天&#xff0c;如何才能挑选到适合自己的葡萄酒&#xff1f;如何品鉴葡萄酒的独特魅力&#xff1f;资深品酒师荆芳老师的最新力作《葡萄酒爱好者》正式上线&#xff0c;带你走进葡萄酒的世界&#xff0c;领略品酒选酒的奥秘。作为一位资深的品酒师和教育工作…

微软宣布计划在 Windows 10 版本 22H2 中引入 AI 助手 Copilot

根据之前的传言&#xff0c;微软宣布计划在 Windows 10 版本 22H2 中引入 AI 助手 Copilot。Copilot 将包含在 Windows 10 家庭版和专业版中。该更新的发布日期尚未公布&#xff0c;但预计将在不久的将来发布。 在一份新闻稿中&#xff0c;微软表示在向 Windows 11 用户提供 Co…

物联网AI MicroPython学习之语法UART通用异步通信

学物联网&#xff0c;来万物简单IoT物联网&#xff01;&#xff01; UART 介绍 模块功能: UART通过串行异步收发通信 接口说明 UART - 构建UART对象 函数原型&#xff1a;UART(id, baudrate&#xff0c;bits, parity&#xff0c;stop, tx, rx)参数说明&#xff1a; 参数类…

WhatsApp账号被封?看看是不是你的原因!

WhatsApp经常封号是一个难题&#xff0c;这一篇将为你详细介绍WhatsApp封号原因&#xff0c;以及如何防封。 封号原因 首先我们分情况来判定封号原因&#xff0c;WhatsApp封号一般有以下几种情况&#xff1a; 1、一注册就封 许多小伙伴账号刚注册什么都没动&#xff0c;就遭…

Apifox 关于token的使用方式

前言&#xff0c;关于token的使用&#xff0c;仅做了简单的demo测试token效果。 1.手动登录获取token 顾名思义&#xff0c;因为只有登录之后才有token的信息&#xff0c;所以在调用其他接口前需要拥有token才能访问。 操作步骤 1)添加环境变量、全局参数 这里拿测试环境举…

PyTorch深度学习原理与实现

PyTorch深度学习原理与实现 1. 引言 深度学习发展历程 感知机网络&#xff08;解决线性可分问题&#xff0c;20世纪40年代&#xff09; BP神经网络&#xff08;解决线性不可分问题&#xff0c;20世纪80年代&#xff09; 深度神经网络&#xff08;海量图片分类&#xff0c;2…

SSH协议简介与使用

Secure Shell(SSH) 是由 IETF(The Internet Engineering Task Force) 制定的建立在应用层基础上的安全网络协议。它是专为远程登录会话(甚至可以用Windows远程登录Linux服务器进行文件互传)和其他网络服务提供安全性的协议&#xff0c;可有效弥补网络中的漏洞。通过SSH&#xf…

浙大恩特客户资源管理系统 SQL注入漏洞复现

0x01 产品简介 浙大恩特客户资源管理系统是一款针对企业客户资源管理的软件产品。该系统旨在帮助企业高效地管理和利用客户资源&#xff0c;提升销售和市场营销的效果。 0x02 漏洞概述 浙大恩特客户资源管理系统中T0140_editAction.entweb接口处存在SQL注入漏洞&#xff0c;未…

阿里云CentOS主机开启ipv6

目录 一、云主机开启和使用 ipv6 1、网络和交换机开启 ipv6 2、创建 / 编辑云主机&#xff0c;开启ipv6 3、安全组放行ipv6端口 二、使用 ipv6 地址进行 ssh 连接 三、ipv6 地址绑定域名 一、云主机开启和使用 ipv6 1、网络和交换机开启 ipv6 进入网络、交换机详情页面…

如何用AB测试完善产品激励体系

更多技术交流、求职机会&#xff0c;欢迎关注字节跳动数据平台微信公众号&#xff0c;回复【1】进入官方交流群 用户激励体系&#xff0c;也称用户激励机制&#xff0c;是为了让用户持续使用产品&#xff0c;而设计的一套对应规则。在用户激励体系建立过程中&#xff0c;产品可…

锐捷网络NBR700G 信息泄露漏洞复现 [附POC]

文章目录 锐捷网络NBR700G 信息泄露漏洞复现 [附POC]0x01 前言0x02 漏洞描述0x03 影响版本0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现 0x06 修复建议 锐捷网络NBR700G 信息泄露漏洞复现 [附POC] 0x01 前言 免责声明&#xff1a;请勿利用文章内的相关技术从事非…

SQL 查询优化指南:SELECT、SELECT DISTINCT、WHERE 和 ORDER BY 详解

SELECT 关键字 SQL的SELECT语句用于从数据库中选择数据。SELECT语句的基本语法如下&#xff1a; SELECT column1, column2, ... FROM table_name;其中&#xff0c;column1, column2,等是您要从表中选择的字段名称&#xff0c;而table_name是您要选择数据的表的名称。 如果要…

JavaEE初阶 01 计算机是如何工作的

前言 今天开始进行对JavaEE的一些基本总结,希望大家能在阅读中有所收获,如有错误还望多多指正. 1.冯诺依曼体系结构 这个体系结构相信学计算机的同学都不陌生,但是你真的知道这个体系结构说的是什么嘛?请听我娓娓道来.首先我先给出一张冯诺依曼体系结构的简图 你可以理解为当前…

2023年腾讯云服务器限时特惠,2023年腾讯云服务器最新优惠汇总

亲爱的朋友们&#xff0c;如果你正在考虑购买腾讯云服务器&#xff0c;那么你一定需要了解近期腾讯云服务器的限时特惠活动。本文将为你提供2023年腾讯云服务器的最新优惠汇总&#xff0c;并详细介绍几款值得购买的优惠云服务器。 首先为大家介绍的是轻量2核2G3M服务器&#x…

Web前端—移动Web第一天(平面转换、渐变、综合案例--播客网页设计)

版本说明 当前版本号[20231117]。 版本修改说明20231117初版 目录 文章目录 版本说明目录移动 Web 第一天01-平面转换简介示例 平移定位居中案例-双开门旋转转换原点案例-时钟多重转换缩放案例-播放特效倾斜 02-渐变线性渐变案例-产品展示径向渐变 03-综合案例导航-频道箭头…

openssl1.0.2版本Windows安装问题

之前安装过1.1版本&#xff0c;Windows环境下C 安装OpenSSL库 源码编译及使用&#xff08;VS2019&#xff09;_vs2019安装openssl_肥宝Fable的博客-CSDN博客 后来发现linux编译不过&#xff0c;以为是版本问题&#xff0c;相差太大&#xff0c;所以降一下版本&#xff0c;以免…