@@ -836,18 +836,8 @@ class ExcelWriter(metaclass=abc.ABCMeta):
836
836
837
837
Use engine_kwargs instead.
838
838
839
- Attributes
840
- ----------
841
- None
842
-
843
- Methods
844
- -------
845
- None
846
-
847
839
Notes
848
840
-----
849
- None of the methods and properties are considered public.
850
-
851
841
For compatibility with CSV writers, ExcelWriter serializes lists
852
842
and dicts to strings before writing.
853
843
@@ -1034,7 +1024,7 @@ def __new__(
1034
1024
return object .__new__ (cls )
1035
1025
1036
1026
# declare external properties you can count on
1037
- path = None
1027
+ _path = None
1038
1028
1039
1029
@property
1040
1030
@abc .abstractmethod
@@ -1054,7 +1044,16 @@ def sheets(self) -> dict[str, Any]:
1054
1044
"""Mapping of sheet names to sheet objects."""
1055
1045
pass
1056
1046
1047
+ @property
1057
1048
@abc .abstractmethod
1049
+ def book (self ):
1050
+ """
1051
+ Book instance. Class type will depend on the engine used.
1052
+
1053
+ This attribute can be used to access engine-specific features.
1054
+ """
1055
+ pass
1056
+
1058
1057
def write_cells (
1059
1058
self ,
1060
1059
cells ,
@@ -1066,6 +1065,8 @@ def write_cells(
1066
1065
"""
1067
1066
Write given formatted cells into Excel an excel sheet
1068
1067
1068
+ .. deprecated:: 1.5.0
1069
+
1069
1070
Parameters
1070
1071
----------
1071
1072
cells : generator
@@ -1077,12 +1078,47 @@ def write_cells(
1077
1078
freeze_panes: int tuple of length 2
1078
1079
contains the bottom-most row and right-most column to freeze
1079
1080
"""
1080
- pass
1081
+ self ._deprecate ("write_cells" )
1082
+ return self ._write_cells (cells , sheet_name , startrow , startcol , freeze_panes )
1081
1083
1082
1084
@abc .abstractmethod
1085
+ def _write_cells (
1086
+ self ,
1087
+ cells ,
1088
+ sheet_name : str | None = None ,
1089
+ startrow : int = 0 ,
1090
+ startcol : int = 0 ,
1091
+ freeze_panes : tuple [int , int ] | None = None ,
1092
+ ) -> None :
1093
+ """
1094
+ Write given formatted cells into Excel an excel sheet
1095
+
1096
+ Parameters
1097
+ ----------
1098
+ cells : generator
1099
+ cell of formatted data to save to Excel sheet
1100
+ sheet_name : str, default None
1101
+ Name of Excel sheet, if None, then use self.cur_sheet
1102
+ startrow : upper left cell row to dump data frame
1103
+ startcol : upper left cell column to dump data frame
1104
+ freeze_panes: int tuple of length 2
1105
+ contains the bottom-most row and right-most column to freeze
1106
+ """
1107
+ pass
1108
+
1083
1109
def save (self ) -> None :
1084
1110
"""
1085
1111
Save workbook to disk.
1112
+
1113
+ .. deprecated:: 1.5.0
1114
+ """
1115
+ self ._deprecate ("save" )
1116
+ return self ._save ()
1117
+
1118
+ @abc .abstractmethod
1119
+ def _save (self ) -> None :
1120
+ """
1121
+ Save workbook to disk.
1086
1122
"""
1087
1123
pass
1088
1124
@@ -1111,25 +1147,25 @@ def __init__(
1111
1147
mode = mode .replace ("a" , "r+" )
1112
1148
1113
1149
# cast ExcelWriter to avoid adding 'if self.handles is not None'
1114
- self .handles = IOHandles (
1150
+ self ._handles = IOHandles (
1115
1151
cast (IO [bytes ], path ), compression = {"compression" : None }
1116
1152
)
1117
1153
if not isinstance (path , ExcelWriter ):
1118
- self .handles = get_handle (
1154
+ self ._handles = get_handle (
1119
1155
path , mode , storage_options = storage_options , is_text = False
1120
1156
)
1121
- self .cur_sheet = None
1157
+ self ._cur_sheet = None
1122
1158
1123
1159
if date_format is None :
1124
- self .date_format = "YYYY-MM-DD"
1160
+ self ._date_format = "YYYY-MM-DD"
1125
1161
else :
1126
- self .date_format = date_format
1162
+ self ._date_format = date_format
1127
1163
if datetime_format is None :
1128
- self .datetime_format = "YYYY-MM-DD HH:MM:SS"
1164
+ self ._datetime_format = "YYYY-MM-DD HH:MM:SS"
1129
1165
else :
1130
- self .datetime_format = datetime_format
1166
+ self ._datetime_format = datetime_format
1131
1167
1132
- self .mode = mode
1168
+ self ._mode = mode
1133
1169
1134
1170
if if_sheet_exists not in (None , "error" , "new" , "replace" , "overlay" ):
1135
1171
raise ValueError (
@@ -1140,16 +1176,78 @@ def __init__(
1140
1176
raise ValueError ("if_sheet_exists is only valid in append mode (mode='a')" )
1141
1177
if if_sheet_exists is None :
1142
1178
if_sheet_exists = "error"
1143
- self .if_sheet_exists = if_sheet_exists
1179
+ self ._if_sheet_exists = if_sheet_exists
1180
+
1181
+ def _deprecate (self , attr : str ):
1182
+ """
1183
+ Deprecate attribute or method for ExcelWriter.
1184
+ """
1185
+ warnings .warn (
1186
+ f"{ attr } is not part of the public API, usage can give in unexpected "
1187
+ "results and will be removed in a future version" ,
1188
+ FutureWarning ,
1189
+ stacklevel = find_stack_level (),
1190
+ )
1191
+
1192
+ @property
1193
+ def date_format (self ) -> str :
1194
+ """
1195
+ Format string for dates written into Excel files (e.g. ‘YYYY-MM-DD’).
1196
+ """
1197
+ return self ._date_format
1198
+
1199
+ @property
1200
+ def datetime_format (self ) -> str :
1201
+ """
1202
+ Format string for dates written into Excel files (e.g. ‘YYYY-MM-DD’).
1203
+ """
1204
+ return self ._datetime_format
1205
+
1206
+ @property
1207
+ def if_sheet_exists (self ) -> str :
1208
+ """
1209
+ How to behave when writing to a sheet that already exists in append mode.
1210
+ """
1211
+ return self ._if_sheet_exists
1212
+
1213
+ @property
1214
+ def cur_sheet (self ):
1215
+ """
1216
+ Current sheet for writing.
1217
+
1218
+ .. deprecated:: 1.5.0
1219
+ """
1220
+ self ._deprecate ("cur_sheet" )
1221
+ return self ._cur_sheet
1222
+
1223
+ @property
1224
+ def handles (self ):
1225
+ """
1226
+ Handles to Excel sheets.
1227
+
1228
+ .. deprecated:: 1.5.0
1229
+ """
1230
+ self ._deprecate ("handles" )
1231
+ return self ._handles
1232
+
1233
+ @property
1234
+ def path (self ):
1235
+ """
1236
+ Path to Excel file.
1237
+
1238
+ .. deprecated:: 1.5.0
1239
+ """
1240
+ self ._deprecate ("path" )
1241
+ return self ._path
1144
1242
1145
1243
def __fspath__ (self ):
1146
- return getattr (self .handles .handle , "name" , "" )
1244
+ return getattr (self ._handles .handle , "name" , "" )
1147
1245
1148
1246
def _get_sheet_name (self , sheet_name : str | None ) -> str :
1149
1247
if sheet_name is None :
1150
- sheet_name = self .cur_sheet
1248
+ sheet_name = self ._cur_sheet
1151
1249
if sheet_name is None : # pragma: no cover
1152
- raise ValueError ("Must pass explicit sheet_name or set cur_sheet property" )
1250
+ raise ValueError ("Must pass explicit sheet_name or set _cur_sheet property" )
1153
1251
return sheet_name
1154
1252
1155
1253
def _value_with_fmt (self , val ) -> tuple [object , str | None ]:
@@ -1175,9 +1273,9 @@ def _value_with_fmt(self, val) -> tuple[object, str | None]:
1175
1273
elif is_bool (val ):
1176
1274
val = bool (val )
1177
1275
elif isinstance (val , datetime .datetime ):
1178
- fmt = self .datetime_format
1276
+ fmt = self ._datetime_format
1179
1277
elif isinstance (val , datetime .date ):
1180
- fmt = self .date_format
1278
+ fmt = self ._date_format
1181
1279
elif isinstance (val , datetime .timedelta ):
1182
1280
val = val .total_seconds () / 86400
1183
1281
fmt = "0"
@@ -1213,8 +1311,8 @@ def __exit__(self, exc_type, exc_value, traceback):
1213
1311
1214
1312
def close (self ) -> None :
1215
1313
"""synonym for save, to make it more file-like"""
1216
- self .save ()
1217
- self .handles .close ()
1314
+ self ._save ()
1315
+ self ._handles .close ()
1218
1316
1219
1317
1220
1318
XLS_SIGNATURES = (
0 commit comments