Module refinery.lib.excel.common
Expand source code Browse git
from __future__ import annotations
import datetime
import enum
import functools
import re
import struct
from typing import NamedTuple
from xml.etree.ElementTree import ParseError
from defusedxml import DefusedXmlException
class ExcelFormatError(Exception):
"""
The structure of a workbook is defective; the cells that were read before the defect are
still available to the caller while anything after it is not.
"""
#: What parsing the markup of a package part raises when the part is defective: markup that is
#: not well-formed, and the entity declarations the hardened parser refuses to expand.
XML_DEFECTS = (ParseError, DefusedXmlException)
class CellKind(enum.Enum):
"""
The kind of value a spreadsheet cell holds. A formula cell with a cached result carries the
kind of that result together with the formula source; a formula cell without a cached
result carries `FORMULA` and no value.
"""
TEXT = enum.auto()
NUMBER = enum.auto()
DATE = enum.auto()
BOOLEAN = enum.auto()
ERROR = enum.auto()
BLANK = enum.auto()
FORMULA = enum.auto()
class SheetKind(enum.Enum):
"""
The purpose of a sheet inside a workbook; only worksheets and macrosheets contain cells.
"""
WORKSHEET = enum.auto()
MACROSHEET = enum.auto()
CHART = enum.auto()
MODULE = enum.auto()
OTHER = enum.auto()
#: The value a spreadsheet cell carries; a date cell carries the serial number Excel stores,
#: which only the date mode of its workbook turns into a calendar date.
CellValue = str | int | float | bool | None
FormulaSource = str | bytes | None
class Cell(NamedTuple):
"""
A single spreadsheet cell at a one-based `row` and `col`. The `value` is typed by `kind`;
`formula` is the formula source as stored by the format, without interpretation, and is
`None` for cells that are not formulas. `assignment` marks a formula the container says
assigns a value to a name — the `bx` attribute of an OOXML macrosheet formula, whose text
spells the assignment as a comparison; the formats that store the assignment as the
`SET.NAME` call it already spells leave the flag unset.
"""
row: int
col: int
kind: CellKind
value: CellValue
formula: FormulaSource
assignment: bool = False
class BiffVersion(enum.IntEnum):
"""
The BIFF version of a stream. BIFF7 workbooks parse exactly like BIFF5, so there is no
member for it; BIFF2 workbooks without XF records fall back to the BIFF2.0 rule that
reads the format key from the cell attributes.
"""
BIFF2_1 = 21
BIFF3 = 30
BIFF4 = 40
BIFF4W = 45
BIFF5 = 50
BIFF8 = 80
class DefinedName(NamedTuple):
"""
A defined name of a workbook. The `formula` is the name's formula source as stored by the
format, without interpretation; `sheet` is the zero-based index of the sheet the name is
scoped to, counted in the document order of the format's own sheet table, or `None` when
the name is global.
"""
name: str
formula: FormulaSource
sheet: int | None
def local_name(tag: str) -> str:
"""
Return the part of an XML tag that follows its namespace.
"""
return tag.rsplit('}', 1)[-1]
def ref2rc(ref: str) -> tuple[int, int]:
"""
Convert a cell reference like `B12` into its one-based row and column.
"""
match = re.match(R'^([A-Za-z]+)(\d+)$', ref)
if not match:
raise ValueError
col = functools.reduce(
lambda acc, c: (acc * 26) + c,
(ord(c.upper()) - 0x40 for c in match[1]),
0,
)
row = int(match[2], 10)
if row <= 0:
raise ValueError
return row, col
def column_letters(col: int) -> str:
"""
The A1 letters of a one-based column number, so that `column_letters(1)` is `A`.
"""
letters = ''
while col:
col, letter = divmod(col - 1, 26)
letters = chr(0x41 + letter) + letters
return letters
def rc2ref(row: int, col: int) -> str:
"""
Convert one-based row and column numbers into a cell reference like `B12`.
"""
if row <= 0:
raise ValueError
if col <= 0:
raise ValueError
return F'{column_letters(col)}{row}'
ERROR_TEXT = {
0x00: '#NULL!',
0x07: '#DIV/0!',
0x0F: '#VALUE!',
0x17: '#REF!',
0x1D: '#NAME?',
0x24: '#NUM!',
0x2A: '#N/A',
0x2B: '#GETTING_DATA',
}
_EPOCH_1904 = datetime.datetime(1904, 1, 1)
_EPOCH_1900 = datetime.datetime(1899, 12, 31)
_EPOCH_1900_LEAP = datetime.datetime(1899, 12, 30)
_MARCH_FIRST_1900 = datetime.datetime(1900, 3, 1)
_MILLISECONDS_PER_DAY = 86400000.0
def serial_to_datetime(
serial: int | float,
date_mode_1904: bool,
) -> datetime.datetime | datetime.time:
"""
Convert an Excel serial date number into a datetime, or into a time when the serial number
carries only a fraction of a day. The 1900 epoch accounts for the spurious leap day that
Excel inherited from Lotus 1-2-3: serial 60 is the non-existent date of February 29, 1900,
and serials up to 59 are shifted back by one day.
"""
days, fraction = divmod(float(serial), 1.0)
milliseconds = round(fraction * _MILLISECONDS_PER_DAY)
if 0 <= serial < 1 and milliseconds < _MILLISECONDS_PER_DAY:
return (datetime.datetime.min + datetime.timedelta(milliseconds=milliseconds)).time()
if date_mode_1904:
epoch = _EPOCH_1904
elif 0 < serial < 60:
epoch = _EPOCH_1900
else:
epoch = _EPOCH_1900_LEAP
return epoch + datetime.timedelta(days=days, milliseconds=milliseconds)
def datetime_to_serial(
value: datetime.datetime | datetime.time,
date_mode_1904: bool,
) -> int | float:
"""
Convert a datetime or a time into the Excel serial date number that `serial_to_datetime`
turns back into it. A time names the fraction of a day it covers; a datetime of the 1900
epoch before March 1, 1900 counts from December 31, 1899, so the spurious leap day that
Excel inherited from Lotus 1-2-3 keeps serial 60 out of the round trip: February 29,
1900 does not exist, and the February 28 that serials 59 and 60 both resolve to converts
back to 59 only. A serial number carries no time zone, so a datetime that names one counts
by the wall-clock time it spells.
"""
if isinstance(value, datetime.time):
milliseconds = (value.hour * 60 + value.minute) * 60000 + value.second * 1000
milliseconds += value.microsecond // 1000
serial = milliseconds / _MILLISECONDS_PER_DAY
else:
value = value.replace(tzinfo=None)
if date_mode_1904:
epoch = _EPOCH_1904
elif value < _MARCH_FIRST_1900:
epoch = _EPOCH_1900
else:
epoch = _EPOCH_1900_LEAP
delta = value - epoch
milliseconds = delta.seconds * 1000 + delta.microseconds // 1000
serial = delta.days + milliseconds / _MILLISECONDS_PER_DAY
if isinstance(serial, float) and serial.is_integer():
return int(serial)
return serial
def date_cell(
row: int,
col: int,
serial: int | float,
date_mode_1904: bool,
formula: FormulaSource = None,
assignment: bool = False,
) -> Cell:
"""
Compose the cell of a number whose format marks it as a date. The cell keeps the serial
number Excel stores — the interpretation of the serial is a question of the reader, not of
the workbook — and a serial number that no datetime can represent degrades to the
`#VALUE!` error that Excel displays for it.
"""
try:
serial_to_datetime(serial, date_mode_1904)
except (OverflowError, ValueError):
return Cell(row, col, CellKind.ERROR, ERROR_TEXT[0x0F], formula, assignment)
return Cell(row, col, CellKind.DATE, serial, formula, assignment)
def decode_rk(rk: bytes | bytearray | memoryview) -> float:
"""
Decode the four-byte RK number encoding in which BIFF and XLSB store small numbers: either
a signed 30-bit integer or the top 30 bits of an IEEE 754 double, with the two low bits of
the first byte holding flags that select the type and a division by one hundred.
"""
flags = rk[0] & 0x03
if flags & 0x02:
number = int.from_bytes(rk, 'little', signed=True) >> 2
else:
high = bytes((rk[0] & 0xFC, rk[1], rk[2], rk[3]))
number = struct.unpack('<d', b'\0\0\0\0' + high)[0]
if flags & 0x01:
return number / 100.0
return float(number)
_BUILTIN_DATE_FORMATS = frozenset(
code
for lo, hi in [
(14, 22),
(27, 36),
(45, 47),
(50, 58),
(71, 81),
]
for code in range(lo, hi + 1)
)
_NON_DATE_FORMATS = frozenset([
'0.00E+00',
'##0.0E+0',
'General',
'GENERAL',
'general',
'@',
])
_SKIP_FORMAT_CHARS = frozenset('$-+/(): ')
_DATE_FORMAT_CHARS = frozenset('ymdhsYMDHS')
_NUM_FORMAT_CHARS = frozenset('0#?')
_BRACKETED_FORMAT = re.compile(r'\[[^\]]*\]')
def is_date_format_string(fmt: str) -> bool:
"""
Decide whether a number format string describes a date or time rather than a number.
Quoted and escaped literals are ignored, as are bracketed sections; among what remains,
the count of date letters like `y`, `m`, `d`, `h`, and `s` is weighed against the count
of digit placeholders.
"""
literal = ''
escaped = False
quoted = False
for char in fmt:
if escaped:
escaped = False
elif quoted:
if char == '"':
quoted = False
elif char == '"':
quoted = True
elif char in r'\_*':
escaped = True
elif char not in _SKIP_FORMAT_CHARS:
literal += char
reduced = _BRACKETED_FORMAT.sub('', literal)
if reduced in _NON_DATE_FORMATS:
return False
date_count = 0
num_count = 0
for char in reduced:
if char in _DATE_FORMAT_CHARS:
date_count += 1
elif char in _NUM_FORMAT_CHARS:
num_count += 1
if date_count and not num_count:
return True
if num_count and not date_count:
return False
return date_count > num_count
def is_builtin_date_format(fmt_id: int) -> bool:
"""
Decide whether a built-in number format identifier describes a date or time.
"""
return fmt_id in _BUILTIN_DATE_FORMATS
_XSTRING_ESCAPE = re.compile('_x([0-9A-Fa-f]{4})_')
def decode_xstring(value: str) -> str:
"""
Decode the ST_Xstring escaping in which an OOXML workbook stores control characters that
XML cannot represent, writing them as `_xHHHH_`. The escape of an underscore itself is
`_x005F_`, so a literal `_x000F_` is stored as `_x005F_x000F_` and survives decoding.
"""
return _XSTRING_ESCAPE.sub(lambda m: chr(int(m[1], 16)), value)
Global variables
var XML_DEFECTS-
What parsing the markup of a package part raises when the part is defective: markup that is not well-formed, and the entity declarations the hardened parser refuses to expand.
var CellValue-
The value a spreadsheet cell carries; a date cell carries the serial number Excel stores, which only the date mode of its workbook turns into a calendar date.
Functions
def local_name(tag)-
Return the part of an XML tag that follows its namespace.
Expand source code Browse git
def local_name(tag: str) -> str: """ Return the part of an XML tag that follows its namespace. """ return tag.rsplit('}', 1)[-1] def ref2rc(ref)-
Convert a cell reference like
B12into its one-based row and column.Expand source code Browse git
def ref2rc(ref: str) -> tuple[int, int]: """ Convert a cell reference like `B12` into its one-based row and column. """ match = re.match(R'^([A-Za-z]+)(\d+)$', ref) if not match: raise ValueError col = functools.reduce( lambda acc, c: (acc * 26) + c, (ord(c.upper()) - 0x40 for c in match[1]), 0, ) row = int(match[2], 10) if row <= 0: raise ValueError return row, col def column_letters(col)-
The A1 letters of a one-based column number, so that
column_letters()(1)isA.Expand source code Browse git
def column_letters(col: int) -> str: """ The A1 letters of a one-based column number, so that `column_letters(1)` is `A`. """ letters = '' while col: col, letter = divmod(col - 1, 26) letters = chr(0x41 + letter) + letters return letters def rc2ref(row, col)-
Convert one-based row and column numbers into a cell reference like
B12.Expand source code Browse git
def rc2ref(row: int, col: int) -> str: """ Convert one-based row and column numbers into a cell reference like `B12`. """ if row <= 0: raise ValueError if col <= 0: raise ValueError return F'{column_letters(col)}{row}' def serial_to_datetime(serial, date_mode_1904)-
Convert an Excel serial date number into a datetime, or into a time when the serial number carries only a fraction of a day. The 1900 epoch accounts for the spurious leap day that Excel inherited from Lotus 1-2-3: serial 60 is the non-existent date of February 29, 1900, and serials up to 59 are shifted back by one day.
Expand source code Browse git
def serial_to_datetime( serial: int | float, date_mode_1904: bool, ) -> datetime.datetime | datetime.time: """ Convert an Excel serial date number into a datetime, or into a time when the serial number carries only a fraction of a day. The 1900 epoch accounts for the spurious leap day that Excel inherited from Lotus 1-2-3: serial 60 is the non-existent date of February 29, 1900, and serials up to 59 are shifted back by one day. """ days, fraction = divmod(float(serial), 1.0) milliseconds = round(fraction * _MILLISECONDS_PER_DAY) if 0 <= serial < 1 and milliseconds < _MILLISECONDS_PER_DAY: return (datetime.datetime.min + datetime.timedelta(milliseconds=milliseconds)).time() if date_mode_1904: epoch = _EPOCH_1904 elif 0 < serial < 60: epoch = _EPOCH_1900 else: epoch = _EPOCH_1900_LEAP return epoch + datetime.timedelta(days=days, milliseconds=milliseconds) def datetime_to_serial(value, date_mode_1904)-
Convert a datetime or a time into the Excel serial date number that
serial_to_datetime()turns back into it. A time names the fraction of a day it covers; a datetime of the 1900 epoch before March 1, 1900 counts from December 31, 1899, so the spurious leap day that Excel inherited from Lotus 1-2-3 keeps serial 60 out of the round trip: February 29, 1900 does not exist, and the February 28 that serials 59 and 60 both resolve to converts back to 59 only. A serial number carries no time zone, so a datetime that names one counts by the wall-clock time it spells.Expand source code Browse git
def datetime_to_serial( value: datetime.datetime | datetime.time, date_mode_1904: bool, ) -> int | float: """ Convert a datetime or a time into the Excel serial date number that `serial_to_datetime` turns back into it. A time names the fraction of a day it covers; a datetime of the 1900 epoch before March 1, 1900 counts from December 31, 1899, so the spurious leap day that Excel inherited from Lotus 1-2-3 keeps serial 60 out of the round trip: February 29, 1900 does not exist, and the February 28 that serials 59 and 60 both resolve to converts back to 59 only. A serial number carries no time zone, so a datetime that names one counts by the wall-clock time it spells. """ if isinstance(value, datetime.time): milliseconds = (value.hour * 60 + value.minute) * 60000 + value.second * 1000 milliseconds += value.microsecond // 1000 serial = milliseconds / _MILLISECONDS_PER_DAY else: value = value.replace(tzinfo=None) if date_mode_1904: epoch = _EPOCH_1904 elif value < _MARCH_FIRST_1900: epoch = _EPOCH_1900 else: epoch = _EPOCH_1900_LEAP delta = value - epoch milliseconds = delta.seconds * 1000 + delta.microseconds // 1000 serial = delta.days + milliseconds / _MILLISECONDS_PER_DAY if isinstance(serial, float) and serial.is_integer(): return int(serial) return serial def date_cell(row, col, serial, date_mode_1904, formula=None, assignment=False)-
Compose the cell of a number whose format marks it as a date. The cell keeps the serial number Excel stores — the interpretation of the serial is a question of the reader, not of the workbook — and a serial number that no datetime can represent degrades to the
#VALUE!error that Excel displays for it.Expand source code Browse git
def date_cell( row: int, col: int, serial: int | float, date_mode_1904: bool, formula: FormulaSource = None, assignment: bool = False, ) -> Cell: """ Compose the cell of a number whose format marks it as a date. The cell keeps the serial number Excel stores — the interpretation of the serial is a question of the reader, not of the workbook — and a serial number that no datetime can represent degrades to the `#VALUE!` error that Excel displays for it. """ try: serial_to_datetime(serial, date_mode_1904) except (OverflowError, ValueError): return Cell(row, col, CellKind.ERROR, ERROR_TEXT[0x0F], formula, assignment) return Cell(row, col, CellKind.DATE, serial, formula, assignment) def decode_rk(rk)-
Decode the four-byte RK number encoding in which BIFF and XLSB store small numbers: either a signed 30-bit integer or the top 30 bits of an IEEE 754 double, with the two low bits of the first byte holding flags that select the type and a division by one hundred.
Expand source code Browse git
def decode_rk(rk: bytes | bytearray | memoryview) -> float: """ Decode the four-byte RK number encoding in which BIFF and XLSB store small numbers: either a signed 30-bit integer or the top 30 bits of an IEEE 754 double, with the two low bits of the first byte holding flags that select the type and a division by one hundred. """ flags = rk[0] & 0x03 if flags & 0x02: number = int.from_bytes(rk, 'little', signed=True) >> 2 else: high = bytes((rk[0] & 0xFC, rk[1], rk[2], rk[3])) number = struct.unpack('<d', b'\0\0\0\0' + high)[0] if flags & 0x01: return number / 100.0 return float(number) def is_date_format_string(fmt)-
Decide whether a number format string describes a date or time rather than a number. Quoted and escaped literals are ignored, as are bracketed sections; among what remains, the count of date letters like
y,m,d,h, andsis weighed against the count of digit placeholders.Expand source code Browse git
def is_date_format_string(fmt: str) -> bool: """ Decide whether a number format string describes a date or time rather than a number. Quoted and escaped literals are ignored, as are bracketed sections; among what remains, the count of date letters like `y`, `m`, `d`, `h`, and `s` is weighed against the count of digit placeholders. """ literal = '' escaped = False quoted = False for char in fmt: if escaped: escaped = False elif quoted: if char == '"': quoted = False elif char == '"': quoted = True elif char in r'\_*': escaped = True elif char not in _SKIP_FORMAT_CHARS: literal += char reduced = _BRACKETED_FORMAT.sub('', literal) if reduced in _NON_DATE_FORMATS: return False date_count = 0 num_count = 0 for char in reduced: if char in _DATE_FORMAT_CHARS: date_count += 1 elif char in _NUM_FORMAT_CHARS: num_count += 1 if date_count and not num_count: return True if num_count and not date_count: return False return date_count > num_count def is_builtin_date_format(fmt_id)-
Decide whether a built-in number format identifier describes a date or time.
Expand source code Browse git
def is_builtin_date_format(fmt_id: int) -> bool: """ Decide whether a built-in number format identifier describes a date or time. """ return fmt_id in _BUILTIN_DATE_FORMATS def decode_xstring(value)-
Decode the ST_Xstring escaping in which an OOXML workbook stores control characters that XML cannot represent, writing them as
_xHHHH_. The escape of an underscore itself is_x005F_, so a literal_x000F_is stored as_x005F_x000F_and survives decoding.Expand source code Browse git
def decode_xstring(value: str) -> str: """ Decode the ST_Xstring escaping in which an OOXML workbook stores control characters that XML cannot represent, writing them as `_xHHHH_`. The escape of an underscore itself is `_x005F_`, so a literal `_x000F_` is stored as `_x005F_x000F_` and survives decoding. """ return _XSTRING_ESCAPE.sub(lambda m: chr(int(m[1], 16)), value)
Classes
class ExcelFormatError (*args, **kwargs)-
The structure of a workbook is defective; the cells that were read before the defect are still available to the caller while anything after it is not.
Expand source code Browse git
class ExcelFormatError(Exception): """ The structure of a workbook is defective; the cells that were read before the defect are still available to the caller while anything after it is not. """Ancestors
- builtins.Exception
- builtins.BaseException
class CellKind (*args, **kwds)-
The kind of value a spreadsheet cell holds. A formula cell with a cached result carries the kind of that result together with the formula source; a formula cell without a cached result carries
FORMULAand no value.Expand source code Browse git
class CellKind(enum.Enum): """ The kind of value a spreadsheet cell holds. A formula cell with a cached result carries the kind of that result together with the formula source; a formula cell without a cached result carries `FORMULA` and no value. """ TEXT = enum.auto() NUMBER = enum.auto() DATE = enum.auto() BOOLEAN = enum.auto() ERROR = enum.auto() BLANK = enum.auto() FORMULA = enum.auto()Ancestors
- enum.Enum
Class variables
var TEXT-
The type of the None singleton.
var NUMBER-
The type of the None singleton.
var DATE-
The type of the None singleton.
var BOOLEAN-
The type of the None singleton.
var ERROR-
The type of the None singleton.
var BLANK-
The type of the None singleton.
var FORMULA-
The type of the None singleton.
class SheetKind (*args, **kwds)-
The purpose of a sheet inside a workbook; only worksheets and macrosheets contain cells.
Expand source code Browse git
class SheetKind(enum.Enum): """ The purpose of a sheet inside a workbook; only worksheets and macrosheets contain cells. """ WORKSHEET = enum.auto() MACROSHEET = enum.auto() CHART = enum.auto() MODULE = enum.auto() OTHER = enum.auto()Ancestors
- enum.Enum
Class variables
var WORKSHEET-
The type of the None singleton.
var MACROSHEET-
The type of the None singleton.
var CHART-
The type of the None singleton.
var MODULE-
The type of the None singleton.
var OTHER-
The type of the None singleton.
class Cell (row, col, kind, value, formula, assignment=False)-
A single spreadsheet cell at a one-based
rowandcol. Thevalueis typed bykind;formulais the formula source as stored by the format, without interpretation, and isNonefor cells that are not formulas.assignmentmarks a formula the container says assigns a value to a name — thebxattribute of an OOXML macrosheet formula, whose text spells the assignment as a comparison; the formats that store the assignment as theSET.NAMEcall it already spells leave the flag unset.Expand source code Browse git
class Cell(NamedTuple): """ A single spreadsheet cell at a one-based `row` and `col`. The `value` is typed by `kind`; `formula` is the formula source as stored by the format, without interpretation, and is `None` for cells that are not formulas. `assignment` marks a formula the container says assigns a value to a name — the `bx` attribute of an OOXML macrosheet formula, whose text spells the assignment as a comparison; the formats that store the assignment as the `SET.NAME` call it already spells leave the flag unset. """ row: int col: int kind: CellKind value: CellValue formula: FormulaSource assignment: bool = FalseAncestors
- builtins.tuple
Instance variables
var row-
Alias for field number 0
Expand source code Browse git
class Cell(NamedTuple): """ A single spreadsheet cell at a one-based `row` and `col`. The `value` is typed by `kind`; `formula` is the formula source as stored by the format, without interpretation, and is `None` for cells that are not formulas. `assignment` marks a formula the container says assigns a value to a name — the `bx` attribute of an OOXML macrosheet formula, whose text spells the assignment as a comparison; the formats that store the assignment as the `SET.NAME` call it already spells leave the flag unset. """ row: int col: int kind: CellKind value: CellValue formula: FormulaSource assignment: bool = False var col-
Alias for field number 1
Expand source code Browse git
class Cell(NamedTuple): """ A single spreadsheet cell at a one-based `row` and `col`. The `value` is typed by `kind`; `formula` is the formula source as stored by the format, without interpretation, and is `None` for cells that are not formulas. `assignment` marks a formula the container says assigns a value to a name — the `bx` attribute of an OOXML macrosheet formula, whose text spells the assignment as a comparison; the formats that store the assignment as the `SET.NAME` call it already spells leave the flag unset. """ row: int col: int kind: CellKind value: CellValue formula: FormulaSource assignment: bool = False var kind-
Alias for field number 2
Expand source code Browse git
class Cell(NamedTuple): """ A single spreadsheet cell at a one-based `row` and `col`. The `value` is typed by `kind`; `formula` is the formula source as stored by the format, without interpretation, and is `None` for cells that are not formulas. `assignment` marks a formula the container says assigns a value to a name — the `bx` attribute of an OOXML macrosheet formula, whose text spells the assignment as a comparison; the formats that store the assignment as the `SET.NAME` call it already spells leave the flag unset. """ row: int col: int kind: CellKind value: CellValue formula: FormulaSource assignment: bool = False var value-
Alias for field number 3
Expand source code Browse git
class Cell(NamedTuple): """ A single spreadsheet cell at a one-based `row` and `col`. The `value` is typed by `kind`; `formula` is the formula source as stored by the format, without interpretation, and is `None` for cells that are not formulas. `assignment` marks a formula the container says assigns a value to a name — the `bx` attribute of an OOXML macrosheet formula, whose text spells the assignment as a comparison; the formats that store the assignment as the `SET.NAME` call it already spells leave the flag unset. """ row: int col: int kind: CellKind value: CellValue formula: FormulaSource assignment: bool = False var formula-
Alias for field number 4
Expand source code Browse git
class Cell(NamedTuple): """ A single spreadsheet cell at a one-based `row` and `col`. The `value` is typed by `kind`; `formula` is the formula source as stored by the format, without interpretation, and is `None` for cells that are not formulas. `assignment` marks a formula the container says assigns a value to a name — the `bx` attribute of an OOXML macrosheet formula, whose text spells the assignment as a comparison; the formats that store the assignment as the `SET.NAME` call it already spells leave the flag unset. """ row: int col: int kind: CellKind value: CellValue formula: FormulaSource assignment: bool = False var assignment-
Alias for field number 5
Expand source code Browse git
class Cell(NamedTuple): """ A single spreadsheet cell at a one-based `row` and `col`. The `value` is typed by `kind`; `formula` is the formula source as stored by the format, without interpretation, and is `None` for cells that are not formulas. `assignment` marks a formula the container says assigns a value to a name — the `bx` attribute of an OOXML macrosheet formula, whose text spells the assignment as a comparison; the formats that store the assignment as the `SET.NAME` call it already spells leave the flag unset. """ row: int col: int kind: CellKind value: CellValue formula: FormulaSource assignment: bool = False
class BiffVersion (*args, **kwds)-
The BIFF version of a stream. BIFF7 workbooks parse exactly like BIFF5, so there is no member for it; BIFF2 workbooks without XF records fall back to the BIFF2.0 rule that reads the format key from the cell attributes.
Expand source code Browse git
class BiffVersion(enum.IntEnum): """ The BIFF version of a stream. BIFF7 workbooks parse exactly like BIFF5, so there is no member for it; BIFF2 workbooks without XF records fall back to the BIFF2.0 rule that reads the format key from the cell attributes. """ BIFF2_1 = 21 BIFF3 = 30 BIFF4 = 40 BIFF4W = 45 BIFF5 = 50 BIFF8 = 80Ancestors
- enum.IntEnum
- builtins.int
- enum.ReprEnum
- enum.Enum
Class variables
var BIFF2_1-
The type of the None singleton.
var BIFF3-
The type of the None singleton.
var BIFF4-
The type of the None singleton.
var BIFF4W-
The type of the None singleton.
var BIFF5-
The type of the None singleton.
var BIFF8-
The type of the None singleton.
class DefinedName (name, formula, sheet)-
A defined name of a workbook. The
formulais the name's formula source as stored by the format, without interpretation;sheetis the zero-based index of the sheet the name is scoped to, counted in the document order of the format's own sheet table, orNonewhen the name is global.Expand source code Browse git
class DefinedName(NamedTuple): """ A defined name of a workbook. The `formula` is the name's formula source as stored by the format, without interpretation; `sheet` is the zero-based index of the sheet the name is scoped to, counted in the document order of the format's own sheet table, or `None` when the name is global. """ name: str formula: FormulaSource sheet: int | NoneAncestors
- builtins.tuple
Instance variables
var name-
Alias for field number 0
Expand source code Browse git
class DefinedName(NamedTuple): """ A defined name of a workbook. The `formula` is the name's formula source as stored by the format, without interpretation; `sheet` is the zero-based index of the sheet the name is scoped to, counted in the document order of the format's own sheet table, or `None` when the name is global. """ name: str formula: FormulaSource sheet: int | None var formula-
Alias for field number 1
Expand source code Browse git
class DefinedName(NamedTuple): """ A defined name of a workbook. The `formula` is the name's formula source as stored by the format, without interpretation; `sheet` is the zero-based index of the sheet the name is scoped to, counted in the document order of the format's own sheet table, or `None` when the name is global. """ name: str formula: FormulaSource sheet: int | None var sheet-
Alias for field number 2
Expand source code Browse git
class DefinedName(NamedTuple): """ A defined name of a workbook. The `formula` is the name's formula source as stored by the format, without interpretation; `sheet` is the zero-based index of the sheet the name is scoped to, counted in the document order of the format's own sheet table, or `None` when the name is global. """ name: str formula: FormulaSource sheet: int | None