Skip to content

Commit feaa963

Browse files
BUG: Fix to_excel storing decimals as strings instead of numbers (issue #49598) (#60230)
* Fix issue 50174 * Add release notes * Use correct github issue number
1 parent 692ea6f commit feaa963

File tree

3 files changed

+36
-1
lines changed

3 files changed

+36
-1
lines changed

doc/source/whatsnew/v2.3.0.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ MultiIndex
133133

134134
I/O
135135
^^^
136-
-
136+
- :meth:`DataFrame.to_excel` was storing decimals as strings instead of numbers (:issue:`49598`)
137137
-
138138

139139
Period

pandas/io/excel/_base.py

+4
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
Sequence,
99
)
1010
import datetime
11+
from decimal import Decimal
1112
from functools import partial
1213
import os
1314
from textwrap import fill
@@ -43,6 +44,7 @@
4344

4445
from pandas.core.dtypes.common import (
4546
is_bool,
47+
is_decimal,
4648
is_file_like,
4749
is_float,
4850
is_integer,
@@ -1348,6 +1350,8 @@ def _value_with_fmt(
13481350
val = float(val)
13491351
elif is_bool(val):
13501352
val = bool(val)
1353+
elif is_decimal(val):
1354+
val = Decimal(val)
13511355
elif isinstance(val, datetime.datetime):
13521356
fmt = self._datetime_format
13531357
elif isinstance(val, datetime.date):

pandas/tests/io/excel/test_writers.py

+31
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
datetime,
44
timedelta,
55
)
6+
from decimal import Decimal
67
from functools import partial
78
from io import BytesIO
89
import os
@@ -977,6 +978,36 @@ def test_to_excel_float_format(self, tmp_excel):
977978
)
978979
tm.assert_frame_equal(result, expected)
979980

981+
def test_to_excel_datatypes_preserved(self, tmp_excel):
982+
# Test that when writing and reading Excel with dtype=object,
983+
# datatypes are preserved, except Decimals which should be
984+
# stored as floats
985+
986+
# see gh-49598
987+
df = DataFrame(
988+
[
989+
[1.23, "1.23", Decimal("1.23")],
990+
[4.56, "4.56", Decimal("4.56")],
991+
],
992+
index=["A", "B"],
993+
columns=["X", "Y", "Z"],
994+
)
995+
df.to_excel(tmp_excel)
996+
997+
with ExcelFile(tmp_excel) as reader:
998+
result = pd.read_excel(reader, index_col=0, dtype=object)
999+
1000+
expected = DataFrame(
1001+
[
1002+
[1.23, "1.23", 1.23],
1003+
[4.56, "4.56", 4.56],
1004+
],
1005+
index=["A", "B"],
1006+
columns=["X", "Y", "Z"],
1007+
dtype=object,
1008+
)
1009+
tm.assert_frame_equal(result, expected)
1010+
9801011
def test_to_excel_output_encoding(self, tmp_excel):
9811012
# Avoid mixed inferred_type.
9821013
df = DataFrame(

0 commit comments

Comments
 (0)