@@ -45,11 +45,13 @@ def get_writer(engine_name):
45
45
except KeyError :
46
46
raise ValueError ("No Excel writer '%s'" % engine_name )
47
47
48
- def read_excel (path_or_buf , sheetname , ** kwds ):
48
+ def read_excel (io , sheetname , ** kwds ):
49
49
"""Read an Excel table into a pandas DataFrame
50
50
51
51
Parameters
52
52
----------
53
+ io : string, file-like object or xlrd workbook
54
+ If a string, expected to be a path to xls or xlsx file
53
55
sheetname : string
54
56
Name of Excel sheet
55
57
header : int, default 0
@@ -74,7 +76,10 @@ def read_excel(path_or_buf, sheetname, **kwds):
74
76
values are overridden, otherwise they're appended to
75
77
verbose : boolean, default False
76
78
Indicate number of NA values placed in non-numeric columns
77
-
79
+ engine: string, default None
80
+ If io is not a buffer or path, this must be set to identify io.
81
+ Acceptable values are None or xlrd
82
+
78
83
Returns
79
84
-------
80
85
parsed : DataFrame
@@ -84,7 +89,10 @@ def read_excel(path_or_buf, sheetname, **kwds):
84
89
kwds .pop ('kind' )
85
90
warn ("kind keyword is no longer supported in read_excel and may be "
86
91
"removed in a future version" , FutureWarning )
87
- return ExcelFile (path_or_buf ).parse (sheetname = sheetname , ** kwds )
92
+
93
+ engine = kwds .pop ('engine' , None )
94
+
95
+ return ExcelFile (io , engine = engine ).parse (sheetname = sheetname , ** kwds )
88
96
89
97
90
98
class ExcelFile (object ):
@@ -94,10 +102,13 @@ class ExcelFile(object):
94
102
95
103
Parameters
96
104
----------
97
- path : string or file-like object
98
- Path to xls or xlsx file
105
+ io : string, file-like object or xlrd workbook
106
+ If a string, expected to be a path to xls or xlsx file
107
+ engine: string, default None
108
+ If io is not a buffer or path, this must be set to identify io.
109
+ Acceptable values are None or xlrd
99
110
"""
100
- def __init__ (self , path_or_buf , ** kwds ):
111
+ def __init__ (self , io , ** kwds ):
101
112
102
113
import xlrd # throw an ImportError if we need to
103
114
@@ -106,14 +117,22 @@ def __init__(self, path_or_buf, **kwds):
106
117
raise ImportError ("pandas requires xlrd >= 0.9.0 for excel "
107
118
"support, current version " + xlrd .__VERSION__ )
108
119
109
- self .path_or_buf = path_or_buf
110
- self .tmpfile = None
111
-
112
- if isinstance (path_or_buf , compat .string_types ):
113
- self .book = xlrd .open_workbook (path_or_buf )
114
- else :
115
- data = path_or_buf .read ()
120
+ self .io = io
121
+
122
+ engine = kwds .pop ('engine' , None )
123
+
124
+ if engine is not None and engine != 'xlrd' :
125
+ raise ValueError ("Unknown engine: %s" % engine )
126
+
127
+ if isinstance (io , compat .string_types ):
128
+ self .book = xlrd .open_workbook (io )
129
+ elif engine == "xlrd" and isinstance (io , xlrd .Book ):
130
+ self .book = io
131
+ elif hasattr (io , "read" ):
132
+ data = io .read ()
116
133
self .book = xlrd .open_workbook (file_contents = data )
134
+ else :
135
+ raise ValueError ('Must explicitly set engine if not passing in buffer or path for io.' )
117
136
118
137
def parse (self , sheetname , header = 0 , skiprows = None , skip_footer = 0 ,
119
138
index_col = None , parse_cols = None , parse_dates = False ,
@@ -261,9 +280,9 @@ def sheet_names(self):
261
280
return self .book .sheet_names ()
262
281
263
282
def close (self ):
264
- """close path_or_buf if necessary"""
265
- if hasattr (self .path_or_buf , 'close' ):
266
- self .path_or_buf .close ()
283
+ """close io if necessary"""
284
+ if hasattr (self .io , 'close' ):
285
+ self .io .close ()
267
286
268
287
def __enter__ (self ):
269
288
return self
0 commit comments