fix: 修改文本颜色未使用问题

This commit is contained in:
fuzhongyun 2025-12-30 16:35:09 +08:00
parent abc8db580c
commit b429b8e874
4 changed files with 74 additions and 8 deletions

View File

@ -179,8 +179,9 @@ class ExcelRenderer:
current_font = self._get_font(is_bold, font_size) current_font = self._get_font(is_bold, font_size)
# Font color # Font color
font_color_hex = cell.font.color.rgb if (cell.font and cell.font.color) else None # Excel's Color object can be complex. We pass the whole object to _parse_color.
text_color = self._parse_color(font_color_hex, default=(0, 0, 0)) font_color_obj = cell.font.color if (cell.font and cell.font.color) else None
text_color = self._parse_color(font_color_obj, default=(0, 0, 0))
# Alignment # Alignment
h_align = cell.alignment.horizontal if (cell.alignment and cell.alignment.horizontal) else 'left' h_align = cell.alignment.horizontal if (cell.alignment and cell.alignment.horizontal) else 'left'
@ -189,15 +190,44 @@ class ExcelRenderer:
# Text rendering with simple truncation # Text rendering with simple truncation
self._draw_text(draw, text, x1, y1, x2, y2, current_font, text_color, h_align, v_align, font_size) self._draw_text(draw, text, x1, y1, x2, y2, current_font, text_color, h_align, v_align, font_size)
def _parse_color(self, color_code, default=(0, 0, 0)) -> Tuple[int, int, int]: def _parse_color(self, color_obj, default=(0, 0, 0)) -> Tuple[int, int, int]:
if not color_code or color_code == '00000000' or not isinstance(color_code, str): """
Parse Excel color object to RGB tuple.
"""
if not color_obj:
return default return default
# Handle ARGB (Excel often uses this) color_code = None
# If it's a string, treat as hex
if isinstance(color_obj, str):
color_code = color_obj
# If it's a Color object
elif hasattr(color_obj, 'type'):
if color_obj.type == 'rgb':
color_code = color_obj.rgb
elif color_obj.type == 'theme':
# Use hardcoded common theme colors as a fallback for MVP
# Theme 0: Light 1 (White) - FFFFFF
# Theme 1: Dark 1 (Black) - 000000
# Theme 2: Light 2 (EEECE1)
# Theme 3: Dark 2 (1F497D)
if color_obj.theme == 0:
color_code = "FFFFFFFF" # White
elif color_obj.theme == 1:
color_code = "FF000000" # Black
else:
# Attempt to check if rgb is populated even for theme
if hasattr(color_obj, 'rgb') and color_obj.rgb:
color_code = color_obj.rgb
elif hasattr(color_obj, 'rgb'):
color_code = color_obj.rgb
if not color_code or color_code == '00000000':
return default
# Handle ARGB
if len(color_code) > 6: if len(color_code) > 6:
# Strip alpha if present (usually first 2 chars for ARGB)
# Example: FF000000 -> 000000 (Black), FFFFFFFF -> FFFFFF (White)
# Note: This is a simplification.
if color_code.startswith('FF') or len(color_code) == 8: if color_code.startswith('FF') or len(color_code) == 8:
color_code = color_code[2:] color_code = color_code[2:]

Binary file not shown.

BIN
tests/kshj_gt1767081783800.xlsx Executable file

Binary file not shown.

36
tests/test_font_color.py Normal file
View File

@ -0,0 +1,36 @@
import pytest
import io
import os
from core.renderer import ExcelRenderer
from PIL import Image
# Use the file provided by the user for reproduction
TEST_FILE_PATH = "tests/kshj_gt1767081783800.xlsx"
@pytest.mark.skipif(not os.path.exists(TEST_FILE_PATH), reason="Test file not found")
def test_font_color_rendering_real_file():
"""
Test rendering with a real file that has font color issues.
This test will generate an output image for visual inspection.
"""
with open(TEST_FILE_PATH, "rb") as f:
content = f.read()
renderer = ExcelRenderer(content)
try:
# Render the first sheet (or specific sheet if known, default to active)
img_bytes = renderer.render_to_bytes()
# Save for visual inspection
output_path = "tests/test_output_font_color.png"
with open(output_path, "wb") as f_out:
f_out.write(img_bytes)
print(f"Generated test image at: {os.path.abspath(output_path)}")
assert isinstance(img_bytes, bytes)
assert len(img_bytes) > 0
except Exception as e:
pytest.fail(f"Rendering failed: {e}")