Loads an arbitrary file type (xlsx, xls, or csv like) and returns
    a list of 2D tables. For csv files this will be a list of one table,
    but excel formats can have many tables/worksheets.

    TODO:
        Add wrapper which can be closed/exited on each file type which cleans
        up the file handler.

    Args:
        file_name: The name of the local file, or the holder for the
            extension type when the file_contents are supplied.
        file_contents: The file-like object holding contents of file_name.
            If left as None, then file_name is directly loaded.
        on_demand: Requests that a yielder be used in place of a full data
            copy.

def read(file_name, file_contents=None, on_demand=False):
    '''
    Loads an arbitrary file type (xlsx, xls, or csv like) and returns
    a list of 2D tables. For csv files this will be a list of one table,
    but excel formats can have many tables/worksheets.

    TODO:
        Add wrapper which can be closed/exited on each file type which cleans
        up the file handler.

    Args:
        file_name: The name of the local file, or the holder for the
            extension type when the file_contents are supplied.
        file_contents: The file-like object holding contents of file_name.
            If left as None, then file_name is directly loaded.
        on_demand: Requests that a yielder be used in place of a full data
            copy.
    '''
    try:
        if re.search(XML_EXT_REGEX, file_name):
            return get_data_excel_xml(file_name, file_contents=file_contents, on_demand=on_demand)
        if re.search(XLSX_EXT_REGEX, file_name):
            return get_data_xlsx(file_name, file_contents=file_contents, on_demand=on_demand)
        elif re.search(XLS_EXT_REGEX, file_name):
            return get_data_xls(file_name, file_contents=file_contents, on_demand=on_demand)
        elif re.search(CSV_EXT_REGEX, file_name):
            return get_data_csv(file_name, file_contents=file_contents, on_demand=on_demand)
        else:
            try:
                return get_data_csv(file_name, file_contents=file_contents, on_demand=on_demand)
            except:
                raise ValueError("Unable to load file '{}' as csv".format(file_name))
    except xlrd.XLRDError as e:
        if "<?xml" in str(e):
            return get_data_excel_xml(file_name, file_contents=file_contents, on_demand=on_demand)
        raise