summaryrefslogtreecommitdiff
path: root/tablib/packages/xlwt3/Cell.py
diff options
context:
space:
mode:
authorKenneth Reitz <me@kennethreitz.com>2011-03-23 01:47:01 -0400
committerKenneth Reitz <me@kennethreitz.com>2011-03-23 01:47:01 -0400
commit0e56db632ad18d169a2e935b5e9aaa97f9c3b71b (patch)
tree3cdf51e4f1e48bb42934c377665c0997afbf331b /tablib/packages/xlwt3/Cell.py
parentb07512071e2e4d81a4334c9cdad24220694731b5 (diff)
downloadtablib-0e56db632ad18d169a2e935b5e9aaa97f9c3b71b.tar.gz
xlwt3 package
Diffstat (limited to 'tablib/packages/xlwt3/Cell.py')
-rw-r--r--tablib/packages/xlwt3/Cell.py233
1 files changed, 233 insertions, 0 deletions
diff --git a/tablib/packages/xlwt3/Cell.py b/tablib/packages/xlwt3/Cell.py
new file mode 100644
index 0000000..08a9e42
--- /dev/null
+++ b/tablib/packages/xlwt3/Cell.py
@@ -0,0 +1,233 @@
+from struct import unpack, pack
+from . import BIFFRecords
+
+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
+
+ # The four possible kinds of RK encoding are *not* mutually exclusive.
+ # The 30-bit integer variety picks up the most.
+ # In the code below, the four varieties are checked in descending order
+ # of bangs per buck, or not at all.
+ # SJM 2007-10-01
+
+ if -0x20000000 <= num < 0x20000000: # fits in 30-bit *signed* int
+ inum = int(num)
+ if inum == num: # survives round-trip
+ rk_encoded = 2 | (inum << 2)
+ return 1, rk_encoded
+
+ temp = num * 100
+
+ if -0x20000000 <= temp < 0x20000000:
+ # That was step 1: the coded value will fit in
+ # a 30-bit signed integer.
+ itemp = int(round(temp, 0))
+ # That was step 2: "itemp" is the best candidate coded value.
+ # Now for step 3: simulate the decoding,
+ # to check for round-trip correctness.
+ if itemp / 100.0 == num:
+ rk_encoded = 3 | (itemp << 2)
+ return 1, rk_encoded
+
+ if 0: # Cost of extra pack+unpack not justified by tiny yield.
+ 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 # NUMBER record already packed
+
+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, # Intersection of two cell ranges is empty
+ 0x07: 7, # Division by zero
+ 0x0F: 15, # Wrong type of operand
+ 0x17: 23, # Illegal or deleted cell reference
+ 0x1D: 29, # Wrong function or range name
+ 0x24: 36, # Value range overflow
+ 0x2A: 42, # Argument or function not available
+ '#NULL!' : 0, # Intersection of two cell ranges is empty
+ '#DIV/0!': 7, # Division by zero
+ '#VALUE!': 36, # Wrong type of operand
+ '#REF!' : 23, # Illegal or deleted cell reference
+ '#NAME?' : 29, # Wrong function or range name
+ '#NUM!' : 36, # Value range overflow
+ '#N/A!' : 42, # Argument or function not available
+}
+
+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()
+
+# module-level function for *internal* use by the Row module
+
+def _get_cells_biff_data_mul(rowx, cell_items):
+ # Return the BIFF data for all cell records in the row.
+ # Adjacent BLANK|RK records are combined into MUL(BLANK|RK) records.
+ 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) # pre-packed NUMBER record
+ 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 = b'' # (to_py3): 'b' binary data
+ for j in range(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:
+ # RK record
+ value, xf_idx = muldata[0]
+ pieces.append(pack('<5Hi', 0x027E, 10, rowx, icolx, xf_idx, value))
+ else:
+ # MULRK record
+ nc = lastcolx - icolx + 1
+ pieces.append(pack('<4H', 0x00BD, 6 * nc + 6, rowx, icolx))
+ # (to_py3): 'b' binary data
+ pieces.append(b''.join([pack('<Hi', xf_idx, value) for value, xf_idx in muldata]))
+ pieces.append(pack('<H', lastcolx))
+ else:
+ if lastcolx == icolx:
+ # BLANK record
+ xf_idx = muldata[0]
+ pieces.append(pack('<5H', 0x0201, 6, rowx, icolx, xf_idx))
+ else:
+ # MULBLANK record
+ nc = lastcolx - icolx + 1
+ pieces.append(pack('<4H', 0x00BE, 2 * nc + 6, rowx, icolx))
+ # (to_py3): 'b' binary data
+ 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) # (to_py3): 'b' binary data