feat: FormattingDetector(取消线/背景色/批注)
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from genesis.data_models import CellComment, CellFormatting
|
||||
from genesis.parsers.provenance import build_source_uri
|
||||
|
||||
_BLACK_RGB = ("00000000", "FF000000")
|
||||
|
||||
|
||||
def _to_rgb_hex(color) -> str | None:
|
||||
"""将 openpyxl Color 转为 RGB 十六进制;非 RGB 主题色/默认色返回 None"""
|
||||
if color is None:
|
||||
return None
|
||||
try:
|
||||
value = str(color.rgb)
|
||||
except Exception:
|
||||
return None
|
||||
if not value or value in _BLACK_RGB:
|
||||
return None
|
||||
if len(value) not in (6, 8):
|
||||
return None
|
||||
if not all(ch in "0123456789ABCDEFabcdef" for ch in value):
|
||||
return None
|
||||
return value
|
||||
|
||||
|
||||
def cell_formatting(cell) -> CellFormatting | None:
|
||||
strike = bool(cell.font.strike)
|
||||
font_color = _to_rgb_hex(getattr(cell.font, "color", None))
|
||||
bg_color = None
|
||||
fill = cell.fill
|
||||
if fill is not None:
|
||||
bg_color = _to_rgb_hex(getattr(fill, "fgColor", None))
|
||||
if strike or font_color or bg_color:
|
||||
return CellFormatting(
|
||||
strikethrough=strike, font_color=font_color, bg_color=bg_color,
|
||||
)
|
||||
return None
|
||||
|
||||
|
||||
def cell_comment(cell, file_name: str) -> CellComment | None:
|
||||
if cell.comment is None:
|
||||
return None
|
||||
return CellComment(
|
||||
author=cell.comment.author or "",
|
||||
text=cell.comment.text or "",
|
||||
source_uri=build_source_uri(file_name, cell.parent.title, cell.coordinate),
|
||||
)
|
||||
|
||||
|
||||
def collect_comments(ws, file_name: str) -> list[CellComment]:
|
||||
result = []
|
||||
for row in ws.iter_rows():
|
||||
for cell in row:
|
||||
cm = cell_comment(cell, file_name)
|
||||
if cm is not None:
|
||||
result.append(cm)
|
||||
return result
|
||||
Reference in New Issue
Block a user