You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用openpyxl为单元格填充50%强度的十六进制颜色

问题背景

Python 3.10环境下使用openpyxl读取sqlite数据库数据生成Excel文件,需要读取库中存储的十六进制格式颜色值,为单元格填充该颜色的50%强度版本。要求填充为纯实色,不能带线条、点阵类的图案填充效果。
现有实现代码如下:

import sqlite3, openpyxl

def getRouteColor(route):
    cursor.execute('''SELECT route_color
                       FROM routes
                       WHERE route_short_name = "{}"'''.format(route))
    return cursor.fetchall()[0][0]

[...]
color = getRouteColor(route) #hexadecimal

for column in sheet.columns: 
  for cell in column:
        if not cell.row % 2:
             cell.fill = openpyxl.styles.PatternFill(patternType = 'solid', fgColor = color)

尝试调整patternType参数模拟半透明效果未达预期,需要找可行的实现方案,包括openpyxl原生支持的方式,或者十六进制色值换算方法。

实现方案

openpyxl没有提供直接给纯色填充设置透明度的原生API,兼容性最好的方案是预计算50%强度对应的纯色十六进制值,保持solid填充模式即可,不需要调整patternType。

50%强度色值计算逻辑

50%色彩强度的视觉效果等价于目标颜色和纯白色(#FFFFFF)按1:1比例混合,计算规则:

  • 将6位十六进制颜色拆分为R(红)、G(绿)、B(蓝)三个通道,分别转为0-255范围的十进制数值
  • 每个通道的新值 = 原通道值 * 0.5 + 255(纯白通道值)* 0.5,结果四舍五入取整
  • 将计算后的三个通道值转回两位十六进制字符串,不足两位时前面补0,拼接后就是50%强度的色值

可直接复用的代码

先写色值转换函数:

def get_half_intensity_color(hex_color: str) -> str:
    # 兼容带#前缀的色值输入
    hex_color = hex_color.lstrip('#')
    # 拆分三通道转十进制
    r = int(hex_color[0:2], 16)
    g = int(hex_color[2:4], 16)
    b = int(hex_color[4:6], 16)
    # 和白色1:1混合
    r_half = round(r * 0.5 + 255 * 0.5)
    g_half = round(g * 0.5 + 255 * 0.5)
    b_half = round(b * 0.5 + 255 * 0.5)
    # 转回十六进制拼接返回
    return f"{r_half:02X}{g_half:02X}{b_half:02X}"

修改原有填充逻辑,传入转换后的色值即可:

color = getRouteColor(route)
half_strength_color = get_half_intensity_color(color)

for column in sheet.columns: 
    for cell in column:
        if not cell.row % 2:
             cell.fill = openpyxl.styles.PatternFill(
                 patternType='solid', 
                 fgColor=half_strength_color
             )

额外优化建议

原有代码中SQL查询用字符串格式化拼接参数存在SQL注入风险,建议改成参数化查询写法,同时用fetchone代替fetchall取单条结果更高效:

def getRouteColor(route):
    cursor.execute('SELECT route_color FROM routes WHERE route_short_name = ?', (route,))
    return cursor.fetchone()[0]

不要用点阵、线条类的patternType模拟半透明,这类样式在不同版本的Excel、WPS中渲染效果差异极大,预计算纯色值的方案全平台兼容,显示效果一致。

内容的提问来源于stack exchange,提问作者Eijaf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 04:24:15