123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244 |
- from struct import unpack, pack
- from . import BIFFRecords
- from .compat import xrange
- class StrCell(object):
- __slots__ = ["rowx", "colx", "xf_idx", "sst_idx"]
- def __init__(self, rowx, colx, xf_idx, sst_idx):
- self.rowx = rowx
- self.colx = colx
- self.xf_idx = xf_idx
- self.sst_idx = sst_idx
- def get_biff_data(self):
-
- return pack('<5HL', 0x00FD, 10, self.rowx, self.colx, self.xf_idx, self.sst_idx)
- class BlankCell(object):
- __slots__ = ["rowx", "colx", "xf_idx"]
- def __init__(self, rowx, colx, xf_idx):
- self.rowx = rowx
- self.colx = colx
- self.xf_idx = xf_idx
- def get_biff_data(self):
-
- return pack('<5H', 0x0201, 6, self.rowx, self.colx, self.xf_idx)
- class MulBlankCell(object):
- __slots__ = ["rowx", "colx1", "colx2", "xf_idx"]
- def __init__(self, rowx, colx1, colx2, xf_idx):
- self.rowx = rowx
- self.colx1 = colx1
- self.colx2 = colx2
- self.xf_idx = xf_idx
- def get_biff_data(self):
- return BIFFRecords.MulBlankRecord(self.rowx,
- self.colx1, self.colx2, self.xf_idx).get()
- class NumberCell(object):
- __slots__ = ["rowx", "colx", "xf_idx", "number"]
- def __init__(self, rowx, colx, xf_idx, number):
- self.rowx = rowx
- self.colx = colx
- self.xf_idx = xf_idx
- self.number = float(number)
- def get_encoded_data(self):
- rk_encoded = 0
- num = self.number
-
-
-
-
-
- if -0x20000000 <= num < 0x20000000:
- inum = int(num)
- if inum == num:
-
- rk_encoded = 2 | (inum << 2)
- return 1, rk_encoded
- temp = num * 100
- if -0x20000000 <= temp < 0x20000000:
-
-
- itemp = int(round(temp, 0))
-
-
-
- if itemp / 100.0 == num:
-
- rk_encoded = 3 | (itemp << 2)
- return 1, rk_encoded
- if 0:
- packed = pack('<d', num)
- w01, w23 = unpack('<2i', packed)
- if not w01 and not(w23 & 3):
-
-
- return 1, w23
- packed100 = pack('<d', temp)
- w01, w23 = unpack('<2i', packed100)
- if not w01 and not(w23 & 3):
-
-
- return 1, w23 | 1
-
-
- return 0, pack('<5Hd', 0x0203, 14, self.rowx, self.colx, self.xf_idx, num)
- def get_biff_data(self):
- isRK, value = self.get_encoded_data()
- if isRK:
- return pack('<5Hi', 0x27E, 10, self.rowx, self.colx, self.xf_idx, value)
- return value
- class BooleanCell(object):
- __slots__ = ["rowx", "colx", "xf_idx", "number"]
- def __init__(self, rowx, colx, xf_idx, number):
- self.rowx = rowx
- self.colx = colx
- self.xf_idx = xf_idx
- self.number = number
- def get_biff_data(self):
- return BIFFRecords.BoolErrRecord(self.rowx,
- self.colx, self.xf_idx, self.number, 0).get()
- error_code_map = {
- 0x00: 0,
- 0x07: 7,
- 0x0F: 15,
- 0x17: 23,
- 0x1D: 29,
- 0x24: 36,
- 0x2A: 42,
- '#NULL!' : 0,
- '#DIV/0!': 7,
- '#VALUE!': 36,
- '#REF!' : 23,
- '#NAME?' : 29,
- '#NUM!' : 36,
- '#N/A!' : 42,
- }
- class ErrorCell(object):
- __slots__ = ["rowx", "colx", "xf_idx", "number"]
- def __init__(self, rowx, colx, xf_idx, error_string_or_code):
- self.rowx = rowx
- self.colx = colx
- self.xf_idx = xf_idx
- try:
- self.number = error_code_map[error_string_or_code]
- except KeyError:
- raise Exception('Illegal error value (%r)' % error_string_or_code)
- def get_biff_data(self):
- return BIFFRecords.BoolErrRecord(self.rowx,
- self.colx, self.xf_idx, self.number, 1).get()
- class FormulaCell(object):
- __slots__ = ["rowx", "colx", "xf_idx", "frmla", "calc_flags"]
- def __init__(self, rowx, colx, xf_idx, frmla, calc_flags=0):
- self.rowx = rowx
- self.colx = colx
- self.xf_idx = xf_idx
- self.frmla = frmla
- self.calc_flags = calc_flags
- def get_biff_data(self):
- return BIFFRecords.FormulaRecord(self.rowx,
- self.colx, self.xf_idx, self.frmla.rpn(), self.calc_flags).get()
- def _get_cells_biff_data_mul(rowx, cell_items):
-
-
- pieces = []
- nitems = len(cell_items)
- i = 0
- while i < nitems:
- icolx, icell = cell_items[i]
- if isinstance(icell, NumberCell):
- isRK, value = icell.get_encoded_data()
- if not isRK:
- pieces.append(value)
- i += 1
- continue
- muldata = [(value, icell.xf_idx)]
- target = NumberCell
- elif isinstance(icell, BlankCell):
- muldata = [icell.xf_idx]
- target = BlankCell
- else:
- pieces.append(icell.get_biff_data())
- i += 1
- continue
- lastcolx = icolx
- j = i
- packed_record = ''
- for j in xrange(i+1, nitems):
- jcolx, jcell = cell_items[j]
- if jcolx != lastcolx + 1:
- nexti = j
- break
- if not isinstance(jcell, target):
- nexti = j
- break
- if target == NumberCell:
- isRK, value = jcell.get_encoded_data()
- if not isRK:
- packed_record = value
- nexti = j + 1
- break
- muldata.append((value, jcell.xf_idx))
- else:
- muldata.append(jcell.xf_idx)
- lastcolx = jcolx
- else:
- nexti = j + 1
- if target == NumberCell:
- if lastcolx == icolx:
-
- value, xf_idx = muldata[0]
- pieces.append(pack('<5Hi', 0x027E, 10, rowx, icolx, xf_idx, value))
- else:
-
- nc = lastcolx - icolx + 1
- pieces.append(pack('<4H', 0x00BD, 6 * nc + 6, rowx, icolx))
- pieces.append(b''.join(pack('<Hi', xf_idx, value) for value, xf_idx in muldata))
- pieces.append(pack('<H', lastcolx))
- else:
- if lastcolx == icolx:
-
- xf_idx = muldata[0]
- pieces.append(pack('<5H', 0x0201, 6, rowx, icolx, xf_idx))
- else:
-
- nc = lastcolx - icolx + 1
- pieces.append(pack('<4H', 0x00BE, 2 * nc + 6, rowx, icolx))
- pieces.append(b''.join(pack('<H', xf_idx) for xf_idx in muldata))
- pieces.append(pack('<H', lastcolx))
- if packed_record:
- pieces.append(packed_record)
- i = nexti
- return b''.join(pieces)
|