mirror of
https://github.com/PiBrewing/craftbeerpi4.git
synced 2024-11-27 01:08:12 +01:00
69 lines
2.3 KiB
Python
69 lines
2.3 KiB
Python
from typing import List
|
|
|
|
from pandas._typing import FilePathOrBuffer, Scalar
|
|
from pandas.compat._optional import import_optional_dependency
|
|
|
|
from pandas.io.excel._base import _BaseExcelReader
|
|
|
|
|
|
class _PyxlsbReader(_BaseExcelReader):
|
|
def __init__(self, filepath_or_buffer: FilePathOrBuffer):
|
|
"""
|
|
Reader using pyxlsb engine.
|
|
|
|
Parameters
|
|
----------
|
|
filepath_or_buffer: str, path object, or Workbook
|
|
Object to be parsed.
|
|
"""
|
|
import_optional_dependency("pyxlsb")
|
|
# This will call load_workbook on the filepath or buffer
|
|
# And set the result to the book-attribute
|
|
super().__init__(filepath_or_buffer)
|
|
|
|
@property
|
|
def _workbook_class(self):
|
|
from pyxlsb import Workbook
|
|
|
|
return Workbook
|
|
|
|
def load_workbook(self, filepath_or_buffer: FilePathOrBuffer):
|
|
from pyxlsb import open_workbook
|
|
|
|
# TODO: hack in buffer capability
|
|
# This might need some modifications to the Pyxlsb library
|
|
# Actual work for opening it is in xlsbpackage.py, line 20-ish
|
|
|
|
return open_workbook(filepath_or_buffer)
|
|
|
|
@property
|
|
def sheet_names(self) -> List[str]:
|
|
return self.book.sheets
|
|
|
|
def get_sheet_by_name(self, name: str):
|
|
return self.book.get_sheet(name)
|
|
|
|
def get_sheet_by_index(self, index: int):
|
|
# pyxlsb sheets are indexed from 1 onwards
|
|
# There's a fix for this in the source, but the pypi package doesn't have it
|
|
return self.book.get_sheet(index + 1)
|
|
|
|
def _convert_cell(self, cell, convert_float: bool) -> Scalar:
|
|
# TODO: there is no way to distinguish between floats and datetimes in pyxlsb
|
|
# This means that there is no way to read datetime types from an xlsb file yet
|
|
if cell.v is None:
|
|
return "" # Prevents non-named columns from not showing up as Unnamed: i
|
|
if isinstance(cell.v, float) and convert_float:
|
|
val = int(cell.v)
|
|
if val == cell.v:
|
|
return val
|
|
else:
|
|
return float(cell.v)
|
|
|
|
return cell.v
|
|
|
|
def get_sheet_data(self, sheet, convert_float: bool) -> List[List[Scalar]]:
|
|
return [
|
|
[self._convert_cell(c, convert_float) for c in r]
|
|
for r in sheet.rows(sparse=False)
|
|
]
|