@@ -836,18 +836,8 @@ class ExcelWriter(metaclass=abc.ABCMeta):
836836
837837 Use engine_kwargs instead.
838838
839- Attributes
840- ----------
841- None
842-
843- Methods
844- -------
845- None
846-
847839 Notes
848840 -----
849- None of the methods and properties are considered public.
850-
851841 For compatibility with CSV writers, ExcelWriter serializes lists
852842 and dicts to strings before writing.
853843
@@ -1034,7 +1024,7 @@ def __new__(
10341024 return object .__new__ (cls )
10351025
10361026 # declare external properties you can count on
1037- path = None
1027+ _path = None
10381028
10391029 @property
10401030 @abc .abstractmethod
@@ -1054,7 +1044,16 @@ def sheets(self) -> dict[str, Any]:
10541044 """Mapping of sheet names to sheet objects."""
10551045 pass
10561046
1047+ @property
10571048 @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+
10581057 def write_cells (
10591058 self ,
10601059 cells ,
@@ -1066,6 +1065,8 @@ def write_cells(
10661065 """
10671066 Write given formatted cells into Excel an excel sheet
10681067
1068+ .. deprecated:: 1.5.0
1069+
10691070 Parameters
10701071 ----------
10711072 cells : generator
@@ -1077,12 +1078,47 @@ def write_cells(
10771078 freeze_panes: int tuple of length 2
10781079 contains the bottom-most row and right-most column to freeze
10791080 """
1080- pass
1081+ self ._deprecate ("write_cells" )
1082+ return self ._write_cells (cells , sheet_name , startrow , startcol , freeze_panes )
10811083
10821084 @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+
10831109 def save (self ) -> None :
10841110 """
10851111 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.
10861122 """
10871123 pass
10881124
@@ -1111,25 +1147,25 @@ def __init__(
11111147 mode = mode .replace ("a" , "r+" )
11121148
11131149 # cast ExcelWriter to avoid adding 'if self.handles is not None'
1114- self .handles = IOHandles (
1150+ self ._handles = IOHandles (
11151151 cast (IO [bytes ], path ), compression = {"compression" : None }
11161152 )
11171153 if not isinstance (path , ExcelWriter ):
1118- self .handles = get_handle (
1154+ self ._handles = get_handle (
11191155 path , mode , storage_options = storage_options , is_text = False
11201156 )
1121- self .cur_sheet = None
1157+ self ._cur_sheet = None
11221158
11231159 if date_format is None :
1124- self .date_format = "YYYY-MM-DD"
1160+ self ._date_format = "YYYY-MM-DD"
11251161 else :
1126- self .date_format = date_format
1162+ self ._date_format = date_format
11271163 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"
11291165 else :
1130- self .datetime_format = datetime_format
1166+ self ._datetime_format = datetime_format
11311167
1132- self .mode = mode
1168+ self ._mode = mode
11331169
11341170 if if_sheet_exists not in (None , "error" , "new" , "replace" , "overlay" ):
11351171 raise ValueError (
@@ -1140,16 +1176,78 @@ def __init__(
11401176 raise ValueError ("if_sheet_exists is only valid in append mode (mode='a')" )
11411177 if if_sheet_exists is None :
11421178 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
11441242
11451243 def __fspath__ (self ):
1146- return getattr (self .handles .handle , "name" , "" )
1244+ return getattr (self ._handles .handle , "name" , "" )
11471245
11481246 def _get_sheet_name (self , sheet_name : str | None ) -> str :
11491247 if sheet_name is None :
1150- sheet_name = self .cur_sheet
1248+ sheet_name = self ._cur_sheet
11511249 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" )
11531251 return sheet_name
11541252
11551253 def _value_with_fmt (self , val ) -> tuple [object , str | None ]:
@@ -1175,9 +1273,9 @@ def _value_with_fmt(self, val) -> tuple[object, str | None]:
11751273 elif is_bool (val ):
11761274 val = bool (val )
11771275 elif isinstance (val , datetime .datetime ):
1178- fmt = self .datetime_format
1276+ fmt = self ._datetime_format
11791277 elif isinstance (val , datetime .date ):
1180- fmt = self .date_format
1278+ fmt = self ._date_format
11811279 elif isinstance (val , datetime .timedelta ):
11821280 val = val .total_seconds () / 86400
11831281 fmt = "0"
@@ -1213,8 +1311,8 @@ def __exit__(self, exc_type, exc_value, traceback):
12131311
12141312 def close (self ) -> None :
12151313 """synonym for save, to make it more file-like"""
1216- self .save ()
1217- self .handles .close ()
1314+ self ._save ()
1315+ self ._handles .close ()
12181316
12191317
12201318XLS_SIGNATURES = (
0 commit comments