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

news2025/1/11 19:55:01

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

📢博客主页: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.coloradmin.cn/o/1220708.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Stable Diffusion - StableDiffusion WebUI 软件升级与扩展兼容

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/134463035 目前&#xff0c;StableDiffusion WebUI 的版本是 1.6.0&#xff0c;同步更新 controlnet、tagcomplete、roop、easy-prompt-selector等…

Go 语言变量类型和声明详解

在Go中&#xff0c;有不同的变量类型&#xff0c;例如&#xff1a; int 存储整数&#xff08;整数&#xff09;&#xff0c;例如123或-123float32 存储浮点数字&#xff0c;带小数&#xff0c;例如19.99或-19.99string - 存储文本&#xff0c;例如“ Hello World”。字符串值用…

批量替换WordPress文章内图片链接

在WordPress使用过程中&#xff0c;如果中途更换了域名&#xff0c;原先文章内的图片使用的是原来的域名&#xff0c;就会造成文章页里面的图片链接无法显示。如果从后台文章挨个修改就比较麻烦。可以通过数据库进行批量替换即可。 使用 PHPMyadmin 打开 数据库&#xff0c;登…

我所理解的 UI Toolkit 启蒙阶段(一)

我所理解的 UI Toolkit 启蒙阶段&#xff08;一&#xff09; 对于自己不会的新东西的学习&#xff0c;我认为最合适的路径就是&#xff1a; 实例教学视频 —> 实操熟悉 —> 官方文档查漏补缺 —> 拟定思路实现功能 但这 4 步并非每一步都需要下 100% 的功夫&#x…

Linux C 线程

线程 概述线程和进程的异同如何选择使用进程还是线程 函数获取进程自身ID  pthread_self创建线程  pthread_create退出线程  pthread_exit线程等待  pthread_join 四种线程模型1 &#xff09;单线程2 &#xff09;单线程3 &#xff09;双线程4 &#xff09;三线程 概述…

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

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

自建es数据迁移阿里云方案

一、ElasticSearch数据迁移方法介绍 https://help.aliyun.com/document_detail/170095.html?spma2c4g.26937906.0.0.429240c9ymiXGm 可以通过Logstash、reindex和OSS等多种方式完成阿里云Elasticsearch间数据迁移、Elasticsearch数据迁移至Openstore存储中、自建Elasticsear…

GB28181学习(十六)——基于jrtplib实现tcp被动和主动收流

前言 GB/T28181-2022实时流的传输方式介绍&#xff1a;https://blog.csdn.net/www_dong/article/details/134255185 tcp passive收流 流程图 注意&#xff1a; m字段指定传输方式为TCP/RTP/AVP&#xff1b;sdp信息中增加"asetup:passive"&#xff1b;SIP服务器启…

微服务学习 | Ribbon负载均衡、Nacos注册中心、微服务技术对比

Ribbon负载均衡 负载均衡流程 负载均衡策略 通过定义IRule实现可以修改负载均衡规则&#xff0c;有两种方式&#xff1a; 1. 代码方式:在服务消费者order-service中的OrderApplication类中&#xff0c;定义一个新的IRule: 2.配置文件方式: 在order-service的application.yml…

技术分享 | 如何写好测试用例?

对于软件测试工程师来说&#xff0c;设计测试用例和提交缺陷报告是最基本的职业技能。是非常重要的部分。一个好的测试用例能够指示测试人员如何对软件进行测试。在这篇文章中&#xff0c;我们将介绍测试用例设计常用的几种方法&#xff0c;以及如何编写高效的测试用例。 ## 一…

【Rust】快速教程——模块mod与跨文件

前言 道尊&#xff1a;没有办法&#xff0c;你的法力已经消失&#xff0c;我的法力所剩无几&#xff0c;除非咱们重新修行&#xff0c;在这个世界里取得更多法力之后&#xff0c;或许有办法下降。——《拔魔》 \;\\\;\\\; 目录 前言跨文件mod多文件mod 跨文件mod //my_mod.rs…

C#语言的由来与发展历程

C#语言的由来与发展历程可以追溯到2000年&#xff0c;当时微软公司为了在.NET平台上开发应用程序&#xff0c;发布了一种新的编程语言——C#。C#语言的设计目标是成为一种简单、现代、通用和面向对象的编程语言&#xff0c;为开发者提供更强大的生产力、更强大的面向对象支持和…

Line多账号如何运营?

Line在亚洲地区非常流行&#xff0c;特别是在日本、台湾、泰国等地&#xff0c;是当地最受欢迎的即时通讯应用之一。 除了基本的聊天功能外&#xff0c;Line还提供了各种各样的贴图、表情包和游戏等娱乐功能&#xff0c;吸引了大量的用户。 一、选择利用line进行海外营销的原…

2024年山东省职业院校技能大赛中职组“网络安全”赛项竞赛试题-A

2024年山东省职业院校技能大赛中职组 “网络安全”赛项竞赛试题-A 一、竞赛时间 总计&#xff1a;360分钟 二、竞赛阶段 竞赛阶段 任务阶段 竞赛任务 竞赛时间 分值 A、B模块 A-1 登录安全加固 180分钟 200分 A-2 本地安全策略设置 A-3 流量完整性保护 A-4 …

百度智能云正式上线Python SDK版本并全面开源

文章目录 前言一、SDK的优势二、千帆SDK&#xff1a;快速落地LLM应用三、如何快速上手千帆SDK3.1、SDK快速启动3.2. SDK进阶指引 3.3. 通过Langchain接入千帆SDK4、开源社区 前言 百度智能云千帆大模型平台再次升级&#xff01;在原有API基础上&#xff0c;百度智能云正式上线…

【漏洞复现】IP-guard WebServer 远程命令执行

漏洞描述 IP-guard是一款终端安全管理软件,旨在帮助企业保护终端设备安全、数据安全、管理网络使用和简化IT系统管理。互联网上披露IP-guard WebServer远程命令执行漏洞情报。攻击者可利用该漏洞执行任意命令,获取服务器控制权限。 免责声明 技术文章仅供参考,任何个人和…

Beego之Bee工具使用

1、bee工具使用 bee 工具是一个为了协助快速开发 Beego 项目而创建的项目&#xff0c;通过 bee 你可以很容易的进行 Beego 项目的创 建、热编译、开发、测试、和部署。Bee工具可以使用的命令&#xff1a; [rootzsx ~]# bee 2023/02/18 18:17:26.196 [D] init global config…

Nacos在Windows本地安装并启动教程

Nacos在Windows本地安装并启动教程 Nacos注册中心和Eureka是两种常见的服务注册与发现组件&#xff0c;它们在以下方面存在一些区别&#xff1a; 开源项目&#xff1a;Nacos是阿里巴巴开源的项目&#xff0c;而Eureka是Netflix开源的项目。 功能特性&#xff1a;Nacos在服务注册…

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

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

某60区块链安全之51%攻击实战学习记录

区块链安全 文章目录 区块链安全51%攻击实战实验目的实验环境实验工具实验原理攻击过程 51%攻击实战 实验目的 1.理解并掌握区块链基本概念及区块链原理 2.理解区块链分又问题 3.理解掌握区块链51%算力攻击原理与利用 4.找到题目漏洞进行分析并形成利用 实验环境 1.Ubuntu1…