@@ -45,11 +45,13 @@ def get_writer(engine_name):
4545 except KeyError :
4646 raise ValueError ("No Excel writer '%s'" % engine_name )
4747
48- def read_excel (path_or_buf , sheetname , ** kwds ):
48+ def read_excel (io , sheetname , ** kwds ):
4949 """Read an Excel table into a pandas DataFrame
5050
5151 Parameters
5252 ----------
53+ io : string, file-like object or xlrd workbook
54+ If a string, expected to be a path to xls or xlsx file
5355 sheetname : string
5456 Name of Excel sheet
5557 header : int, default 0
@@ -74,7 +76,10 @@ def read_excel(path_or_buf, sheetname, **kwds):
7476 values are overridden, otherwise they're appended to
7577 verbose : boolean, default False
7678 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+
7883 Returns
7984 -------
8085 parsed : DataFrame
@@ -84,7 +89,10 @@ def read_excel(path_or_buf, sheetname, **kwds):
8489 kwds .pop ('kind' )
8590 warn ("kind keyword is no longer supported in read_excel and may be "
8691 "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 )
8896
8997
9098class ExcelFile (object ):
@@ -94,10 +102,13 @@ class ExcelFile(object):
94102
95103 Parameters
96104 ----------
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
99110 """
100- def __init__ (self , path_or_buf , ** kwds ):
111+ def __init__ (self , io , ** kwds ):
101112
102113 import xlrd # throw an ImportError if we need to
103114
@@ -106,14 +117,22 @@ def __init__(self, path_or_buf, **kwds):
106117 raise ImportError ("pandas requires xlrd >= 0.9.0 for excel "
107118 "support, current version " + xlrd .__VERSION__ )
108119
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 ()
116133 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.' )
117136
118137 def parse (self , sheetname , header = 0 , skiprows = None , skip_footer = 0 ,
119138 index_col = None , parse_cols = None , parse_dates = False ,
@@ -261,9 +280,9 @@ def sheet_names(self):
261280 return self .book .sheet_names ()
262281
263282 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 ()
267286
268287 def __enter__ (self ):
269288 return self
0 commit comments