Repository: modin-project/modin

Issue:
read_excel error: KeyError: "There is no item named 'xl/worksheets/sheet1.xml' in the archive"
Due to some changes at some point in time, it is possible to have a valid excel spreadsheet with some of the sheet xml files being partially capitalized. We should give a better error in the cases we can't find the excel sheets and we should do some further searching for the sheet with various capitalization.


Discussion:

Resolving patch:
diff --git a/modin/backends/pandas/parsers.py b/modin/backends/pandas/parsers.py
--- a/modin/backends/pandas/parsers.py
+++ b/modin/backends/pandas/parsers.py
@@ -221,7 +221,7 @@ def parse(fname, **kwargs):
         ws = Worksheet(wb)
         # Read the raw data
         with ZipFile(fname) as z:
-            with z.open("xl/worksheets/{}.xml".format(sheet_name.lower())) as file:
+            with z.open("xl/worksheets/{}.xml".format(sheet_name)) as file:
                 file.seek(start)
                 bytes_data = file.read(end - start)
 
diff --git a/modin/engines/base/io/text/excel_reader.py b/modin/engines/base/io/text/excel_reader.py
--- a/modin/engines/base/io/text/excel_reader.py
+++ b/modin/engines/base/io/text/excel_reader.py
@@ -65,18 +65,25 @@ def _read(cls, io, **kwargs):
         ex.read_manifest()
         ex.read_strings()
         ws = Worksheet(wb)
-        # Convert index to sheet name in file
-        if isinstance(sheet_name, int):
-            sheet_name = "sheet{}".format(sheet_name + 1)
-        else:
-            sheet_name = "sheet{}".format(wb.sheetnames.index(sheet_name) + 1)
-        # Pass this value to the workers
-        kwargs["sheet_name"] = sheet_name
 
         with ZipFile(io) as z:
             from io import BytesIO
 
-            f = z.open("xl/worksheets/{}.xml".format(sheet_name.lower()))
+            # Convert index to sheet name in file
+            if isinstance(sheet_name, int):
+                sheet_name = "sheet{}".format(sheet_name + 1)
+            else:
+                sheet_name = "sheet{}".format(wb.sheetnames.index(sheet_name) + 1)
+            if any(sheet_name.lower() in name for name in z.namelist()):
+                sheet_name = sheet_name.lower()
+            elif any(sheet_name.title() in name for name in z.namelist()):
+                sheet_name = sheet_name.title()
+            else:
+                raise ValueError("Sheet {} not found".format(sheet_name.lower()))
+            # Pass this value to the workers
+            kwargs["sheet_name"] = sheet_name
+
+            f = z.open("xl/worksheets/{}.xml".format(sheet_name))
             f = BytesIO(f.read())
             total_bytes = cls.file_size(f)
 


Test patch:
diff --git a/modin/pandas/test/data/excel_sheetname_title.xlsx b/modin/pandas/test/data/excel_sheetname_title.xlsx
new file mode 100644
Binary files /dev/null and b/modin/pandas/test/data/excel_sheetname_title.xlsx differ
diff --git a/modin/pandas/test/test_io.py b/modin/pandas/test/test_io.py
--- a/modin/pandas/test/test_io.py
+++ b/modin/pandas/test/test_io.py
@@ -888,6 +888,13 @@ def test_from_excel_all_sheets():
     teardown_excel_file()
 
 
+def test_from_excel_sheetname_title():
+    path = "modin/pandas/test/data/excel_sheetname_title.xlsx"
+    modin_df = pd.read_excel(path)
+    pandas_df = pandas.read_excel(path)
+    df_equals(modin_df, pandas_df)
+
+
 @pytest.mark.parametrize(
     "sheet_name",
     ["Sheet1", "AnotherSpecialName", "SpecialName", "SecondSpecialName", 0, 1, 2, 3],