We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Support xls and xlsx
## Problem
Mathesar does not support excel files (xls or xlsx). Please see this file: 

https://github.com/centerofci/mathesar/blob/0d99ee984206a99c6743a319504a1d86621d71d5/mathesar/imports/base.py#L13

## Proposed solution
Mathesar should support both xls and xlsx files. This should be simple to do with the xlrd (for xls) and openpyxl (for xlsx) libraries and the implementation would be similar to csv.

## Additional context
It is important to keep in mind that non-technical users can't really use csv but are comfortable with xls and xlsx. Implementing this feature would make mathesar much more friendly for these users.

I see that there's an issue about xlsx files: #2742 however it seems to be closed ? If you want and nobody else is working on that I can try providing a PR implementing the xls and xlsx features.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `mathesar/imports/excel.py`
Content:
```
1 import pandas
2 
3 from db.tables.operations.alter import update_pk_sequence_to_latest
4 from mathesar.database.base import create_mathesar_engine
5 from db.records.operations.insert import insert_records_from_excel
6 from db.tables.operations.create import create_string_column_table
7 from db.tables.operations.drop import drop_table
8 from mathesar.imports.utils import get_alternate_column_names, process_column_names
9 from psycopg2.errors import IntegrityError, DataError
10 
11 from mathesar.state import reset_reflection
12 
13 
14 def insert_records_from_dataframe(name, schema, column_names, engine, comment, dataframe):
15     table = create_string_column_table(
16         name=name,
17         schema_oid=schema.oid,
18         column_names=column_names,
19         engine=engine,
20         comment=comment,
21     )
22 
23     insert_records_from_excel(
24         table,
25         engine,
26         dataframe,
27     )
28     return table
29 
30 
31 def create_db_table_from_excel_data_file(data_file, name, schema, comment=None):
32     db_name = schema.database.name
33     engine = create_mathesar_engine(db_name)
34     dataframe = pandas.read_excel(data_file.file.path)
35     column_names = process_column_names(dataframe.columns)
36     try:
37         table = insert_records_from_dataframe(name, schema, column_names, engine, comment, dataframe)
38         update_pk_sequence_to_latest(engine, table)
39     except (IntegrityError, DataError):
40         drop_table(name=name, schema=schema.name, engine=engine)
41         column_names_alt = get_alternate_column_names(column_names)
42         table = insert_records_from_dataframe(name, schema, column_names_alt, engine, comment, dataframe)
43 
44     reset_reflection(db_name=db_name)
45     return table
46
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/mathesar/imports/excel.py b/mathesar/imports/excel.py
--- a/mathesar/imports/excel.py
+++ b/mathesar/imports/excel.py
@@ -28,10 +28,28 @@
     return table
 
 
+def remove_empty_rows_and_columns_from_dataframe(df):
+    if df.iloc[0].isna().any():
+
+        # drop rows with all NaN values
+        df.dropna(how='all', inplace=True)
+
+        # drop columns with all NaN values
+        df.dropna(axis=1, how='all', inplace=True)
+
+    if all(df.columns.str.startswith('Unnamed')):
+        df.columns = df.iloc[0]
+        df = df[1:]
+
+    return df
+
+
 def create_db_table_from_excel_data_file(data_file, name, schema, comment=None):
     db_name = schema.database.name
     engine = create_mathesar_engine(db_name)
-    dataframe = pandas.read_excel(data_file.file.path)
+    dataframe = remove_empty_rows_and_columns_from_dataframe(
+        pandas.read_excel(data_file.file.path)
+    )
     column_names = process_column_names(dataframe.columns)
     try:
         table = insert_records_from_dataframe(name, schema, column_names, engine, comment, dataframe)

{"golden_diff": "diff --git a/mathesar/imports/excel.py b/mathesar/imports/excel.py\n--- a/mathesar/imports/excel.py\n+++ b/mathesar/imports/excel.py\n@@ -28,10 +28,28 @@\n     return table\n \n \n+def remove_empty_rows_and_columns_from_dataframe(df):\n+    if df.iloc[0].isna().any():\n+\n+        # drop rows with all NaN values\n+        df.dropna(how='all', inplace=True)\n+\n+        # drop columns with all NaN values\n+        df.dropna(axis=1, how='all', inplace=True)\n+\n+    if all(df.columns.str.startswith('Unnamed')):\n+        df.columns = df.iloc[0]\n+        df = df[1:]\n+\n+    return df\n+\n+\n def create_db_table_from_excel_data_file(data_file, name, schema, comment=None):\n     db_name = schema.database.name\n     engine = create_mathesar_engine(db_name)\n-    dataframe = pandas.read_excel(data_file.file.path)\n+    dataframe = remove_empty_rows_and_columns_from_dataframe(\n+        pandas.read_excel(data_file.file.path)\n+    )\n     column_names = process_column_names(dataframe.columns)\n     try:\n         table = insert_records_from_dataframe(name, schema, column_names, engine, comment, dataframe)\n", "issue": "Support xls and xlsx\n## Problem\r\nMathesar does not support excel files (xls or xlsx). Please see this file: \r\n\r\nhttps://github.com/centerofci/mathesar/blob/0d99ee984206a99c6743a319504a1d86621d71d5/mathesar/imports/base.py#L13\r\n\r\n## Proposed solution\r\nMathesar should support both xls and xlsx files. This should be simple to do with the xlrd (for xls) and openpyxl (for xlsx) libraries and the implementation would be similar to csv.\r\n\r\n## Additional context\r\nIt is important to keep in mind that non-technical users can't really use csv but are comfortable with xls and xlsx. Implementing this feature would make mathesar much more friendly for these users.\r\n\r\nI see that there's an issue about xlsx files: #2742 however it seems to be closed ? If you want and nobody else is working on that I can try providing a PR implementing the xls and xlsx features.\r\n\n", "before_files": [{"content": "import pandas\n\nfrom db.tables.operations.alter import update_pk_sequence_to_latest\nfrom mathesar.database.base import create_mathesar_engine\nfrom db.records.operations.insert import insert_records_from_excel\nfrom db.tables.operations.create import create_string_column_table\nfrom db.tables.operations.drop import drop_table\nfrom mathesar.imports.utils import get_alternate_column_names, process_column_names\nfrom psycopg2.errors import IntegrityError, DataError\n\nfrom mathesar.state import reset_reflection\n\n\ndef insert_records_from_dataframe(name, schema, column_names, engine, comment, dataframe):\n    table = create_string_column_table(\n        name=name,\n        schema_oid=schema.oid,\n        column_names=column_names,\n        engine=engine,\n        comment=comment,\n    )\n\n    insert_records_from_excel(\n        table,\n        engine,\n        dataframe,\n    )\n    return table\n\n\ndef create_db_table_from_excel_data_file(data_file, name, schema, comment=None):\n    db_name = schema.database.name\n    engine = create_mathesar_engine(db_name)\n    dataframe = pandas.read_excel(data_file.file.path)\n    column_names = process_column_names(dataframe.columns)\n    try:\n        table = insert_records_from_dataframe(name, schema, column_names, engine, comment, dataframe)\n        update_pk_sequence_to_latest(engine, table)\n    except (IntegrityError, DataError):\n        drop_table(name=name, schema=schema.name, engine=engine)\n        column_names_alt = get_alternate_column_names(column_names)\n        table = insert_records_from_dataframe(name, schema, column_names_alt, engine, comment, dataframe)\n\n    reset_reflection(db_name=db_name)\n    return table\n", "path": "mathesar/imports/excel.py"}], "after_files": [{"content": "import pandas\n\nfrom db.tables.operations.alter import update_pk_sequence_to_latest\nfrom mathesar.database.base import create_mathesar_engine\nfrom db.records.operations.insert import insert_records_from_excel\nfrom db.tables.operations.create import create_string_column_table\nfrom db.tables.operations.drop import drop_table\nfrom mathesar.imports.utils import get_alternate_column_names, process_column_names\nfrom psycopg2.errors import IntegrityError, DataError\n\nfrom mathesar.state import reset_reflection\n\n\ndef insert_records_from_dataframe(name, schema, column_names, engine, comment, dataframe):\n    table = create_string_column_table(\n        name=name,\n        schema_oid=schema.oid,\n        column_names=column_names,\n        engine=engine,\n        comment=comment,\n    )\n\n    insert_records_from_excel(\n        table,\n        engine,\n        dataframe,\n    )\n    return table\n\n\ndef remove_empty_rows_and_columns_from_dataframe(df):\n    if df.iloc[0].isna().any():\n\n        # drop rows with all NaN values\n        df.dropna(how='all', inplace=True)\n\n        # drop columns with all NaN values\n        df.dropna(axis=1, how='all', inplace=True)\n\n    if all(df.columns.str.startswith('Unnamed')):\n        df.columns = df.iloc[0]\n        df = df[1:]\n\n    return df\n\n\ndef create_db_table_from_excel_data_file(data_file, name, schema, comment=None):\n    db_name = schema.database.name\n    engine = create_mathesar_engine(db_name)\n    dataframe = remove_empty_rows_and_columns_from_dataframe(\n        pandas.read_excel(data_file.file.path)\n    )\n    column_names = process_column_names(dataframe.columns)\n    try:\n        table = insert_records_from_dataframe(name, schema, column_names, engine, comment, dataframe)\n        update_pk_sequence_to_latest(engine, table)\n    except (IntegrityError, DataError):\n        drop_table(name=name, schema=schema.name, engine=engine)\n        column_names_alt = get_alternate_column_names(column_names)\n        table = insert_records_from_dataframe(name, schema, column_names_alt, engine, comment, dataframe)\n\n    reset_reflection(db_name=db_name)\n    return table\n", "path": "mathesar/imports/excel.py"}]}