diff --git a/doc/source/whatsnew/v1.0.0.rst b/doc/source/whatsnew/v1.0.0.rst index 58918f2d8c40e..7c02a6e72f0cb 100644 --- a/doc/source/whatsnew/v1.0.0.rst +++ b/doc/source/whatsnew/v1.0.0.rst @@ -83,6 +83,7 @@ Performance improvements Bug fixes ~~~~~~~~~ +- Bug in :meth:`DataFrame.to_html` when using ``formatters=`` and ``max_cols`` together. (:issue:`25955`) Categorical ^^^^^^^^^^^ diff --git a/pandas/io/formats/format.py b/pandas/io/formats/format.py index 61af935bd8227..fd1afcff1dce0 100644 --- a/pandas/io/formats/format.py +++ b/pandas/io/formats/format.py @@ -656,6 +656,13 @@ def _chk_truncate(self) -> None: frame = concat( (frame.iloc[:, :col_num], frame.iloc[:, -col_num:]), axis=1 ) + # truncate formatter + if isinstance(self.formatters, (list, tuple)): + truncate_fmt = self.formatters + self.formatters = [ + *truncate_fmt[:col_num], + *truncate_fmt[-col_num:], + ] self.tr_col_num = col_num if truncate_v: # cast here since if truncate_v is True, max_rows_adj is not None diff --git a/pandas/tests/io/formats/data/html/truncate_formatter.html b/pandas/tests/io/formats/data/html/truncate_formatter.html new file mode 100644 index 0000000000000..7615ef89d85d1 --- /dev/null +++ b/pandas/tests/io/formats/data/html/truncate_formatter.html @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
A...D
01_mod...4
15_mod...8
29_mod...12
313_mod...16
diff --git a/pandas/tests/io/formats/test_to_html.py b/pandas/tests/io/formats/test_to_html.py index 448e869df950d..b21f437f2b6e9 100644 --- a/pandas/tests/io/formats/test_to_html.py +++ b/pandas/tests/io/formats/test_to_html.py @@ -235,6 +235,23 @@ def test_to_html_truncate(datapath): assert result == expected +def test_to_html_truncate_formatter(datapath): + # issue-25955 + data = [ + {"A": 1, "B": 2, "C": 3, "D": 4}, + {"A": 5, "B": 6, "C": 7, "D": 8}, + {"A": 9, "B": 10, "C": 11, "D": 12}, + {"A": 13, "B": 14, "C": 15, "D": 16}, + ] + + df = DataFrame(data) + fmt = lambda x: str(x) + "_mod" + formatters = [fmt, fmt, None, None] + result = df.to_html(formatters=formatters, max_cols=3) + expected = expected_html(datapath, "truncate_formatter") + assert result == expected + + @pytest.mark.parametrize( "sparsify,expected", [(True, "truncate_multi_index"), (False, "truncate_multi_index_sparse_off")],