使用openpyxl查找TEXT的颜色

时间:2019-10-20 23:21:37

标签: python python-3.x openpyxl

因此,我的应用程序必须在单元格内查找文本的值和颜色。我可以找到文本的背景色。例如,我的单元格值为“您好我的名字是... ,很高兴认识您”(粗体字表示颜色为红色),因此当我找到颜色并看到红色文本时,我想删除它我对如何删除它有一个想法,但是如果单元格值不知道如何找到TEXT颜色。

1 个答案:

答案 0 :(得分:0)

令人惊讶的是,这并不像它看起来那么简单,但是如果您遵循逻辑,那么它对于标准的文本颜色格式是有意义的。

要识别字体颜色值,需要遍历单元格属性:

  

cell将返回一个Cell对象
  cell.font将返回一个Font对象
  cell.font.color将返回一个Color对象

下面是现有工作簿的REPL输出:

>> from openpyxl import load_workbook
>> from openpyxl.styles import Font
>> wb = load_workbook('example.xlsx')
>> sheet0 = wb['FEB 2019']
>>> print(sheet0['C20'].font)
<openpyxl.styles.fonts.Font object>
Parameters:
name='Calibri', charset=None, family=None, b=False, i=False, strike=False, outline=None, shadow=None, condense=None, color=<openpyxl.styles.colors.Color object>
Parameters:
rgb='00ffffff', indexed=None, auto=None, theme=None, tint=0.0, type='rgb', extend=None, sz=11.0, u=None, vertAlign=None, scheme=None
>>> print(sheet0['A1'].font.color)
<openpyxl.styles.colors.Color object>
Parameters:
rgb='00ffffff', indexed=None, auto=None, theme=None, tint=0.0, type='rgb'

在此示例中要注意的重点是颜色是在 rgb 中指定的(不确定是否可以在CMYK或其他选项中输出)

这导致对象属性

  

cell.font.color.rgb

相同
>>> print(sheet0['A1'].font.color.rgb)
00ffffff

如果单元格内容为富文本,则openpyxl无法处理此内容。原来将颜色应用于单元格的一部分需要富文本格式。有关该库中的已知问题,请参见https://bitbucket.org/openpyxl/openpyxl/issues/20/richtext-request

可以用xlrd完成,但只能使用旧的xls格式,不能使用现代的xlsx。请参见以下stackoverflow答案:How do I find the formatting for a subset of text in an Excel document cell(这是python2代码,但易于转换为python3)(请参见下文-我还添加了行print('colour:', segment['font'].colour_index),以显示特定的颜色。

#! /usr/bin/env python
# -*- coding: utf-8 -*-

import xlrd

# accessing Column 'C' in this example
COL_IDX = 2

book = xlrd.open_workbook('example.xls', formatting_info=True)
first_sheet = book.sheet_by_index(0)

for row_idx in range(first_sheet.nrows):
  text_cell = first_sheet.cell_value(row_idx, COL_IDX)
  text_cell_xf = book.xf_list[first_sheet.cell_xf_index(row_idx, COL_IDX)]

  # skip rows where cell is empty
  if not text_cell:
    continue
  print(text_cell)

  text_cell_runlist = first_sheet.rich_text_runlist_map.get((row_idx, COL_IDX))
  if text_cell_runlist:
    print('(cell multi style) SEGMENTS:')
    segments = []
    for segment_idx in range(len(text_cell_runlist)):
      start = text_cell_runlist[segment_idx][0]
      # the last segment starts at given 'start' and ends at the end of the string
      end = None
      if segment_idx != len(text_cell_runlist) - 1:
        end = text_cell_runlist[segment_idx + 1][0]
      segment_text = text_cell[start:end]
      segments.append({
        'text': segment_text,
        'font': book.font_list[text_cell_runlist[segment_idx][1]]
      })
    # segments did not start at beginning, assume cell starts with text styled as the cell
    if text_cell_runlist[0][0] != 0:
      segments.insert(0, {
        'text': text_cell[:text_cell_runlist[0][0]],
        'font': book.font_list[text_cell_xf.font_index]
      })

    for segment in segments:
      print(segment['text'])
      print('italic:', segment['font'].italic)
      print('bold:', segment['font'].bold)
      print('colour:', segment['font'].colour_index)

  else:
    print('(cell single style)')
    print('italic:', book.font_list[text_cell_xf.font_index].italic)
    print('bold:', book.font_list[text_cell_xf.font_index].bold)
    print('colour:', book.font_list[text_cell_xf.font_index].colour_index)

将您的example.xlsx转换为example.xls,对于单元格C24,将提供以下输出:

  

Person O,花园£216
  (单元格多样式)细分:
  O人,216英镑
  斜体:0
  粗体:1
  颜色:8
  花园
  斜体:0
  粗体:1
  颜色:10

斜体/粗体0/1可能是布尔值(1为True)。

颜色取决于存储在工作簿中的颜色图(因为用户可以定义自己的颜色图:https://xlrd.readthedocs.io/en/latest/formatting.html#palette)。 0-7是系统固定的,8+是用户定义的。 8个默认为用户定义的黑色,10个默认为用户定义的红色。