diff --git a/doc/source/whatsnew/v3.0.0.rst b/doc/source/whatsnew/v3.0.0.rst index 6d41c29a6c614..ec6172b4a7ba6 100644 --- a/doc/source/whatsnew/v3.0.0.rst +++ b/doc/source/whatsnew/v3.0.0.rst @@ -28,7 +28,7 @@ enhancement2 Other enhancements ^^^^^^^^^^^^^^^^^^ -- +- :func:`DataFrame.to_excel` now raises an ``UserWarning`` when the character count in a cell exceeds Excel's limitation of 32767 characters (:issue:`56954`) - .. --------------------------------------------------------------------------- diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 87a394761ee7c..9a65e53722d57 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -2363,6 +2363,10 @@ def to_excel( Once a workbook has been saved it is not possible to write further data without rewriting the whole workbook. + pandas will check the number of rows, columns, + and cell character count does not exceed Excel's limitations. + All other limitations must be checked by the user. + Examples -------- diff --git a/pandas/io/excel/_base.py b/pandas/io/excel/_base.py index c7642236d4b2a..4109b6d0965bb 100644 --- a/pandas/io/excel/_base.py +++ b/pandas/io/excel/_base.py @@ -1326,7 +1326,15 @@ def _value_with_fmt( fmt = "0" else: val = str(val) - + # GH#56954 + # Excel's limitation on cell contents is 32767 characters + # xref https://support.microsoft.com/en-au/office/excel-specifications-and-limits-1672b34d-7043-467e-8e27-269d656771c3 + if len(val) > 32767: + warnings.warn( + "Cell contents too long, truncated to 32767 characters", + UserWarning, + stacklevel=find_stack_level(), + ) return val, fmt @classmethod diff --git a/pandas/tests/io/excel/test_writers.py b/pandas/tests/io/excel/test_writers.py index 6aea7464ee8dc..6ea48cd759fbc 100644 --- a/pandas/tests/io/excel/test_writers.py +++ b/pandas/tests/io/excel/test_writers.py @@ -1385,6 +1385,18 @@ def test_to_excel_empty_frame(self, engine, ext): expected = DataFrame() tm.assert_frame_equal(result, expected) + def test_to_excel_raising_warning_when_cell_character_exceed_limit( + self, path, engine + ): + # GH#56954 + df = DataFrame({"A": ["a" * 32768]}) + msg = "Cell contents too long, truncated to 32767 characters" + with tm.assert_produces_warning( + UserWarning, match=msg, raise_on_extra_warnings=False + ): + buf = BytesIO() + df.to_excel(buf) + class TestExcelWriterEngineTests: @pytest.mark.parametrize(