class CustomChartsheetViews(Serialisable): tagname = "customSheetViews" customSheetView = Sequence(expected_type=CustomChartsheetView, allow_none=True) __elements__ = ('customSheetView', ) def __init__( self, customSheetView=None, ): self.customSheetView = customSheetView
class SmartTagList(Serialisable): tagname = "smartTagTypes" smartTagType = Sequence(expected_type=SmartTag, allow_none=True) __elements__ = ('smartTagType', ) def __init__( self, smartTagType=(), ): self.smartTagType = smartTagType
class OleObjects(Serialisable): tagname = "oleObjects" oleObject = Sequence(expected_type=OleObject) __elements__ = ('oleObject', ) def __init__( self, oleObject=(), ): self.oleObject = oleObject
class GradientStopList(Serialisable): tagname = "gradStopLst" gs = Sequence(expected_type=GradientStop) def __init__( self, gs=None, ): if gs is None: gs = [GradientStop(), GradientStop()] self.gs = gs
class Level(Serialisable): tagname = "lvl" pt = Sequence(expected_type=StrVal) __elements__ = ('pt', ) def __init__( self, pt=(), ): self.pt = pt
class Error(Serialisable): tagname = "e" tpls = Typed(expected_type=TupleList, allow_none=True) x = Sequence(expected_type=Index) v = String() u = Bool(allow_none=True) f = Bool(allow_none=True) c = String(allow_none=True) cp = Integer(allow_none=True) _in = Integer(allow_none=True) bc = HexBinary(allow_none=True) fc = HexBinary(allow_none=True) i = Bool(allow_none=True) un = Bool(allow_none=True) st = Bool(allow_none=True) b = Bool(allow_none=True) __elements__ = ('tpls', 'x') def __init__(self, tpls=None, x=(), v=None, u=None, f=None, c=None, cp=None, _in=None, bc=None, fc=None, i=None, un=None, st=None, b=None, ): self.tpls = tpls self.x = x self.v = v self.u = u self.f = f self.c = c self.cp = cp self._in = _in self.bc = bc self.fc = fc self.i = i self.un = un self.st = st self.b = b
class _NamedCellStyleList(Serialisable): """ Container for named cell style objects Not used in client code """ tagname = "cellStyles" count = Integer(allow_none=True) cellStyle = Sequence(expected_type=_NamedCellStyle) __attrs__ = ("count", ) def __init__( self, count=None, cellStyle=(), ): self.cellStyle = cellStyle @property def count(self): return len(self.cellStyle) @property def names(self): """ Convert to NamedStyle objects and remove duplicates. In theory the highest xfId wins but in practice they are duplicates so it doesn't matter. """ def sort_fn(v): return v.xfId styles = [] names = set() for ns in sorted(self.cellStyle, key=sort_fn): if ns.name in names: continue style = NamedStyle(name=ns.name, hidden=ns.hidden, builtinId=ns.builtinId) names.add(ns.name) style._set_index(len(styles)) # assign xfId styles.append(style) return NamedStyleList(styles)
class RecordList(Serialisable): mime_type = "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotCacheRecords+xml" rel_type = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/pivotCacheRecords" _id = 1 _path = "/xl/pivotCache/pivotCacheRecords{0}.xml" tagname ="pivotCacheRecords" r = Sequence(expected_type=Record, allow_none=True) extLst = Typed(expected_type=ExtensionList, allow_none=True) __elements__ = ('r', ) __attrs__ = ('count', ) def __init__(self, count=None, r=(), extLst=None, ): self.r = r self.extLst = extLst @property def count(self): return len(self.r) def to_tree(self): tree = super(RecordList, self).to_tree() tree.set("xmlns", SHEET_MAIN_NS) return tree @property def path(self): return self._path.format(self._id) def _write(self, archive, manifest): """ Write to zipfile and update manifest """ xml = tostring(self.to_tree()) archive.writestr(self.path[1:], xml) manifest.append(self) def _write_rels(self, archive, manifest): pass
class Text(Serialisable): tagname = "text" t = NestedText(allow_none=True, expected_type=unicode) plain = Alias("t") r = Sequence(expected_type=RichText, allow_none=True) formatted = Alias("r") rPh = Sequence(expected_type=PhoneticText, allow_none=True) phonetic = Alias("rPh") phoneticPr = Typed(expected_type=PhoneticProperties, allow_none=True) PhoneticProperties = Alias("phoneticPr") __elements__ = ('t', 'r', 'rPh', 'phoneticPr') def __init__( self, t=None, r=(), rPh=(), phoneticPr=None, ): self.t = t self.r = r self.rPh = rPh self.phoneticPr = phoneticPr @property def content(self): """ Text stripped of all formatting """ snippets = [] if self.plain is not None: snippets.append(self.plain) for block in self.formatted: snippets.append(block.t) return "".join(snippets)
class WebPublishItems(Serialisable): tagname = "WebPublishItems" count = Integer(allow_none=True) webPublishItem = Sequence(expected_type=WebPublishItem, ) __elements__ = ('webPublishItem',) def __init__(self, count=None, webPublishItem=None, ): self.count = len(webPublishItem) self.webPublishItem = webPublishItem
class ExternalRow(Serialisable): r = Integer() cell = Sequence(expected_type=ExternalCell) __elements__ = ('cell', ) def __init__( self, r=(), cell=None, ): self.r = r self.cell = cell
class ConditionalFormatting(Serialisable): tagname = "conditionalFormatting" sqref = String(allow_none=True) pivot = Bool(allow_none=True) cfRule = Sequence(expected_type=Rule) rules = Alias("cfRule") def __init__(self, sqref=None, pivot=None, cfRule=(), extLst=None): self.sqref = sqref self.pivot = pivot self.cfRule = cfRule
class ColorScale(RuleType): tagname = "colorScale" color = Sequence(expected_type=Color) __elements__ = ('cfvo', 'color') def __init__(self, cfvo=None, color=None, ): self.cfvo = cfvo self.color = color
class ChartsheetViewList(Serialisable): tagname = "sheetViews" sheetView = Sequence(expected_type=ChartsheetView, ) extLst = Typed(expected_type=ExtensionList, allow_none=True) __elements__ = ('sheetView',) def __init__(self, sheetView=None, extLst=None, ): if sheetView is None: sheetView = [ChartsheetView()] self.sheetView = sheetView
class CustomFilters(Serialisable): tagname = "customFilters" _and = Bool(allow_none=True) customFilter = Sequence(expected_type=CustomFilter) # min 1, max 2 __elements__ = ('customFilter',) def __init__(self, _and=None, customFilter=(), ): self._and = _and self.customFilter = customFilter
class _SurfaceChartBase(ChartBase): wireframe = NestedBool(allow_none=True) ser = Sequence(expected_type=Series, allow_none=True) bandFmts = Typed(expected_type=BandFormatList, allow_none=True) _series_type = "surface" __elements__ = ('wireframe', 'ser', 'bandFmts') def __init__(self, wireframe=None, ser=(), bandFmts=None, **kw): self.wireframe = wireframe self.ser = ser self.bandFmts = bandFmts super(_SurfaceChartBase, self).__init__(**kw)
class FunctionGroupList(Serialisable): tagname = "functionGroups" builtInGroupCount = Integer(allow_none=True) functionGroup = Sequence(expected_type=FunctionGroup, allow_none=True) __elements__ = ('functionGroup',) def __init__(self, builtInGroupCount=16, functionGroup=(), ): self.builtInGroupCount = builtInGroupCount self.functionGroup = functionGroup
class IgnoredErrors(Serialisable): tagname = "ignoredErrors" ignoredError = Sequence(expected_type=IgnoredError) extLst = Typed(expected_type=ExtensionList, allow_none=True) __elements__ = ('ignoredError', 'extLst') def __init__(self, ignoredError=(), extLst=None, ): self.ignoredError = ignoredError self.extLst = extLst
class HyperlinkList(Serialisable): tagname = "hyperlinks" hyperlink = Sequence(expected_type=Hyperlink) def __init__(self, hyperlink=()): self.hyperlink = hyperlink def __bool__(self): return bool(self.hyperlink) __nonzero__ = __bool__ def __len__(self): return len(self.hyperlink)
class CellSmartTags(Serialisable): tagname = "cellSmartTags" cellSmartTag = Sequence(expected_type=CellSmartTag) r = String() __elements__ = ('cellSmartTag', ) def __init__( self, cellSmartTag=(), r=None, ): self.cellSmartTag = cellSmartTag self.r = r
class ExternalSheetData(Serialisable): sheetId = Integer() refreshError = Bool(allow_none=True) row = Sequence(expected_type=ExternalRow) __elements__ = ('row',) def __init__(self, sheetId=None, refreshError=None, row=(), ): self.sheetId = sheetId self.refreshError = refreshError self.row = row
class PageBreak(Serialisable): tagname = "rowBreaks" count = Integer(allow_none=True) manualBreakCount = Integer(allow_none=True) brk = Sequence(expected_type=Break, allow_none=True) __elements__ = ('brk', ) __attrs__ = ( "count", "manualBreakCount", ) def __init__( self, count=None, manualBreakCount=None, brk=(), ): self.brk = brk def __bool__(self): return len(self.brk) > 0 __nonzero__ = __bool__ def __len__(self): return len(self.brk) @property def count(self): return len(self) @property def manualBreakCount(self): return len(self) def append(self, brk=None): """ Add a page break """ vals = list(self.brk) if not isinstance(brk, Break): brk = Break(id=self.count + 1) vals.append(brk) self.brk = vals
class DefinedNameList(Serialisable): tagname = "definedNames" definedName = Sequence(expected_type=DefinedName) def __init__(self, definedName=()): self.definedName = definedName def _duplicate(self, defn): """ Check for whether DefinedName with the same name and scope already exists """ for d in self.definedName: if d.name == defn.name and d.localSheetId == defn.localSheetId: return True def append(self, defn): if not isinstance(defn, DefinedName): raise TypeError("""You can only append DefinedNames""") if self._duplicate(defn): raise ValueError( """DefinedName with the same name and scope already exists""") names = self.definedName[:] names.append(defn) self.definedName = names def __len__(self): return len(self.definedName) def __contains__(self, name): for defn in self.definedName: if defn.name == name: return True def __getitem__(self, name): for defn in self.definedName: if defn.name == name: return defn raise KeyError("No definition called {0}".format(name)) def __delitem__(self, name): for idx, defn in enumerate(self.definedName): if defn.name == name: del self.definedName[idx] break
class DataValidationList(Serialisable): tagname = "dataValidations" disablePrompts = Bool(allow_none=True) xWindow = Integer(allow_none=True) yWindow = Integer(allow_none=True) dataValidation = Sequence(expected_type=DataValidation) __elements__ = ('dataValidation',) __attrs__ = ('disablePrompts', 'xWindow', 'yWindow', 'count') def __init__(self, disablePrompts=None, xWindow=None, yWindow=None, count=None, dataValidation=(), ): self.disablePrompts = disablePrompts self.xWindow = xWindow self.yWindow = yWindow self.dataValidation = dataValidation @property def count(self): return len(self) def __len__(self): return len(self.dataValidation) def append(self, dv): self.dataValidation.append(dv) def to_tree(self, tagname=None): """ Need to skip validations that have no cell ranges """ ranges = self.dataValidation # copy self.dataValidation = [r for r in self.dataValidation if bool(r.sqref)] xml = super(DataValidationList, self).to_tree(tagname) self.dataValidation = ranges return xml
class RelationshipList(Serialisable): tagname = "Relationships" Relationship = Sequence(expected_type=Relationship) def __init__(self, Relationship=()): self.Relationship = Relationship def append(self, value): values = self.Relationship[:] values.append(value) if not value.Id: value.Id = "rId{0}".format((len(values))) self.Relationship = values def __len__(self): return len(self.Relationship) def __bool__(self): return bool(self.Relationship) def find(self, content_type): """ Find relationships by content-type NB. these content-types namespaced objects and different to the MIME-types in the package manifest :-( """ for r in self.Relationship: if r.Type == content_type: yield r def __getitem__(self, key): for r in self.Relationship: if r.Id == key: return r raise KeyError("Unknown relationship: {0}".format(key)) def to_tree(self): tree = Element("Relationships", xmlns=PKG_REL_NS) for idx, rel in enumerate(self.Relationship, 1): if not rel.Id: rel.Id = "rId{0}".format(idx) tree.append(rel.to_tree()) return tree
class StrData(Serialisable): tagname = "strData" ptCount = NestedInteger(allow_none=True) pt = Sequence(expected_type=StrVal) extLst = Typed(expected_type=ExtensionList, allow_none=True) __elements__ = ('ptCount', 'pt') def __init__(self, ptCount=None, pt=(), extLst=None, ): self.ptCount = ptCount self.pt = pt
class NumData(Serialisable): formatCode = NestedText(expected_type=unicode, allow_none=True) ptCount = NestedInteger(allow_none=True) pt = Sequence(expected_type=NumVal) extLst = Typed(expected_type=ExtensionList, allow_none=True) __elements__ = ('formatCode', 'ptCount', 'pt') def __init__(self, formatCode=None, ptCount=None, pt=(), extLst=None, ): self.formatCode = formatCode self.ptCount = ptCount self.pt = pt
class RowHierarchiesUsage(Serialisable): tagname = "rowHierarchiesUsage" rowHierarchyUsage = Sequence(expected_type=HierarchyUsage, ) __elements__ = ('rowHierarchyUsage',) __attrs__ = ('count', ) def __init__(self, count=None, rowHierarchyUsage=(), ): self.rowHierarchyUsage = rowHierarchyUsage @property def count(self): return len(self.rowHierarchyUsage)
class Page(Serialisable): # PCDSCPage pageItem = Sequence(expected_type=PageItem) __elements__ = ('pageItem',) def __init__(self, count=None, pageItem=None, ): self.pageItem = pageItem @property def count(self): return len(self.pageItem)
class GradientFill(Fill): spec = """18.8.24""" __fields__ = ('fill_type', 'degree', 'left', 'right', 'top', 'bottom', 'stop') fill_type = Set(values=('linear', 'path')) type = Alias("fill_type") degree = Float() left = Float() right = Float() top = Float() bottom = Float() stop = Sequence(expected_type=Color) def __init__(self, fill_type="linear", degree=0, left=0, right=0, top=0, bottom=0, stop=(), type=None): self.degree = degree self.left = left self.right = right self.top = top self.bottom = bottom self.stop = stop # cannot use type attribute but allow it is an argument (ie. when parsing) if type is not None: fill_type = type self.fill_type = fill_type def __iter__(self): """ Dictionary interface for easier serialising. All values converted to strings """ for key in ('type', 'degree', 'left', 'right', 'top', 'bottom'): value = getattr(self, key) if bool(value): yield key, safe_string(value)