class ConditionalFormat(Serialisable): tagname = "conditionalFormat" scope = Set(values=(['selection', 'data', 'field'])) type = NoneSet(values=(['all', 'row', 'column'])) priority = Integer() pivotAreas = NestedSequence(expected_type=PivotArea) extLst = Typed(expected_type=ExtensionList, allow_none=True) __elements__ = ('pivotAreas',) def __init__(self, scope=None, type=None, priority=None, pivotAreas=(), extLst=None, ): self.scope = scope self.type = type self.priority = priority self.pivotAreas = pivotAreas self.extLst = extLst
class XMLColumnProps(Serialisable): tagname = "xmlColumnPr" mapId = Integer() xpath = String() denormalized = Bool(allow_none=True) xmlDataType = String() extLst = Typed(expected_type=ExtensionList, allow_none=True) __elements__ = () def __init__( self, mapId=None, xpath=None, denormalized=None, xmlDataType=None, extLst=None, ): self.mapId = mapId self.xpath = xpath self.denormalized = denormalized self.xmlDataType = xmlDataType
class LightRig(Serialisable): tagname = "lightRig" rig = Set(values=[ 'legacyFlat1', 'legacyFlat2', 'legacyFlat3', 'legacyFlat4', 'legacyNormal1', 'legacyNormal2', 'legacyNormal3', 'legacyNormal4', 'legacyHarsh1', 'legacyHarsh2', 'legacyHarsh3', 'legacyHarsh4', 'threePt', 'balanced', 'soft', 'harsh', 'flood', 'contrasting', 'morning', 'sunrise', 'sunset', 'chilly', 'freezing', 'flat', 'twoPt', 'glow', 'brightRoom' ]) dir = Set(values=(['tl', 't', 'tr', 'l', 'r', 'bl', 'b', 'br'])) rot = Typed(expected_type=SphereCoords, allow_none=True) def __init__( self, rig=None, dir=None, rot=None, ): self.rig = rig self.dir = dir self.rot = rot
class TableStyle(Serialisable): tagname = "tableStyle" name = String() pivot = Bool(allow_none=True) table = Bool(allow_none=True) count = Integer(allow_none=True) tableStyleElement = Typed(expected_type=TableStyleElement, allow_none=True) __elements__ = ('tableStyleElement',) def __init__(self, name=None, pivot=None, table=None, count=None, tableStyleElement=None, ): self.name = name self.pivot = pivot self.table = table self.count = count self.tableStyleElement = tableStyleElement
class _NamedCellStyle(Serialisable): """ Pointer-based representation of named styles in XML xfId refers to the corresponding CellStyleXfs Not used in client code. """ tagname = "cellStyle" name = String() xfId = Integer() builtinId = Integer(allow_none=True) iLevel = Integer(allow_none=True) hidden = Bool(allow_none=True) customBuiltin = Bool(allow_none=True) extLst = Typed(expected_type=ExtensionList, allow_none=True) __elements__ = () def __init__( self, name=None, xfId=None, builtinId=None, iLevel=None, hidden=None, customBuiltin=None, extLst=None, ): self.name = name self.xfId = xfId self.builtinId = builtinId self.iLevel = iLevel self.hidden = hidden self.customBuiltin = customBuiltin
class StockChart(ChartBase): tagname = "stockChart" ser = Sequence(expected_type=Series) #min 3, max4 dLbls = Typed(expected_type=DataLabelList, allow_none=True) dataLabels = Alias('dLbls') dropLines = Typed(expected_type=ChartLines, allow_none=True) hiLowLines = Typed(expected_type=ChartLines, allow_none=True) upDownBars = Typed(expected_type=UpDownBars, allow_none=True) extLst = Typed(expected_type=ExtensionList, allow_none=True) x_axis = Typed(expected_type=TextAxis) y_axis = Typed(expected_type=NumericAxis) _series_type = "line" __elements__ = ('ser', 'dLbls', 'dropLines', 'hiLowLines', 'upDownBars', 'axId') def __init__( self, ser=(), dLbls=None, dropLines=None, hiLowLines=None, upDownBars=None, axId=None, extLst=None, ): self.ser = ser self.dLbls = dLbls self.dropLines = dropLines self.hiLowLines = hiLowLines self.upDownBars = upDownBars self.x_axis = TextAxis() self.y_axis = NumericAxis() super(StockChart, self).__init__()
class LineChart3D(_LineChartBase): tagname = "line3DChart" grouping = _LineChartBase.grouping varyColors = _LineChartBase.varyColors ser = _LineChartBase.ser dLbls = _LineChartBase.dLbls dropLines = _LineChartBase.dropLines gapDepth = NestedGapAmount() hiLowLines = Typed(expected_type=ChartLines, allow_none=True) upDownBars = Typed(expected_type=UpDownBars, allow_none=True) marker = NestedBool(allow_none=True) smooth = NestedBool(allow_none=True) extLst = Typed(expected_type=ExtensionList, allow_none=True) x_axis = Typed(expected_type=TextAxis) y_axis = Typed(expected_type=NumericAxis) z_axis = Typed(expected_type=SeriesAxis) __elements__ = _LineChartBase.__elements__ + ( 'gapDepth', 'hiLowLines', 'upDownBars', 'marker', 'smooth', 'axId') def __init__(self, gapDepth=None, hiLowLines=None, upDownBars=None, marker=None, smooth=None, axId=None, **kw): self.gapDepth = gapDepth self.hiLowLines = hiLowLines self.upDownBars = upDownBars self.marker = marker self.smooth = smooth self.x_axis = TextAxis() self.y_axis = NumericAxis() self.z_axis = SeriesAxis() super(LineChart3D, self).__init__(**kw)
class Shape3D(Serialisable): namespace = DRAWING_NS z = Typed(expected_type=Coordinate, allow_none=True) extrusionH = Integer(allow_none=True) contourW = Integer(allow_none=True) prstMaterial = NoneSet(values=[ 'legacyMatte', 'legacyPlastic', 'legacyMetal', 'legacyWireframe', 'matte', 'plastic', 'metal', 'warmMatte', 'translucentPowder', 'powder', 'dkEdge', 'softEdge', 'clear', 'flat', 'softmetal' ]) bevelT = Typed(expected_type=Bevel, allow_none=True) bevelB = Typed(expected_type=Bevel, allow_none=True) extrusionClr = Typed(expected_type=Color, allow_none=True) contourClr = Typed(expected_type=Color, allow_none=True) extLst = Typed(expected_type=OfficeArtExtensionList, allow_none=True) def __init__( self, z=None, extrusionH=None, contourW=None, prstMaterial=None, bevelT=None, bevelB=None, extrusionClr=None, contourClr=None, extLst=None, ): self.z = z self.extrusionH = extrusionH self.contourW = contourW self.prstMaterial = prstMaterial self.bevelT = bevelT self.bevelB = bevelB self.extrusionClr = extrusionClr self.contourClr = contourClr self.extLst = extLst
class CustomGeometry2D(Serialisable): avLst = Typed(expected_type=GeomGuideList, allow_none=True) gdLst = Typed(expected_type=GeomGuideList, allow_none=True) ahLst = Typed(expected_type=AdjustHandleList, allow_none=True) cxnLst = Typed(expected_type=ConnectionSiteList, allow_none=True) rect = Typed(expected_type=GeomRect, allow_none=True) pathLst = Typed(expected_type=Path2DList, ) def __init__(self, avLst=None, gdLst=None, ahLst=None, cxnLst=None, rect=None, pathLst=None, ): self.avLst = avLst self.gdLst = gdLst self.ahLst = ahLst self.cxnLst = cxnLst self.rect = rect self.pathLst = pathLst
class _AnchorBase(Serialisable): #one of sp = Typed(expected_type=Shape, allow_none=True) shape = Alias("sp") grpSp = Typed(expected_type=GroupShape, allow_none=True) groupShape = Alias("grpSp") graphicFrame = Typed(expected_type=GraphicFrame, allow_none=True) cxnSp = Typed(expected_type=Shape, allow_none=True) connectionShape = Alias("cxnSp") pic = Typed(expected_type=PictureFrame, allow_none=True) contentPart = Relation() clientData = Typed(expected_type=AnchorClientData) __elements__ = ('sp', 'grpSp', 'graphicFrame', 'cxnSp', 'pic', 'contentPart', 'clientData') def __init__(self, clientData=None, sp=None, grpSp=None, graphicFrame=None, cxnSp=None, pic=None, contentPart=None ): if clientData is None: clientData = AnchorClientData() self.clientData = clientData self.sp = sp self.grpSp = grpSp self.graphicFrame = graphicFrame self.cxnSp = cxnSp self.pic = pic self.contentPart = contentPart
class Table(Serialisable): _path = "/tables/table{0}.xml" mime_type = "application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml" _rel_type = "table" _rel_id = None tagname = "table" id = Integer() name = TableNameDescriptor(allow_none=True) displayName = TableNameDescriptor() comment = String(allow_none=True) ref = String() tableType = NoneSet(values=(['worksheet', 'xml', 'queryTable'])) headerRowCount = Integer(allow_none=True) insertRow = Bool(allow_none=True) insertRowShift = Bool(allow_none=True) totalsRowCount = Integer(allow_none=True) totalsRowShown = Bool(allow_none=True) published = Bool(allow_none=True) headerRowDxfId = Integer(allow_none=True) dataDxfId = Integer(allow_none=True) totalsRowDxfId = Integer(allow_none=True) headerRowBorderDxfId = Integer(allow_none=True) tableBorderDxfId = Integer(allow_none=True) totalsRowBorderDxfId = Integer(allow_none=True) headerRowCellStyle = String(allow_none=True) dataCellStyle = String(allow_none=True) totalsRowCellStyle = String(allow_none=True) connectionId = Integer(allow_none=True) autoFilter = Typed(expected_type=AutoFilter, allow_none=True) sortState = Typed(expected_type=SortState, allow_none=True) tableColumns = NestedSequence(expected_type=TableColumn, count=True) tableStyleInfo = Typed(expected_type=TableStyleInfo, allow_none=True) extLst = Typed(expected_type=ExtensionList, allow_none=True) __elements__ = ('autoFilter', 'sortState', 'tableColumns', 'tableStyleInfo') def __init__( self, id=1, displayName=None, ref=None, name=None, comment=None, tableType=None, headerRowCount=None, insertRow=None, insertRowShift=None, totalsRowCount=None, totalsRowShown=None, published=None, headerRowDxfId=None, dataDxfId=None, totalsRowDxfId=None, headerRowBorderDxfId=None, tableBorderDxfId=None, totalsRowBorderDxfId=None, headerRowCellStyle=None, dataCellStyle=None, totalsRowCellStyle=None, connectionId=None, autoFilter=None, sortState=None, tableColumns=(), tableStyleInfo=None, extLst=None, ): self.id = id self.displayName = displayName if name is None: name = displayName self.name = name self.comment = comment self.ref = ref self.tableType = tableType self.headerRowCount = headerRowCount self.insertRow = insertRow self.insertRowShift = insertRowShift self.totalsRowCount = totalsRowCount self.totalsRowShown = totalsRowShown self.published = published self.headerRowDxfId = headerRowDxfId self.dataDxfId = dataDxfId self.totalsRowDxfId = totalsRowDxfId self.headerRowBorderDxfId = headerRowBorderDxfId self.tableBorderDxfId = tableBorderDxfId self.totalsRowBorderDxfId = totalsRowBorderDxfId self.headerRowCellStyle = headerRowCellStyle self.dataCellStyle = dataCellStyle self.totalsRowCellStyle = totalsRowCellStyle self.connectionId = connectionId if autoFilter is None: autoFilter = AutoFilter(ref=ref) self.autoFilter = autoFilter self.sortState = sortState if not tableColumns: tableColumns = list(_initialise_columns(ref)) self.tableColumns = tableColumns self.tableStyleInfo = tableStyleInfo def to_tree(self): tree = super(Table, self).to_tree() tree.set("xmlns", SHEET_MAIN_NS) return tree @property def path(self): """ Return path within the archive """ return "/xl" + self._path.format(self.id) def _write(self, archive): """ Serialise to XML and write to archive """ xml = self.to_tree() archive.writestr(self.path[1:], tostring(xml))
class TableColumn(Serialisable): tagname = "tableColumn" id = Integer() uniqueName = String(allow_none=True) name = String() totalsRowFunction = NoneSet(values=([ 'sum', 'min', 'max', 'average', 'count', 'countNums', 'stdDev', 'var', 'custom' ])) totalsRowLabel = String(allow_none=True) queryTableFieldId = Integer(allow_none=True) headerRowDxfId = Integer(allow_none=True) dataDxfId = Integer(allow_none=True) totalsRowDxfId = Integer(allow_none=True) headerRowCellStyle = String(allow_none=True) dataCellStyle = String(allow_none=True) totalsRowCellStyle = String(allow_none=True) calculatedColumnFormula = Typed(expected_type=TableFormula, allow_none=True) totalsRowFormula = Typed(expected_type=TableFormula, allow_none=True) xmlColumnPr = Typed(expected_type=XMLColumnProps, allow_none=True) extLst = Typed(expected_type=ExtensionList, allow_none=True) __elements__ = ('calculatedColumnFormula', 'totalsRowFormula', 'xmlColumnPr', 'extLst') def __init__( self, id=None, uniqueName=None, name=None, totalsRowFunction=None, totalsRowLabel=None, queryTableFieldId=None, headerRowDxfId=None, dataDxfId=None, totalsRowDxfId=None, headerRowCellStyle=None, dataCellStyle=None, totalsRowCellStyle=None, calculatedColumnFormula=None, totalsRowFormula=None, xmlColumnPr=None, extLst=None, ): self.id = id self.uniqueName = uniqueName self.name = name self.totalsRowFunction = totalsRowFunction self.totalsRowLabel = totalsRowLabel self.queryTableFieldId = queryTableFieldId self.headerRowDxfId = headerRowDxfId self.dataDxfId = dataDxfId self.totalsRowDxfId = totalsRowDxfId self.headerRowCellStyle = headerRowCellStyle self.dataCellStyle = dataCellStyle self.totalsRowCellStyle = totalsRowCellStyle self.calculatedColumnFormula = calculatedColumnFormula self.totalsRowFormula = totalsRowFormula self.xmlColumnPr = xmlColumnPr self.extLst = extLst def __iter__(self): for k, v in super(TableColumn, self).__iter__(): if k == 'name': v = escape(v) yield k, v @classmethod def from_tree(cls, node): self = super(TableColumn, cls).from_tree(node) self.name = unescape(self.name) return self
class TableDefinition(Serialisable): mime_type = "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotTable+xml" rel_type = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/pivotTable" _id = 1 _path = "/xl/pivotTables/pivotTable{0}.xml" tagname = "pivotTableDefinition" cache = None name = String() cacheId = Integer() dataOnRows = Bool() dataPosition = Integer(allow_none=True) dataCaption = String() grandTotalCaption = String(allow_none=True) errorCaption = String(allow_none=True) showError = Bool() missingCaption = String(allow_none=True) showMissing = Bool() pageStyle = String(allow_none=True) pivotTableStyle = String(allow_none=True) vacatedStyle = String(allow_none=True) tag = String(allow_none=True) updatedVersion = Integer() minRefreshableVersion = Integer() asteriskTotals = Bool() showItems = Bool() editData = Bool() disableFieldList = Bool() showCalcMbrs = Bool() visualTotals = Bool() showMultipleLabel = Bool() showDataDropDown = Bool() showDrill = Bool() printDrill = Bool() showMemberPropertyTips = Bool() showDataTips = Bool() enableWizard = Bool() enableDrill = Bool() enableFieldProperties = Bool() preserveFormatting = Bool() useAutoFormatting = Bool() pageWrap = Integer() pageOverThenDown = Bool() subtotalHiddenItems = Bool() rowGrandTotals = Bool() colGrandTotals = Bool() fieldPrintTitles = Bool() itemPrintTitles = Bool() mergeItem = Bool() showDropZones = Bool() createdVersion = Integer() indent = Integer() showEmptyRow = Bool() showEmptyCol = Bool() showHeaders = Bool() compact = Bool() outline = Bool() outlineData = Bool() compactData = Bool() published = Bool() gridDropZones = Bool() immersive = Bool() multipleFieldFilters = Bool() chartFormat = Integer() rowHeaderCaption = String(allow_none=True) colHeaderCaption = String(allow_none=True) fieldListSortAscending = Bool() mdxSubqueries = Bool() customListSort = Bool(allow_none=True) autoFormatId = Integer(allow_none=True) applyNumberFormats = Bool() applyBorderFormats = Bool() applyFontFormats = Bool() applyPatternFormats = Bool() applyAlignmentFormats = Bool() applyWidthHeightFormats = Bool() location = Typed(expected_type=Location, ) pivotFields = NestedSequence(expected_type=PivotField, count=True) rowFields = NestedSequence(expected_type=RowColField, count=True) rowItems = NestedSequence(expected_type=RowColItem, count=True) colFields = NestedSequence(expected_type=RowColField, count=True) colItems = NestedSequence(expected_type=RowColItem, count=True) pageFields = NestedSequence(expected_type=PageField, count=True) dataFields = NestedSequence(expected_type=DataField, count=True) formats = NestedSequence(expected_type=Format, count=True) conditionalFormats = NestedSequence(expected_type=ConditionalFormat, count=True) chartFormats = NestedSequence(expected_type=ChartFormat, count=True) pivotHierarchies = NestedSequence(expected_type=PivotHierarchy, count=True) pivotTableStyleInfo = Typed(expected_type=PivotTableStyle, allow_none=True) filters = NestedSequence(expected_type=PivotFilter, count=True) rowHierarchiesUsage = Typed(expected_type=RowHierarchiesUsage, allow_none=True) colHierarchiesUsage = Typed(expected_type=ColHierarchiesUsage, allow_none=True) extLst = Typed(expected_type=ExtensionList, allow_none=True) id = Relation() __elements__ = ( 'location', 'pivotFields', 'rowFields', 'rowItems', 'colFields', 'colItems', 'pageFields', 'dataFields', 'formats', 'conditionalFormats', 'chartFormats', 'pivotHierarchies', 'pivotTableStyleInfo', 'filters', 'rowHierarchiesUsage', 'colHierarchiesUsage', ) def __init__( self, name=None, cacheId=None, dataOnRows=False, dataPosition=None, dataCaption=None, grandTotalCaption=None, errorCaption=None, showError=False, missingCaption=None, showMissing=True, pageStyle=None, pivotTableStyle=None, vacatedStyle=None, tag=None, updatedVersion=0, minRefreshableVersion=0, asteriskTotals=False, showItems=True, editData=False, disableFieldList=False, showCalcMbrs=True, visualTotals=True, showMultipleLabel=True, showDataDropDown=True, showDrill=True, printDrill=False, showMemberPropertyTips=True, showDataTips=True, enableWizard=True, enableDrill=True, enableFieldProperties=True, preserveFormatting=True, useAutoFormatting=False, pageWrap=0, pageOverThenDown=False, subtotalHiddenItems=False, rowGrandTotals=True, colGrandTotals=True, fieldPrintTitles=False, itemPrintTitles=False, mergeItem=False, showDropZones=True, createdVersion=0, indent=1, showEmptyRow=False, showEmptyCol=False, showHeaders=True, compact=True, outline=False, outlineData=False, compactData=True, published=False, gridDropZones=False, immersive=True, multipleFieldFilters=None, chartFormat=0, rowHeaderCaption=None, colHeaderCaption=None, fieldListSortAscending=None, mdxSubqueries=None, customListSort=None, autoFormatId=None, applyNumberFormats=False, applyBorderFormats=False, applyFontFormats=False, applyPatternFormats=False, applyAlignmentFormats=False, applyWidthHeightFormats=False, location=None, pivotFields=(), rowFields=(), rowItems=(), colFields=(), colItems=(), pageFields=(), dataFields=(), formats=(), conditionalFormats=(), chartFormats=(), pivotHierarchies=(), pivotTableStyleInfo=None, filters=(), rowHierarchiesUsage=None, colHierarchiesUsage=None, extLst=None, id=None, ): self.name = name self.cacheId = cacheId self.dataOnRows = dataOnRows self.dataPosition = dataPosition self.dataCaption = dataCaption self.grandTotalCaption = grandTotalCaption self.errorCaption = errorCaption self.showError = showError self.missingCaption = missingCaption self.showMissing = showMissing self.pageStyle = pageStyle self.pivotTableStyle = pivotTableStyle self.vacatedStyle = vacatedStyle self.tag = tag self.updatedVersion = updatedVersion self.minRefreshableVersion = minRefreshableVersion self.asteriskTotals = asteriskTotals self.showItems = showItems self.editData = editData self.disableFieldList = disableFieldList self.showCalcMbrs = showCalcMbrs self.visualTotals = visualTotals self.showMultipleLabel = showMultipleLabel self.showDataDropDown = showDataDropDown self.showDrill = showDrill self.printDrill = printDrill self.showMemberPropertyTips = showMemberPropertyTips self.showDataTips = showDataTips self.enableWizard = enableWizard self.enableDrill = enableDrill self.enableFieldProperties = enableFieldProperties self.preserveFormatting = preserveFormatting self.useAutoFormatting = useAutoFormatting self.pageWrap = pageWrap self.pageOverThenDown = pageOverThenDown self.subtotalHiddenItems = subtotalHiddenItems self.rowGrandTotals = rowGrandTotals self.colGrandTotals = colGrandTotals self.fieldPrintTitles = fieldPrintTitles self.itemPrintTitles = itemPrintTitles self.mergeItem = mergeItem self.showDropZones = showDropZones self.createdVersion = createdVersion self.indent = indent self.showEmptyRow = showEmptyRow self.showEmptyCol = showEmptyCol self.showHeaders = showHeaders self.compact = compact self.outline = outline self.outlineData = outlineData self.compactData = compactData self.published = published self.gridDropZones = gridDropZones self.immersive = immersive self.multipleFieldFilters = multipleFieldFilters self.chartFormat = chartFormat self.rowHeaderCaption = rowHeaderCaption self.colHeaderCaption = colHeaderCaption self.fieldListSortAscending = fieldListSortAscending self.mdxSubqueries = mdxSubqueries self.customListSort = customListSort self.autoFormatId = autoFormatId self.applyNumberFormats = applyNumberFormats self.applyBorderFormats = applyBorderFormats self.applyFontFormats = applyFontFormats self.applyPatternFormats = applyPatternFormats self.applyAlignmentFormats = applyAlignmentFormats self.applyWidthHeightFormats = applyWidthHeightFormats self.location = location self.pivotFields = pivotFields self.rowFields = rowFields self.rowItems = rowItems self.colFields = colFields self.colItems = colItems self.pageFields = pageFields self.dataFields = dataFields self.formats = formats self.conditionalFormats = conditionalFormats self.chartFormats = chartFormats self.pivotHierarchies = pivotHierarchies self.pivotTableStyleInfo = pivotTableStyleInfo self.filters = filters self.rowHierarchiesUsage = rowHierarchiesUsage self.colHierarchiesUsage = colHierarchiesUsage self.extLst = extLst self.id = id def to_tree(self): tree = super(TableDefinition, 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): """ Add to zipfile and update manifest """ self._write_rels(archive, manifest) xml = tostring(self.to_tree()) archive.writestr(self.path[1:], xml) manifest.append(self) def _write_rels(self, archive, manifest): """ Write the relevant child objects and add links """ if self.cache is None: return rels = RelationshipList() r = Relationship(Type=self.cache.rel_type, Target=self.cache.path) rels.append(r) self.id = r.id if self.cache.path[1:] not in archive.namelist(): self.cache._write(archive, manifest) path = get_rels_path(self.path) xml = tostring(rels.to_tree()) archive.writestr(path[1:], xml)
class Reference(Serialisable): tagname = "reference" field = Integer(allow_none=True) selected = Bool(allow_none=True) byPosition = Bool(allow_none=True) relative = Bool(allow_none=True) defaultSubtotal = Bool(allow_none=True) sumSubtotal = Bool(allow_none=True) countASubtotal = Bool(allow_none=True) avgSubtotal = Bool(allow_none=True) maxSubtotal = Bool(allow_none=True) minSubtotal = Bool(allow_none=True) productSubtotal = Bool(allow_none=True) countSubtotal = Bool(allow_none=True) stdDevSubtotal = Bool(allow_none=True) stdDevPSubtotal = Bool(allow_none=True) varSubtotal = Bool(allow_none=True) varPSubtotal = Bool(allow_none=True) x = NestedInteger(allow_none=True, attribute="v") extLst = Typed(expected_type=ExtensionList, allow_none=True) __elements__ = ('x', ) def __init__( self, field=None, count=None, selected=None, byPosition=None, relative=None, defaultSubtotal=None, sumSubtotal=None, countASubtotal=None, avgSubtotal=None, maxSubtotal=None, minSubtotal=None, productSubtotal=None, countSubtotal=None, stdDevSubtotal=None, stdDevPSubtotal=None, varSubtotal=None, varPSubtotal=None, x=None, extLst=None, ): self.field = field self.selected = selected self.byPosition = byPosition self.relative = relative self.defaultSubtotal = defaultSubtotal self.sumSubtotal = sumSubtotal self.countASubtotal = countASubtotal self.avgSubtotal = avgSubtotal self.maxSubtotal = maxSubtotal self.minSubtotal = minSubtotal self.productSubtotal = productSubtotal self.countSubtotal = countSubtotal self.stdDevSubtotal = stdDevSubtotal self.stdDevPSubtotal = stdDevPSubtotal self.varSubtotal = varSubtotal self.varPSubtotal = varPSubtotal self.x = x @property def count(self): return len(self.field)
class HeaderFooterItem(Strict): """ Header or footer item """ left = Typed(expected_type=_HeaderFooterPart) center = Typed(expected_type=_HeaderFooterPart) right = Typed(expected_type=_HeaderFooterPart) __keys = ('L', 'C', 'R') def __init__(self, left=None, right=None, center=None): if left is None: left = _HeaderFooterPart() self.left = left if center is None: center = _HeaderFooterPart() self.center = center if right is None: right = _HeaderFooterPart() self.right = right def __str__(self): """ Pack parts into a single string """ TRANSFORM = { '&[Tab]': '&A', '&[Pages]': '&N', '&[Date]': '&D', '&[Path]': '&Z', '&[Page]': '&P', '&[Time]': '&T', '&[File]': '&F', '&[Picture]': '&G' } # escape keys and create regex SUBS_REGEX = re.compile("|".join( ["({0})".format(re.escape(k)) for k in TRANSFORM])) def replace(match): """ Callback for re.sub Replace expanded control with mini-format equivalent """ sub = match.group(0) return TRANSFORM[sub] txt = [] for key, part in zip(self.__keys, [self.left, self.center, self.right]): if part.text is not None: txt.append(u"&{0}{1}".format(key, unicode(part))) txt = "".join(txt) txt = SUBS_REGEX.sub(replace, txt) return escape(txt) def __bool__(self): return any([self.left, self.center, self.right]) __nonzero__ = __bool__ def to_tree(self, tagname): """ Return as XML node """ el = Element(tagname) el.text = unicode(self) return el @classmethod def from_tree(cls, node): if node.text: text = unescape(node.text) parts = _split_string(text) for k, v in parts.items(): if v is not None: parts[k] = _HeaderFooterPart.from_str(v) self = cls(**parts) return self
class ExtendedProperties(Serialisable): """ See 22.2 Most of this is irrelevant """ tagname = "Properties" Template = NestedText(expected_type=unicode, allow_none=True) Manager = NestedText(expected_type=unicode, allow_none=True) Company = NestedText(expected_type=unicode, allow_none=True) Pages = NestedText(expected_type=int, allow_none=True) Words = NestedText(expected_type=int, allow_none=True) Characters = NestedText(expected_type=int, allow_none=True) PresentationFormat = NestedText(expected_type=unicode, allow_none=True) Lines = NestedText(expected_type=int, allow_none=True) Paragraphs = NestedText(expected_type=int, allow_none=True) Slides = NestedText(expected_type=int, allow_none=True) Notes = NestedText(expected_type=int, allow_none=True) TotalTime = NestedText(expected_type=int, allow_none=True) HiddenSlides = NestedText(expected_type=int, allow_none=True) MMClips = NestedText(expected_type=int, allow_none=True) ScaleCrop = NestedText(expected_type=bool, allow_none=True) HeadingPairs = Typed(expected_type=VectorVariant, allow_none=True) TitlesOfParts = Typed(expected_type=VectorLpstr, allow_none=True) LinksUpToDate = NestedText(expected_type=bool, allow_none=True) CharactersWithSpaces = NestedText(expected_type=int, allow_none=True) SharedDoc = NestedText(expected_type=bool, allow_none=True) HyperlinkBase = NestedText(expected_type=unicode, allow_none=True) HLinks = Typed(expected_type=VectorVariant, allow_none=True) HyperlinksChanged = NestedText(expected_type=bool, allow_none=True) DigSig = Typed(expected_type=DigSigBlob, allow_none=True) Application = NestedText(expected_type=unicode, allow_none=True) AppVersion = NestedText(expected_type=unicode, allow_none=True) DocSecurity = NestedText(expected_type=int, allow_none=True) __elements__ = ('Application', 'AppVersion', 'DocSecurity', 'ScaleCrop', 'LinksUpToDate', 'SharedDoc', 'HyperlinksChanged') def __init__( self, Template=None, Manager=None, Company=None, Pages=None, Words=None, Characters=None, PresentationFormat=None, Lines=None, Paragraphs=None, Slides=None, Notes=None, TotalTime=None, HiddenSlides=None, MMClips=None, ScaleCrop=None, HeadingPairs=None, TitlesOfParts=None, LinksUpToDate=None, CharactersWithSpaces=None, SharedDoc=None, HyperlinkBase=None, HLinks=None, HyperlinksChanged=None, DigSig=None, Application="Microsoft Excel", AppVersion=VERSION, DocSecurity=None, ): self.Template = Template self.Manager = Manager self.Company = Company self.Pages = Pages self.Words = Words self.Characters = Characters self.PresentationFormat = PresentationFormat self.Lines = Lines self.Paragraphs = Paragraphs self.Slides = Slides self.Notes = Notes self.TotalTime = TotalTime self.HiddenSlides = HiddenSlides self.MMClips = MMClips self.ScaleCrop = ScaleCrop self.HeadingPairs = None self.TitlesOfParts = None self.LinksUpToDate = LinksUpToDate self.CharactersWithSpaces = CharactersWithSpaces self.SharedDoc = SharedDoc self.HyperlinkBase = HyperlinkBase self.HLinks = None self.HyperlinksChanged = HyperlinksChanged self.DigSig = None self.Application = Application self.AppVersion = AppVersion self.DocSecurity = DocSecurity def to_tree(self): tree = super(ExtendedProperties, self).to_tree() tree.set("xmlns", XPROPS_NS) return tree
class Series(Serialisable): """ Generic series object. Should not be instantiated directly. User the chart.Series factory instead. """ tagname = "ser" idx = NestedInteger() order = NestedInteger() tx = Typed(expected_type=SeriesLabel, allow_none=True) title = Alias('tx') spPr = Typed(expected_type=GraphicalProperties, allow_none=True) graphicalProperties = Alias('spPr') # area chart pictureOptions = Typed(expected_type=PictureOptions, allow_none=True) dPt = Sequence(expected_type=DataPoint, allow_none=True) data_points = Alias("dPt") dLbls = Typed(expected_type=DataLabelList, allow_none=True) labels = Alias("dLbls") trendline = Typed(expected_type=Trendline, allow_none=True) errBars = Typed(expected_type=ErrorBars, allow_none=True) cat = Typed(expected_type=AxDataSource, allow_none=True) identifiers = Alias("cat") val = Typed(expected_type=NumDataSource, allow_none=True) extLst = Typed(expected_type=ExtensionList, allow_none=True) #bar chart invertIfNegative = NestedBool(allow_none=True) shape = NestedNoneSet(values=(['cone', 'coneToMax', 'box', 'cylinder', 'pyramid', 'pyramidToMax'])) #bubble chart xVal = Typed(expected_type=AxDataSource, allow_none=True) yVal = Typed(expected_type=NumDataSource, allow_none=True) bubbleSize = Typed(expected_type=NumDataSource, allow_none=True) zVal = Alias("bubbleSize") bubble3D = NestedBool(allow_none=True) #line chart marker = Typed(expected_type=Marker, allow_none=True) smooth = NestedBool(allow_none=True) #pie chart explosion = NestedInteger(allow_none=True) __elements__ = () def __init__(self, idx=0, order=0, tx=None, spPr=None, pictureOptions=None, dPt=(), dLbls=None, trendline=None, errBars=None, cat=None, val=None, invertIfNegative=None, shape=None, xVal=None, yVal=None, bubbleSize=None, bubble3D=None, marker=None, smooth=None, explosion=None, extLst=None, ): self.idx = idx self.order = order self.tx = tx if spPr is None: spPr = GraphicalProperties() self.spPr = spPr self.pictureOptions = pictureOptions self.dPt = dPt self.dLbls = dLbls self.trendline = trendline self.errBars = errBars self.cat = cat self.val = val self.invertIfNegative = invertIfNegative self.shape = shape self.xVal = xVal self.yVal = yVal self.bubbleSize = bubbleSize self.bubble3D = bubble3D if marker is None: marker = Marker() self.marker = marker self.smooth = smooth self.explosion = explosion def to_tree(self, tagname=None, idx=None): """The index can need rebasing""" if idx is not None: if self.order == self.idx: self.order = idx # rebase the order if the index has been rebased self.idx = idx return super(Series, self).to_tree(tagname)
class Blip(Serialisable): tagname = "blip" namespace = DRAWING_NS #Using attribute groupAG_Blob cstate = NoneSet(values=(['email', 'screen', 'print', 'hqprint'])) embed = Relation() #rId link = Relation() #hyperlink noGrp = Bool(allow_none=True) noSelect = Bool(allow_none=True) noRot = Bool(allow_none=True) noChangeAspect = Bool(allow_none=True) noMove = Bool(allow_none=True) noResize = Bool(allow_none=True) noEditPoints = Bool(allow_none=True) noAdjustHandles = Bool(allow_none=True) noChangeArrowheads = Bool(allow_none=True) noChangeShapeType = Bool(allow_none=True) # some elements are choice extLst = Typed(expected_type=OfficeArtExtensionList, allow_none=True) alphaBiLevel = Typed(expected_type=AlphaBiLevelEffect, allow_none=True) alphaCeiling = Typed(expected_type=AlphaCeilingEffect, allow_none=True) alphaFloor = Typed(expected_type=AlphaFloorEffect, allow_none=True) alphaInv = Typed(expected_type=AlphaInverseEffect, allow_none=True) alphaMod = Typed(expected_type=AlphaModulateEffect, allow_none=True) alphaModFix = Typed(expected_type=AlphaModulateFixedEffect, allow_none=True) alphaRepl = Typed(expected_type=AlphaReplaceEffect, allow_none=True) biLevel = Typed(expected_type=BiLevelEffect, allow_none=True) blur = Typed(expected_type=BlurEffect, allow_none=True) clrChange = Typed(expected_type=ColorChangeEffect, allow_none=True) clrRepl = Typed(expected_type=ColorReplaceEffect, allow_none=True) duotone = Typed(expected_type=DuotoneEffect, allow_none=True) fillOverlay = Typed(expected_type=FillOverlayEffect, allow_none=True) grayscl = Typed(expected_type=GrayscaleEffect, allow_none=True) hsl = Typed(expected_type=HSLEffect, allow_none=True) lum = Typed(expected_type=LuminanceEffect, allow_none=True) tint = Typed(expected_type=TintEffect, allow_none=True) __elements__ = ('alphaBiLevel', 'alphaCeiling', 'alphaFloor', 'alphaInv', 'alphaMod', 'alphaModFix', 'alphaRepl', 'biLevel', 'blur', 'clrChange', 'clrRepl', 'duotone', 'fillOverlay', 'grayscl', 'hsl', 'lum', 'tint') def __init__( self, cstate=None, embed=None, link=None, noGrp=None, noSelect=None, noRot=None, noChangeAspect=None, noMove=None, noResize=None, noEditPoints=None, noAdjustHandles=None, noChangeArrowheads=None, noChangeShapeType=None, extLst=None, alphaBiLevel=None, alphaCeiling=None, alphaFloor=None, alphaInv=None, alphaMod=None, alphaModFix=None, alphaRepl=None, biLevel=None, blur=None, clrChange=None, clrRepl=None, duotone=None, fillOverlay=None, grayscl=None, hsl=None, lum=None, tint=None, ): self.cstate = cstate self.embed = embed self.link = link self.noGrp = noGrp self.noSelect = noSelect self.noRot = noRot self.noChangeAspect = noChangeAspect self.noMove = noMove self.noResize = noResize self.noEditPoints = noEditPoints self.noAdjustHandles = noAdjustHandles self.noChangeArrowheads = noChangeArrowheads self.noChangeShapeType = noChangeShapeType self.extLst = extLst self.alphaBiLevel = alphaBiLevel self.alphaCeiling = alphaCeiling self.alphaFloor = alphaFloor self.alphaInv = alphaInv self.alphaMod = alphaMod self.alphaModFix = alphaModFix self.alphaRepl = alphaRepl self.biLevel = biLevel self.blur = blur self.clrChange = clrChange self.clrRepl = clrRepl self.duotone = duotone self.fillOverlay = fillOverlay self.grayscl = grayscl self.hsl = hsl self.lum = lum self.tint = tint
class ChartBase(Serialisable): """ Base class for all charts """ legend = Typed(expected_type=Legend, allow_none=True) layout = Typed(expected_type=Layout, allow_none=True) roundedCorners = Bool(allow_none=True) axId = ValueSequence(expected_type=int) visible_cells_only = Bool(allow_none=True) display_blanks = Set(values=['span', 'gap', 'zero']) _series_type = "" ser = () series = Alias('ser') title = TitleDescriptor() anchor = "E15" # default anchor position width = 15 # in cm, approx 5 rows height = 7.5 # in cm, approx 14 rows _id = 1 _path = "/xl/charts/chart{0}.xml" style = MinMax(allow_none=True, min=1, max=48) mime_type = "application/vnd.openxmlformats-officedocument.drawingml.chart+xml" graphical_properties = Typed(expected_type=GraphicalProperties, allow_none=True) __elements__ = () def __init__(self, axId=(), **kw): self._charts = [self] self.title = None self.layout = None self.roundedCorners = None self.legend = Legend() self.graphical_properties = None self.style = None self.plot_area = PlotArea() self.axId = axId self.display_blanks = 'gap' self.pivotSource = None self.pivotFormats = () self.visible_cells_only = True self.idx_base = 0 super(ChartBase, self).__init__() def __hash__(self): """ Just need to check for identity """ return id(self) def __iadd__(self, other): """ Combine the chart with another one """ if not isinstance(other, ChartBase): raise TypeError("Only other charts can be added") self._charts.append(other) return self def to_tree(self, namespace=None, tagname=None, idx=None): self.axId = [id for id in self._axes] if self.ser is not None: for s in self.ser: s.__elements__ = attribute_mapping[self._series_type] return super(ChartBase, self).to_tree(tagname, idx) def _reindex(self): """ Normalise and rebase series: sort by order and then rebase order """ # sort data series in order and rebase ds = sorted(self.series, key=attrgetter("order")) for idx, s in enumerate(ds): s.order = idx self.series = ds def _write(self): from .chartspace import ChartSpace, ChartContainer self.plot_area.layout = self.layout idx_base = self.idx_base for chart in self._charts: if chart not in self.plot_area._charts: chart.idx_base = idx_base idx_base += len(chart.series) self.plot_area._charts = self._charts container = ChartContainer(plotArea=self.plot_area, legend=self.legend, title=self.title) if isinstance(chart, _3DBase): container.view3D = chart.view3D container.floor = chart.floor container.sideWall = chart.sideWall container.backWall = chart.backWall container.plotVisOnly = self.visible_cells_only container.dispBlanksAs = self.display_blanks container.pivotFmts = self.pivotFormats cs = ChartSpace(chart=container) cs.style = self.style cs.roundedCorners = self.roundedCorners cs.pivotSource = self.pivotSource return cs.to_tree() @property def _axes(self): x = getattr(self, "x_axis", None) y = getattr(self, "y_axis", None) z = getattr(self, "z_axis", None) return OrderedDict([(axis.axId, axis) for axis in (x, y, z) if axis]) def set_categories(self, labels): """ Set the categories / x-axis values """ if not isinstance(labels, Reference): labels = Reference(range_string=labels) for s in self.ser: s.cat = AxDataSource(numRef=NumRef(f=labels)) def add_data(self, data, from_rows=False, titles_from_data=False): """ Add a range of data in a single pass. The default is to treat each column as a data series. """ if not isinstance(data, Reference): data = Reference(range_string=data) if from_rows: values = data.rows else: values = data.cols for ref in values: series = SeriesFactory(ref, title_from_data=titles_from_data) self.series.append(series) def append(self, value): """Append a data series to the chart""" l = self.series[:] l.append(value) self.series = l @property def path(self): return self._path.format(self._id)
class RichTextProperties(Serialisable): tagname = "bodyPr" namespace = DRAWING_NS rot = Integer(allow_none=True) spcFirstLastPara = Bool(allow_none=True) vertOverflow = NoneSet(values=(['overflow', 'ellipsis', 'clip'])) horzOverflow = NoneSet(values=(['overflow', 'clip'])) vert = NoneSet(values=(['horz', 'vert', 'vert270', 'wordArtVert', 'eaVert', 'mongolianVert', 'wordArtVertRtl'])) wrap = NoneSet(values=(['none', 'square'])) lIns = Integer(allow_none=True) tIns = Integer(allow_none=True) rIns = Integer(allow_none=True) bIns = Integer(allow_none=True) numCol = Integer(allow_none=True) spcCol = Integer(allow_none=True) rtlCol = Bool(allow_none=True) fromWordArt = Bool(allow_none=True) anchor = NoneSet(values=(['t', 'ctr', 'b', 'just', 'dist'])) anchorCtr = Bool(allow_none=True) forceAA = Bool(allow_none=True) upright = Bool(allow_none=True) compatLnSpc = Bool(allow_none=True) prstTxWarp = Typed(expected_type=PresetTextShape, allow_none=True) scene3d = Typed(expected_type=Scene3D, allow_none=True) extLst = Typed(expected_type=OfficeArtExtensionList, allow_none=True) noAutofit = EmptyTag() normAutofit = EmptyTag() spAutoFit = EmptyTag() flatTx = NestedInteger(attribute="z", allow_none=True) __elements__ = ('prstTxWarp', 'scene3d', 'noAutofit', 'normAutofit', 'spAutoFit') def __init__(self, rot=None, spcFirstLastPara=None, vertOverflow=None, horzOverflow=None, vert=None, wrap=None, lIns=None, tIns=None, rIns=None, bIns=None, numCol=None, spcCol=None, rtlCol=None, fromWordArt=None, anchor=None, anchorCtr=None, forceAA=None, upright=None, compatLnSpc=None, prstTxWarp=None, scene3d=None, extLst=None, noAutofit=None, normAutofit=None, spAutoFit=None, flatTx=None, ): self.rot = rot self.spcFirstLastPara = spcFirstLastPara self.vertOverflow = vertOverflow self.horzOverflow = horzOverflow self.vert = vert self.wrap = wrap self.lIns = lIns self.tIns = tIns self.rIns = rIns self.bIns = bIns self.numCol = numCol self.spcCol = spcCol self.rtlCol = rtlCol self.fromWordArt = fromWordArt self.anchor = anchor self.anchorCtr = anchorCtr self.forceAA = forceAA self.upright = upright self.compatLnSpc = compatLnSpc self.prstTxWarp = prstTxWarp self.scene3d = scene3d self.noAutofit = noAutofit self.normAutofit = normAutofit self.spAutoFit = spAutoFit self.flatTx = flatTx
class NamedStyle(Serialisable): """ Named and editable styles """ font = Typed(expected_type=Font) fill = Typed(expected_type=Fill) border = Typed(expected_type=Border) alignment = Typed(expected_type=Alignment) number_format = NumberFormatDescriptor() protection = Typed(expected_type=Protection) builtinId = Integer(allow_none=True) hidden = Bool(allow_none=True) xfId = Integer(allow_none=True) name = String() _wb = None _style = StyleArray() def __init__( self, name="Normal", font=Font(), fill=PatternFill(), border=Border(), alignment=Alignment(), number_format=None, protection=Protection(), builtinId=None, hidden=False, xfId=None, ): self.name = name self.font = font self.fill = fill self.border = border self.alignment = alignment self.number_format = number_format self.protection = protection self.builtinId = builtinId self.hidden = hidden self._wb = None self._style = StyleArray() def __setattr__(self, attr, value): super(NamedStyle, self).__setattr__(attr, value) if getattr(self, '_wb', None) and attr in ( 'font', 'fill', 'border', 'alignment', 'number_format', 'protection', ): self._recalculate() def __iter__(self): for key in ('name', 'builtinId', 'hidden', 'xfId'): value = getattr(self, key, None) if value is not None: yield key, safe_string(value) @property def xfId(self): """ Index of the style in the list of named styles """ return self._style.xfId def _set_index(self, idx): """ Allow the containing list to set the index """ self._style.xfId = idx def bind(self, wb): """ Bind a named style to a workbook """ self._wb = wb self._recalculate() def _recalculate(self): self._style.fontId = self._wb._fonts.add(self.font) self._style.borderId = self._wb._borders.add(self.border) self._style.fillId = self._wb._fills.add(self.fill) self._style.protectionId = self._wb._protections.add(self.protection) self._style.alignmentId = self._wb._alignments.add(self.alignment) fmt = self.number_format if fmt in BUILTIN_FORMATS_REVERSE: fmt = BUILTIN_FORMATS_REVERSE[fmt] else: fmt = self._wb._number_formats.add(self.number_format) + 164 self._style.numFmtId = fmt def as_tuple(self): """Return a style array representing the current style""" return self._style def as_xf(self): """ Return equivalent XfStyle """ xf = CellStyle.from_array(self._style) xf.xfId = None xf.pivotButton = None xf.quotePrefix = None if self.alignment != Alignment(): xf.alignment = self.alignment if self.protection != Protection(): xf.protection = self.protection return xf def as_name(self): """ Return relevant named style """ named = _NamedCellStyle(name=self.name, builtinId=self.builtinId, hidden=self.hidden, xfId=self.xfId) return named
class CacheDefinition(Serialisable): mime_type = "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotCacheDefinition+xml" rel_type = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/pivotCacheDefinition" _id = 1 _path = "/xl/pivotCache/pivotCacheDefinition{0}.xml" records = None tagname = "pivotCacheDefinition" invalid = Bool(allow_none=True) saveData = Bool(allow_none=True) refreshOnLoad = Bool(allow_none=True) optimizeMemory = Bool(allow_none=True) enableRefresh = Bool(allow_none=True) refreshedBy = String(allow_none=True) refreshedDate = Float(allow_none=True) refreshedDateIso = DateTime(allow_none=True) backgroundQuery = Bool(allow_none=True) missingItemsLimit = Integer(allow_none=True) createdVersion = Integer(allow_none=True) refreshedVersion = Integer(allow_none=True) minRefreshableVersion = Integer(allow_none=True) recordCount = Integer(allow_none=True) upgradeOnRefresh = Bool(allow_none=True) tupleCache = Bool(allow_none=True) supportSubquery = Bool(allow_none=True) supportAdvancedDrill = Bool(allow_none=True) cacheSource = Typed(expected_type=CacheSource) cacheFields = NestedSequence(expected_type=CacheField, count=True) cacheHierarchies = NestedSequence(expected_type=CacheHierarchy, allow_none=True) kpis = NestedSequence(expected_type=PCDKPI, allow_none=True) tupleCache = Typed(expected_type=TupleCache, allow_none=True) calculatedItems = NestedSequence(expected_type=CalculatedItem, count=True) calculatedMembers = NestedSequence(expected_type=CalculatedMember, count=True) dimensions = NestedSequence(expected_type=PivotDimension, allow_none=True) measureGroups = NestedSequence(expected_type=MeasureGroup, count=True) maps = NestedSequence(expected_type=MeasureDimensionMap, count=True) extLst = Typed(expected_type=ExtensionList, allow_none=True) id = Relation() __elements__ = ( 'cacheSource', 'cacheFields', 'cacheHierarchies', 'kpis', 'tupleCache', 'calculatedItems', 'calculatedMembers', 'dimensions', 'measureGroups', 'maps', ) def __init__( self, invalid=None, saveData=None, refreshOnLoad=None, optimizeMemory=None, enableRefresh=None, refreshedBy=None, refreshedDate=None, refreshedDateIso=None, backgroundQuery=None, missingItemsLimit=None, createdVersion=None, refreshedVersion=None, minRefreshableVersion=None, recordCount=None, upgradeOnRefresh=None, tupleCache=None, supportSubquery=None, supportAdvancedDrill=None, cacheSource=None, cacheFields=(), cacheHierarchies=(), kpis=(), calculatedItems=(), calculatedMembers=(), dimensions=(), measureGroups=(), maps=(), extLst=None, id=None, ): self.invalid = invalid self.saveData = saveData self.refreshOnLoad = refreshOnLoad self.optimizeMemory = optimizeMemory self.enableRefresh = enableRefresh self.refreshedBy = refreshedBy self.refreshedDate = refreshedDate self.refreshedDateIso = refreshedDateIso self.backgroundQuery = backgroundQuery self.missingItemsLimit = missingItemsLimit self.createdVersion = createdVersion self.refreshedVersion = refreshedVersion self.minRefreshableVersion = minRefreshableVersion self.recordCount = recordCount self.upgradeOnRefresh = upgradeOnRefresh self.tupleCache = tupleCache self.supportSubquery = supportSubquery self.supportAdvancedDrill = supportAdvancedDrill self.cacheSource = cacheSource self.cacheFields = cacheFields self.cacheHierarchies = cacheHierarchies self.kpis = kpis self.tupleCache = tupleCache self.calculatedItems = calculatedItems self.calculatedMembers = calculatedMembers self.dimensions = dimensions self.measureGroups = measureGroups self.maps = maps self.id = id def to_tree(self): node = super(CacheDefinition, self).to_tree() node.set("xmlns", SHEET_MAIN_NS) return node @property def path(self): return self._path.format(self._id) def _write(self, archive, manifest): """ Add to zipfile and update manifest """ self._write_rels(archive, manifest) xml = tostring(self.to_tree()) archive.writestr(self.path[1:], xml) manifest.append(self) def _write_rels(self, archive, manifest): """ Write the relevant child objects and add links """ if self.records is None: return rels = RelationshipList() r = Relationship(Type=self.records.rel_type, Target=self.records.path) rels.append(r) self.id = r.id self.records._id = self._id self.records._write(archive, manifest) path = get_rels_path(self.path) xml = tostring(rels.to_tree()) archive.writestr(path[1:], xml)
class Stylesheet(Serialisable): tagname = "styleSheet" numFmts = Typed(expected_type=NumberFormatList) fonts = NestedSequence(expected_type=Font, count=True) fills = NestedSequence(expected_type=Fill, count=True) borders = NestedSequence(expected_type=Border, count=True) cellStyleXfs = Typed(expected_type=CellStyleList) cellXfs = Typed(expected_type=CellStyleList) cellStyles = Typed(expected_type=_NamedCellStyleList) dxfs = NestedSequence(expected_type=DifferentialStyle, count=True) tableStyles = Typed(expected_type=TableStyleList, allow_none=True) colors = Typed(expected_type=ColorList, allow_none=True) extLst = Typed(expected_type=ExtensionList, allow_none=True) __elements__ = ('numFmts', 'fonts', 'fills', 'borders', 'cellStyleXfs', 'cellXfs', 'cellStyles', 'dxfs', 'tableStyles', 'colors') def __init__( self, numFmts=None, fonts=(), fills=(), borders=(), cellStyleXfs=None, cellXfs=None, cellStyles=None, dxfs=(), tableStyles=None, colors=None, extLst=None, ): if numFmts is None: numFmts = NumberFormatList() self.numFmts = numFmts self.number_formats = IndexedList() self.fonts = fonts self.fills = fills self.borders = borders if cellStyleXfs is None: cellStyleXfs = CellStyleList() self.cellStyleXfs = cellStyleXfs if cellXfs is None: cellXfs = CellStyleList() self.cellXfs = cellXfs if cellStyles is None: cellStyles = _NamedCellStyleList() self.cellStyles = cellStyles self.dxfs = dxfs self.tableStyles = tableStyles self.colors = colors self.cell_styles = self.cellXfs._to_array() self.alignments = self.cellXfs.alignments self.protections = self.cellXfs.prots self._normalise_numbers() self.named_styles = self._merge_named_styles() @classmethod def from_tree(cls, node): # strip all attribs attrs = dict(node.attrib) for k in attrs: del node.attrib[k] return super(Stylesheet, cls).from_tree(node) def _merge_named_styles(self): """ Merge named style names "cellStyles" with their associated styles "cellStyleXfs" """ named_styles = self.cellStyles.names for style in named_styles: self._expand_named_style(style) return named_styles def _expand_named_style(self, named_style): """ Bind format definitions for a named style from the associated style record """ xf = self.cellStyleXfs[named_style.xfId] named_style.font = self.fonts[xf.fontId] named_style.fill = self.fills[xf.fillId] named_style.border = self.borders[xf.borderId] if xf.numFmtId in self.custom_formats: named_style.number_format = self.custom_formats[xf.numFmtId] if xf.alignment: named_style.alignment = xf.alignment if xf.protection: named_style.protection = xf.protection def _split_named_styles(self, wb): """ Convert NamedStyle into separate CellStyle and Xf objects """ for style in wb._named_styles: self.cellStyles.cellStyle.append(style.as_name()) self.cellStyleXfs.xf.append(style.as_xf()) @property def custom_formats(self): return dict([(n.numFmtId, n.formatCode) for n in self.numFmts.numFmt]) def _normalise_numbers(self): """ Rebase custom numFmtIds with a floor of 164 when reading stylesheet And index datetime formats """ date_formats = set() custom = self.custom_formats formats = self.number_formats for idx, style in enumerate(self.cell_styles): if style.numFmtId in custom: fmt = custom[style.numFmtId] if fmt in BUILTIN_FORMATS_REVERSE: # remove builtins style.numFmtId = BUILTIN_FORMATS_REVERSE[fmt] else: style.numFmtId = formats.add(fmt) + 164 else: fmt = BUILTIN_FORMATS[style.numFmtId] if is_date_format(fmt): # Create an index of which styles refer to datetimes date_formats.add(idx) self.date_formats = date_formats def to_tree(self, tagname=None, idx=None, namespace=None): tree = super(Stylesheet, self).to_tree(tagname, idx, namespace) tree.set("xmlns", SHEET_MAIN_NS) return tree
class CacheHierarchy(Serialisable): tagname = "cacheHierarchy" uniqueName = String() caption = String(allow_none=True) measure = Bool() set = Bool() parentSet = Integer(allow_none=True) iconSet = Integer() attribute = Bool() time = Bool() keyAttribute = Bool() defaultMemberUniqueName = String(allow_none=True) allUniqueName = String(allow_none=True) allCaption = String(allow_none=True) dimensionUniqueName = String(allow_none=True) displayFolder = String(allow_none=True) measureGroup = String(allow_none=True) measures = Bool() count = Integer() oneField = Bool() memberValueDatatype = Integer(allow_none=True) unbalanced = Bool(allow_none=True) unbalancedGroup = Bool(allow_none=True) hidden = Bool() fieldsUsage = Typed(expected_type=FieldsUsage, allow_none=True) groupLevels = Typed(expected_type=GroupLevels, allow_none=True) extLst = Typed(expected_type=ExtensionList, allow_none=True) __elements__ = ('fieldsUsage', 'groupLevels') def __init__( self, uniqueName="", caption=None, measure=None, set=None, parentSet=None, iconSet=0, attribute=None, time=None, keyAttribute=None, defaultMemberUniqueName=None, allUniqueName=None, allCaption=None, dimensionUniqueName=None, displayFolder=None, measureGroup=None, measures=None, count=None, oneField=None, memberValueDatatype=None, unbalanced=None, unbalancedGroup=None, hidden=None, fieldsUsage=None, groupLevels=None, extLst=None, ): self.uniqueName = uniqueName self.caption = caption self.measure = measure self.set = set self.parentSet = parentSet self.iconSet = iconSet self.attribute = attribute self.time = time self.keyAttribute = keyAttribute self.defaultMemberUniqueName = defaultMemberUniqueName self.allUniqueName = allUniqueName self.allCaption = allCaption self.dimensionUniqueName = dimensionUniqueName self.displayFolder = displayFolder self.measureGroup = measureGroup self.measures = measures self.count = count self.oneField = oneField self.memberValueDatatype = memberValueDatatype self.unbalanced = unbalanced self.unbalancedGroup = unbalancedGroup self.hidden = hidden self.fieldsUsage = fieldsUsage self.groupLevels = groupLevels self.extLst = extLst
class HeaderFooter(Serialisable): tagname = "headerFooter" differentOddEven = Bool(allow_none=True) differentFirst = Bool(allow_none=True) scaleWithDoc = Bool(allow_none=True) alignWithMargins = Bool(allow_none=True) oddHeader = Typed(expected_type=HeaderFooterItem, allow_none=True) oddFooter = Typed(expected_type=HeaderFooterItem, allow_none=True) evenHeader = Typed(expected_type=HeaderFooterItem, allow_none=True) evenFooter = Typed(expected_type=HeaderFooterItem, allow_none=True) firstHeader = Typed(expected_type=HeaderFooterItem, allow_none=True) firstFooter = Typed(expected_type=HeaderFooterItem, allow_none=True) __elements__ = ("oddHeader", "oddFooter", "evenHeader", "evenFooter", "firstHeader", "firstFooter") def __init__( self, differentOddEven=None, differentFirst=None, scaleWithDoc=None, alignWithMargins=None, oddHeader=None, oddFooter=None, evenHeader=None, evenFooter=None, firstHeader=None, firstFooter=None, ): self.differentOddEven = differentOddEven self.differentFirst = differentFirst self.scaleWithDoc = scaleWithDoc self.alignWithMargins = alignWithMargins if oddHeader is None: oddHeader = HeaderFooterItem() self.oddHeader = oddHeader if oddFooter is None: oddFooter = HeaderFooterItem() self.oddFooter = oddFooter if evenHeader is None: evenHeader = HeaderFooterItem() self.evenHeader = evenHeader if evenFooter is None: evenFooter = HeaderFooterItem() self.evenFooter = evenFooter if firstHeader is None: firstHeader = HeaderFooterItem() self.firstHeader = firstHeader if firstFooter is None: firstFooter = HeaderFooterItem() self.firstFooter = firstFooter def __bool__(self): parts = [ getattr(self, attr) for attr in self.__attrs__ + self.__elements__ ] return any(parts) __nonzero__ = __bool__
class CacheField(Serialisable): tagname = "cacheField" sharedItems = Typed(expected_type=SharedItems, allow_none=True) fieldGroup = Typed(expected_type=FieldGroup, allow_none=True) mpMap = NestedInteger(allow_none=True, attribute="v") extLst = Typed(expected_type=ExtensionList, allow_none=True) name = String() caption = String(allow_none=True) propertyName = String(allow_none=True) serverField = Bool(allow_none=True) uniqueList = Bool(allow_none=True) numFmtId = Integer(allow_none=True) formula = String(allow_none=True) sqlType = Integer(allow_none=True) hierarchy = Integer(allow_none=True) level = Integer(allow_none=True) databaseField = Bool(allow_none=True) mappingCount = Integer(allow_none=True) memberPropertyField = Bool(allow_none=True) __elements__ = ('sharedItems', 'fieldGroup', 'mpMap') def __init__( self, sharedItems=None, fieldGroup=None, mpMap=None, extLst=None, name=None, caption=None, propertyName=None, serverField=None, uniqueList=True, numFmtId=None, formula=None, sqlType=0, hierarchy=0, level=0, databaseField=True, mappingCount=None, memberPropertyField=None, ): self.sharedItems = sharedItems self.fieldGroup = fieldGroup self.mpMap = mpMap self.extLst = extLst self.name = name self.caption = caption self.propertyName = propertyName self.serverField = serverField self.uniqueList = uniqueList self.numFmtId = numFmtId self.formula = formula self.sqlType = sqlType self.hierarchy = hierarchy self.level = level self.databaseField = databaseField self.mappingCount = mappingCount self.memberPropertyField = memberPropertyField
class PivotField(Serialisable): tagname = "pivotField" items = NestedSequence(expected_type=FieldItem, count=True) autoSortScope = Typed(expected_type=AutoSortScope, allow_none=True) extLst = Typed(expected_type=ExtensionList, allow_none=True) name = String(allow_none=True) axis = NoneSet(values=(['axisRow', 'axisCol', 'axisPage', 'axisValues'])) dataField = Bool(allow_none=True) subtotalCaption = String(allow_none=True) showDropDowns = Bool(allow_none=True) hiddenLevel = Bool(allow_none=True) uniqueMemberProperty = String(allow_none=True) compact = Bool(allow_none=True) allDrilled = Bool(allow_none=True) numFmtId = Integer(allow_none=True) outline = Bool(allow_none=True) subtotalTop = Bool(allow_none=True) dragToRow = Bool(allow_none=True) dragToCol = Bool(allow_none=True) multipleItemSelectionAllowed = Bool(allow_none=True) dragToPage = Bool(allow_none=True) dragToData = Bool(allow_none=True) dragOff = Bool(allow_none=True) showAll = Bool(allow_none=True) insertBlankRow = Bool(allow_none=True) serverField = Bool(allow_none=True) insertPageBreak = Bool(allow_none=True) autoShow = Bool(allow_none=True) topAutoShow = Bool(allow_none=True) hideNewItems = Bool(allow_none=True) measureFilter = Bool(allow_none=True) includeNewItemsInFilter = Bool(allow_none=True) itemPageCount = Integer(allow_none=True) sortType = Set(values=(['manual', 'ascending', 'descending'])) dataSourceSort = Bool(allow_none=True) nonAutoSortDefault = Bool(allow_none=True) rankBy = Integer(allow_none=True) defaultSubtotal = Bool(allow_none=True) sumSubtotal = Bool(allow_none=True) countASubtotal = Bool(allow_none=True) avgSubtotal = Bool(allow_none=True) maxSubtotal = Bool(allow_none=True) minSubtotal = Bool(allow_none=True) productSubtotal = Bool(allow_none=True) countSubtotal = Bool(allow_none=True) stdDevSubtotal = Bool(allow_none=True) stdDevPSubtotal = Bool(allow_none=True) varSubtotal = Bool(allow_none=True) varPSubtotal = Bool(allow_none=True) showPropCell = Bool(allow_none=True) showPropTip = Bool(allow_none=True) showPropAsCaption = Bool(allow_none=True) defaultAttributeDrillState = Bool(allow_none=True) __elements__ = ( 'items', 'autoSortScope', ) def __init__( self, items=(), autoSortScope=None, name=None, axis=None, dataField=None, subtotalCaption=None, showDropDowns=True, hiddenLevel=None, uniqueMemberProperty=None, compact=True, allDrilled=None, numFmtId=None, outline=True, subtotalTop=True, dragToRow=True, dragToCol=True, multipleItemSelectionAllowed=None, dragToPage=True, dragToData=True, dragOff=True, showAll=True, insertBlankRow=None, serverField=None, insertPageBreak=None, autoShow=None, topAutoShow=True, hideNewItems=None, measureFilter=None, includeNewItemsInFilter=None, itemPageCount=10, sortType="manual", dataSourceSort=None, nonAutoSortDefault=None, rankBy=None, defaultSubtotal=True, sumSubtotal=None, countASubtotal=None, avgSubtotal=None, maxSubtotal=None, minSubtotal=None, productSubtotal=None, countSubtotal=None, stdDevSubtotal=None, stdDevPSubtotal=None, varSubtotal=None, varPSubtotal=None, showPropCell=None, showPropTip=None, showPropAsCaption=None, defaultAttributeDrillState=None, extLst=None, ): self.items = items self.autoSortScope = autoSortScope self.name = name self.axis = axis self.dataField = dataField self.subtotalCaption = subtotalCaption self.showDropDowns = showDropDowns self.hiddenLevel = hiddenLevel self.uniqueMemberProperty = uniqueMemberProperty self.compact = compact self.allDrilled = allDrilled self.numFmtId = numFmtId self.outline = outline self.subtotalTop = subtotalTop self.dragToRow = dragToRow self.dragToCol = dragToCol self.multipleItemSelectionAllowed = multipleItemSelectionAllowed self.dragToPage = dragToPage self.dragToData = dragToData self.dragOff = dragOff self.showAll = showAll self.insertBlankRow = insertBlankRow self.serverField = serverField self.insertPageBreak = insertPageBreak self.autoShow = autoShow self.topAutoShow = topAutoShow self.hideNewItems = hideNewItems self.measureFilter = measureFilter self.includeNewItemsInFilter = includeNewItemsInFilter self.itemPageCount = itemPageCount self.sortType = sortType self.dataSourceSort = dataSourceSort self.nonAutoSortDefault = nonAutoSortDefault self.rankBy = rankBy self.defaultSubtotal = defaultSubtotal self.sumSubtotal = sumSubtotal self.countASubtotal = countASubtotal self.avgSubtotal = avgSubtotal self.maxSubtotal = maxSubtotal self.minSubtotal = minSubtotal self.productSubtotal = productSubtotal self.countSubtotal = countSubtotal self.stdDevSubtotal = stdDevSubtotal self.stdDevPSubtotal = stdDevPSubtotal self.varSubtotal = varSubtotal self.varPSubtotal = varPSubtotal self.showPropCell = showPropCell self.showPropTip = showPropTip self.showPropAsCaption = showPropAsCaption self.defaultAttributeDrillState = defaultAttributeDrillState
class ChartBase(Serialisable): """ Base class for all charts """ legend = Typed(expected_type=Legend, allow_none=True) layout = Typed(expected_type=Layout, allow_none=True) _series_type = "" ser = () series = Alias('ser') title = TitleDescriptor() anchor = "E15" # default anchor position width = 15 # in cm, approx 5 rows height = 7.5 # in cm, approx 14 rows _id = 1 _path = "/xl/charts/chart{0}.xml" style = Integer(allow_none=True) mime_type = "application/vnd.openxmlformats-officedocument.drawingml.chart+xml" graphical_properties = Typed(expected_type=GraphicalProperties, allow_none=True) __elements__ = () def __init__(self, **kw): self._charts = [self] self.title = None self.layout = None self.legend = Legend() self.graphical_properties = None self.style = None self.plot_area = PlotArea() super(ChartBase, self).__init__(**kw) def __hash__(self): """ Just need to check for identity """ return id(self) def __iadd__(self, other): """ Combine the chart with another one """ if not isinstance(other, ChartBase): raise TypeError("Only other charts can be added") self._charts.append(other) return self def to_tree(self, tagname=None, idx=None): if self.ser is not None: for s in self.ser: s.__elements__ = attribute_mapping[self._series_type] return super(ChartBase, self).to_tree(tagname, idx) def _write(self): from .chartspace import ChartSpace, ChartContainer self.plot_area = PlotArea() self.plot_area.layout = self.layout self.plot_area.graphical_properties = self.graphical_properties idx_base = 0 for chart in self._charts: chart.idx_base = idx_base self.plot_area._charts.append(chart) idx_base += len(chart.series) axIds = [] for axId in ("x_axis", "y_axis", 'z_axis'): for chart in self._charts: axis = getattr(chart, axId, None) if axis is None: continue if axis.axId not in axIds: ax = getattr(self.plot_area, axis.tagname) ax.append(axis) axIds.append(axis.axId) container = ChartContainer(plotArea=self.plot_area, legend=self.legend, title=self.title) if isinstance(chart, _3DBase): container.view3D = chart.view3D container.floor = chart.floor container.sideWall = chart.sideWall container.backWall = chart.backWall cs = ChartSpace(chart=container) cs.style = self.style tree = cs.to_tree() tree.set("xmlns", CHART_NS) return tree @property def axId(self): x = getattr(self, "x_axis", None) y = getattr(self, "y_axis", None) z = getattr(self, "z_axis", None) ids = [AxId(axis.axId) for axis in (x, y, z) if axis] return ids def set_categories(self, labels): """ Set the categories / x-axis values """ if not isinstance(labels, Reference): labels = Reference(range_string=labels) for s in self.ser: s.cat = AxDataSource(numRef=NumRef(f=labels)) def add_data(self, data, from_rows=False, titles_from_data=False): """ Add a range of data in a single pass. The default is to treat each column as a data series. """ if not isinstance(data, Reference): data = Reference(range_string=data) if from_rows: values = data.rows else: values = data.cols for v in values: range_string = u"{0}!{1}:{2}".format(data.sheetname, v[0], v[-1]) series = SeriesFactory(range_string, title_from_data=titles_from_data) self.ser.append(series) def append(self, value): """Append a data series to the chart""" l = self.series[:] l.append(value) self.series = l @property def path(self): return self._path.format(self._id)
class PivotFilter(Serialisable): tagname = "filter" fld = Integer() mpFld = Integer(allow_none=True) type = Set(values=([ 'unknown', 'count', 'percent', 'sum', 'captionEqual', 'captionNotEqual', 'captionBeginsWith', 'captionNotBeginsWith', 'captionEndsWith', 'captionNotEndsWith', 'captionContains', 'captionNotContains', 'captionGreaterThan', 'captionGreaterThanOrEqual', 'captionLessThan', 'captionLessThanOrEqual', 'captionBetween', 'captionNotBetween', 'valueEqual', 'valueNotEqual', 'valueGreaterThan', 'valueGreaterThanOrEqual', 'valueLessThan', 'valueLessThanOrEqual', 'valueBetween', 'valueNotBetween', 'dateEqual', 'dateNotEqual', 'dateOlderThan', 'dateOlderThanOrEqual', 'dateNewerThan', 'dateNewerThanOrEqual', 'dateBetween', 'dateNotBetween', 'tomorrow', 'today', 'yesterday', 'nextWeek', 'thisWeek', 'lastWeek', 'nextMonth', 'thisMonth', 'lastMonth', 'nextQuarter', 'thisQuarter', 'lastQuarter', 'nextYear', 'thisYear', 'lastYear', 'yearToDate', 'Q1', 'Q2', 'Q3', 'Q4', 'M1', 'M2', 'M3', 'M4', 'M5', 'M6', 'M7', 'M8', 'M9', 'M10', 'M11', 'M12' ])) evalOrder = Integer(allow_none=True) id = Integer() iMeasureHier = Integer(allow_none=True) iMeasureFld = Integer(allow_none=True) name = String(allow_none=True) description = String(allow_none=True) stringValue1 = String(allow_none=True) stringValue2 = String(allow_none=True) autoFilter = Typed(expected_type=AutoFilter, ) extLst = Typed(expected_type=ExtensionList, allow_none=True) __elements__ = ('autoFilter', ) def __init__( self, fld=None, mpFld=None, type=None, evalOrder=None, id=None, iMeasureHier=None, iMeasureFld=None, name=None, description=None, stringValue1=None, stringValue2=None, autoFilter=None, extLst=None, ): self.fld = fld self.mpFld = mpFld self.type = type self.evalOrder = evalOrder self.id = id self.iMeasureHier = iMeasureHier self.iMeasureFld = iMeasureFld self.name = name self.description = description self.stringValue1 = stringValue1 self.stringValue2 = stringValue2 self.autoFilter = autoFilter
class NamedStyle(Strict): """ Named and editable styles """ font = Typed(expected_type=Font) fill = Typed(expected_type=Fill) border = Typed(expected_type=Border) alignment = Typed(expected_type=Alignment) number_format = NumberFormatDescriptor() protection = Typed(expected_type=Protection) builtinId = Integer(allow_none=True) hidden = Bool(allow_none=True) __fields__ = ("name", "font", "fill", "border", "number_format", "alignment", "protection") def __init__(self, name="Normal", font=Font(), fill=PatternFill(), border=Border(), alignment=Alignment(), number_format=None, protection=Protection(), builtinId=0, hidden=False, ): self.name = name self.font = font self.fill = fill self.border = border self.alignment = alignment self.number_format = number_format self.protection = protection self.builtinId = builtinId self.hidden = hidden def _make_key(self): """Use a tuple of fields as the basis for a key""" self._key = hash(tuple(getattr(self, x) for x in self.__fields__)) def __hash__(self): if not hasattr(self, '_key'): self._make_key() return self._key def __eq__(self, other): if isinstance(other, self.__class__): if not hasattr(self, '_key'): self._make_key() if not hasattr(other, '_key'): other._make_key() return self._key == other._key def __ne__(self, other): return not self == other def __repr__(self): pieces = [] for k in self.__fields__: value = getattr(self, k) pieces.append('%s=%s' % (k, repr(value))) return '%s(%s)' % (self.__class__.__name__, ', '.join(pieces)) def __iter__(self): for key in ('name', 'builtinId', 'hidden', 'xfId'): value = getattr(self, key, None) if value is not None: yield key, safe_string(value)