Return a rows.Table created from imported XLSX file.

    workbook_kwargs will be passed to openpyxl.load_workbook

def import_from_xlsx(
    filename_or_fobj,
    sheet_name=None,
    sheet_index=0,
    start_row=None,
    start_column=None,
    end_row=None,
    end_column=None,
    workbook_kwargs=None,
    *args,
    **kwargs
):
    """Return a rows.Table created from imported XLSX file.

    workbook_kwargs will be passed to openpyxl.load_workbook
    """

    workbook_kwargs = workbook_kwargs or {}
    if "read_only" not in workbook_kwargs:
        workbook_kwargs["read_only"] = True

    workbook = load_workbook(filename_or_fobj, **workbook_kwargs)
    if sheet_name is None:
        sheet_name = workbook.sheetnames[sheet_index]
    sheet = workbook[sheet_name]

    # The openpyxl library reads rows and columns starting from 1 and ending on
    # sheet.max_row/max_col. rows uses 0-based indexes (from 0 to N - 1), so we
    # need to adjust the ranges accordingly.
    min_row, min_column = sheet.min_row - 1, sheet.min_column - 1
    max_row, max_column = sheet.max_row - 1, sheet.max_column - 1
    # TODO: consider adding a parameter `ignore_padding=True` and when it's
    # True, consider `start_row` starting from `sheet.min_row` and
    # `start_column` starting from `sheet.min_col`.
    start_row = start_row if start_row is not None else min_row
    end_row = end_row if end_row is not None else max_row
    start_column = start_column if start_column is not None else min_column
    end_column = end_column if end_column is not None else max_column
    table_rows = []
    is_empty = lambda row: all(cell is None for cell in row)
    selected_rows = sheet.iter_rows(
        min_row=start_row + 1,
        max_row=end_row + 1,
        min_col=start_column + 1,
        max_col=end_column + 1,
    )
    for row in selected_rows:
        row = [_cell_to_python(cell) for cell in row]
        if not is_empty(row):
            table_rows.append(row)

    source = Source.from_file(filename_or_fobj, plugin_name="xlsx")
    source.fobj.close()
    # TODO: pass a parameter to Source.from_file so it won't open the file
    metadata = {"imported_from": "xlsx", "source": source, "name": sheet_name}
    return create_table(table_rows, meta=metadata, *args, **kwargs)