diff --git a/pandas/io/formats/excel.py b/pandas/io/formats/excel.py index 5fde6577e9f95..f2cf1a4838c36 100644 --- a/pandas/io/formats/excel.py +++ b/pandas/io/formats/excel.py @@ -303,13 +303,13 @@ def _border_style( # 'slantDashDot' # 'thick' # 'thin' - if width is None and style is None and color is None: - # Return None will remove "border" from style dictionary - return None - if width is None and style is None: - # Return "none" will keep "border" in style dictionary - return "none" + if color is None: + # Return None will remove "border" from style dictionary + return None + else: + # Return "none" will keep "border" in style dictionary + return "none" if style in ("none", "hidden"): return "none" @@ -411,11 +411,6 @@ def _get_decoration(self, props: Mapping[str, str]) -> Sequence[str]: else: return () - def _get_underline(self, decoration: Sequence[str]) -> str | None: - if "underline" in decoration: - return "single" - return None - def _get_shadow(self, props: Mapping[str, str]) -> bool | None: if "text-shadow" in props: return bool(re.search("^[^#(]*[1-9]", props["text-shadow"])) diff --git a/pandas/tests/io/formats/test_to_excel.py b/pandas/tests/io/formats/test_to_excel.py index b40201b9ba1e6..babbfcb46a6fc 100644 --- a/pandas/tests/io/formats/test_to_excel.py +++ b/pandas/tests/io/formats/test_to_excel.py @@ -156,6 +156,14 @@ "border-top-style: solid; border-top-width: 4pt", {"border": {"top": {"style": "thick"}}}, ), + ( + "border-top-style: solid; border-top-width: none", + {"border": {"top": {"style": "none"}}}, + ), + ( + "border-top-style: solid; border-top-width: 0.000001pt", + {"border": {"top": {"style": "none"}}}, + ), ( "border-top-style: dotted", {"border": {"top": {"style": "mediumDashDotDot"}}}, @@ -194,6 +202,10 @@ "border-top-color: blue", {"border": {"top": {"color": "0000FF", "style": "none"}}}, ), + ( + "border-top-style: slantDashDot; border-top-color: blue", + {"border": {"top": {"style": "slantDashDot", "color": "0000FF"}}}, + ), # ALIGNMENT # - horizontal ("text-align: center", {"alignment": {"horizontal": "center"}}), @@ -249,6 +261,20 @@ def test_css_to_excel_multiple(): } == actual +@pytest.mark.parametrize( + "css", + [ + "border-top-style: unhandled-border-style", + "border-style: another-unhandled-style", + ], +) +def test_css_to_excel_unhandled_border_style_warns(css): + """Test that unhandled border styles raise a CSSWarning.""" + convert = CSSToExcelConverter() + with tm.assert_produces_warning(CSSWarning, match="Unhandled border style format"): + convert(css) + + @pytest.mark.parametrize( "css,inherited,expected", [ @@ -330,6 +356,23 @@ def test_css_to_excel_bad_colors(input_color): assert expected == convert(css) +@pytest.mark.parametrize("input_color", ["#", "#1234567"]) +def test_css_to_excel_invalid_color_raises(input_color): + """Test that invalid colors raise a ValueError.""" + css = ( + f"border-top-color: {input_color}; " + f"border-right-color: {input_color}; " + f"border-bottom-color: {input_color}; " + f"border-left-color: {input_color}; " + f"background-color: {input_color}; " + f"color: {input_color}" + ) + + convert = CSSToExcelConverter() + with pytest.raises(ValueError, match=f"Unexpected color {input_color}"): + convert(css) + + def tests_css_named_colors_valid(): upper_hexs = set(map(str.upper, string.hexdigits)) for color in CSSToExcelConverter.NAMED_COLORS.values():