prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <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.
  
  
  </issue>
  <code>
  [start of mathesar/imports/excel.py]
  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 of mathesar/imports/excel.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: 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)
  
verification_info: {"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"}]}