async def ingest(
        self, data: bytes, *args, **kwargs
    ) -> AsyncGenerator[str, None]:
        """Ingest XLS data and yield text from each row."""
        if isinstance(data, str):
            raise ValueError("XLS data must be in bytes format.")

        wb = self.xlrd.open_workbook(file_contents=data)
        for sheet in wb.sheets():
            for row_idx in range(sheet.nrows):
                # Get all values in the row
                row_values = []
                for col_idx in range(sheet.ncols):
                    cell = sheet.cell(row_idx, col_idx)
                    # Handle different cell types
                    if cell.ctype == self.xlrd.XL_CELL_DATE:
                        try:
                            value = self.xlrd.xldate_as_datetime(
                                cell.value, wb.datemode
                            ).strftime("%Y-%m-%d")
                        except Exception:
                            value = str(cell.value)
                    elif cell.ctype == self.xlrd.XL_CELL_BOOLEAN:
                        value = str(bool(cell.value)).lower()
                    elif cell.ctype == self.xlrd.XL_CELL_ERROR:
                        value = "#ERROR#"
                    else:
                        value = str(cell.value).strip()

                    row_values.append(value)

                # Yield non-empty rows
                if any(val.strip() for val in row_values):
                    yield ", ".join(row_values)
Ingest XLS data and yield text from each row.
py/core/parsers/structured/xls_parser.py