【发布时间】:2020-02-17 01:24:27
【问题描述】:
所以我的应用程序必须找到单元格内文本的值和颜色。我可以找到文本的背景颜色。例如,我的单元格值为“Hello my name is ... nice to meet you”(粗体字表示颜色为红色),所以当我找到颜色并看到红色文字时,我想删除它我知道如何删除它,但不知道如何找到单元格值的 TEXT 颜色。
【问题讨论】:
标签: python python-3.x openpyxl
所以我的应用程序必须找到单元格内文本的值和颜色。我可以找到文本的背景颜色。例如,我的单元格值为“Hello my name is ... nice to meet you”(粗体字表示颜色为红色),所以当我找到颜色并看到红色文字时,我想删除它我知道如何删除它,但不知道如何找到单元格值的 TEXT 颜色。
【问题讨论】:
标签: python python-3.x openpyxl
令人惊讶的是,这并不像它可能的那么简单,但如果您遵循逻辑,它对于标准文本颜色格式是有意义的。
要识别字体颜色值,需要遍历单元格属性:
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 英镑花园
(单元格多样式) SEGMENTS:
人 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个默认为自定义红色。
【讨论】: