diff options
author | S. Solomon Darnell | 2025-03-28 21:52:21 -0500 |
---|---|---|
committer | S. Solomon Darnell | 2025-03-28 21:52:21 -0500 |
commit | 4a52a71956a8d46fcb7294ac71734504bb09bcc2 (patch) | |
tree | ee3dc5af3b6313e921cd920906356f5d4febc4ed /.venv/lib/python3.12/site-packages/openpyxl/pivot | |
parent | cc961e04ba734dd72309fb548a2f97d67d578813 (diff) | |
download | gn-ai-master.tar.gz |
Diffstat (limited to '.venv/lib/python3.12/site-packages/openpyxl/pivot')
5 files changed, 2664 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/openpyxl/pivot/__init__.py b/.venv/lib/python3.12/site-packages/openpyxl/pivot/__init__.py new file mode 100644 index 00000000..ab6cdead --- /dev/null +++ b/.venv/lib/python3.12/site-packages/openpyxl/pivot/__init__.py @@ -0,0 +1 @@ +# Copyright (c) 2010-2024 openpyxl diff --git a/.venv/lib/python3.12/site-packages/openpyxl/pivot/cache.py b/.venv/lib/python3.12/site-packages/openpyxl/pivot/cache.py new file mode 100644 index 00000000..7ae2b4dd --- /dev/null +++ b/.venv/lib/python3.12/site-packages/openpyxl/pivot/cache.py @@ -0,0 +1,965 @@ +# Copyright (c) 2010-2024 openpyxl + +from openpyxl.descriptors.serialisable import Serialisable +from openpyxl.descriptors import ( + Typed, + Bool, + Float, + Set, + NoneSet, + String, + Integer, + DateTime, + Sequence, +) + +from openpyxl.descriptors.excel import ( + HexBinary, + ExtensionList, + Relation, +) +from openpyxl.descriptors.nested import NestedInteger +from openpyxl.descriptors.sequence import ( + NestedSequence, + MultiSequence, + MultiSequencePart, +) +from openpyxl.xml.constants import SHEET_MAIN_NS +from openpyxl.xml.functions import tostring +from openpyxl.packaging.relationship import ( + RelationshipList, + Relationship, + get_rels_path +) + +from .table import ( + PivotArea, + Reference, +) +from .fields import ( + Boolean, + Error, + Missing, + Number, + Text, + TupleList, + DateTimeField, +) + +class MeasureDimensionMap(Serialisable): + + tagname = "map" + + measureGroup = Integer(allow_none=True) + dimension = Integer(allow_none=True) + + def __init__(self, + measureGroup=None, + dimension=None, + ): + self.measureGroup = measureGroup + self.dimension = dimension + + +class MeasureGroup(Serialisable): + + tagname = "measureGroup" + + name = String() + caption = String() + + def __init__(self, + name=None, + caption=None, + ): + self.name = name + self.caption = caption + + +class PivotDimension(Serialisable): + + tagname = "dimension" + + measure = Bool() + name = String() + uniqueName = String() + caption = String() + + def __init__(self, + measure=None, + name=None, + uniqueName=None, + caption=None, + ): + self.measure = measure + self.name = name + self.uniqueName = uniqueName + self.caption = caption + + +class CalculatedMember(Serialisable): + + tagname = "calculatedMember" + + name = String() + mdx = String() + memberName = String(allow_none=True) + hierarchy = String(allow_none=True) + parent = String(allow_none=True) + solveOrder = Integer(allow_none=True) + set = Bool() + extLst = Typed(expected_type=ExtensionList, allow_none=True) + + __elements__ = () + + def __init__(self, + name=None, + mdx=None, + memberName=None, + hierarchy=None, + parent=None, + solveOrder=None, + set=None, + extLst=None, + ): + self.name = name + self.mdx = mdx + self.memberName = memberName + self.hierarchy = hierarchy + self.parent = parent + self.solveOrder = solveOrder + self.set = set + #self.extLst = extLst + + +class CalculatedItem(Serialisable): + + tagname = "calculatedItem" + + field = Integer(allow_none=True) + formula = String() + pivotArea = Typed(expected_type=PivotArea, ) + extLst = Typed(expected_type=ExtensionList, allow_none=True) + + __elements__ = ('pivotArea', 'extLst') + + def __init__(self, + field=None, + formula=None, + pivotArea=None, + extLst=None, + ): + self.field = field + self.formula = formula + self.pivotArea = pivotArea + self.extLst = extLst + + +class ServerFormat(Serialisable): + + tagname = "serverFormat" + + culture = String(allow_none=True) + format = String(allow_none=True) + + def __init__(self, + culture=None, + format=None, + ): + self.culture = culture + self.format = format + + +class Query(Serialisable): + + tagname = "query" + + mdx = String() + tpls = Typed(expected_type=TupleList, allow_none=True) + + __elements__ = ('tpls',) + + def __init__(self, + mdx=None, + tpls=None, + ): + self.mdx = mdx + self.tpls = tpls + + +class OLAPSet(Serialisable): + + tagname = "set" + + count = Integer() + maxRank = Integer() + setDefinition = String() + sortType = NoneSet(values=(['ascending', 'descending', 'ascendingAlpha', + 'descendingAlpha', 'ascendingNatural', 'descendingNatural'])) + queryFailed = Bool() + tpls = Typed(expected_type=TupleList, allow_none=True) + sortByTuple = Typed(expected_type=TupleList, allow_none=True) + + __elements__ = ('tpls', 'sortByTuple') + + def __init__(self, + count=None, + maxRank=None, + setDefinition=None, + sortType=None, + queryFailed=None, + tpls=None, + sortByTuple=None, + ): + self.count = count + self.maxRank = maxRank + self.setDefinition = setDefinition + self.sortType = sortType + self.queryFailed = queryFailed + self.tpls = tpls + self.sortByTuple = sortByTuple + + +class PCDSDTCEntries(Serialisable): + # Implements CT_PCDSDTCEntries + + tagname = "entries" + + count = Integer(allow_none=True) + # elements are choice + m = Typed(expected_type=Missing, allow_none=True) + n = Typed(expected_type=Number, allow_none=True) + e = Typed(expected_type=Error, allow_none=True) + s = Typed(expected_type=Text, allow_none=True) + + __elements__ = ('m', 'n', 'e', 's') + + def __init__(self, + count=None, + m=None, + n=None, + e=None, + s=None, + ): + self.count = count + self.m = m + self.n = n + self.e = e + self.s = s + + +class TupleCache(Serialisable): + + tagname = "tupleCache" + + entries = Typed(expected_type=PCDSDTCEntries, allow_none=True) + sets = NestedSequence(expected_type=OLAPSet, count=True) + queryCache = NestedSequence(expected_type=Query, count=True) + serverFormats = NestedSequence(expected_type=ServerFormat, count=True) + extLst = Typed(expected_type=ExtensionList, allow_none=True) + + __elements__ = ('entries', 'sets', 'queryCache', 'serverFormats', 'extLst') + + def __init__(self, + entries=None, + sets=(), + queryCache=(), + serverFormats=(), + extLst=None, + ): + self.entries = entries + self.sets = sets + self.queryCache = queryCache + self.serverFormats = serverFormats + self.extLst = extLst + + +class OLAPKPI(Serialisable): + + tagname = "kpi" + + uniqueName = String() + caption = String(allow_none=True) + displayFolder = String(allow_none=True) + measureGroup = String(allow_none=True) + parent = String(allow_none=True) + value = String() + goal = String(allow_none=True) + status = String(allow_none=True) + trend = String(allow_none=True) + weight = String(allow_none=True) + time = String(allow_none=True) + + def __init__(self, + uniqueName=None, + caption=None, + displayFolder=None, + measureGroup=None, + parent=None, + value=None, + goal=None, + status=None, + trend=None, + weight=None, + time=None, + ): + self.uniqueName = uniqueName + self.caption = caption + self.displayFolder = displayFolder + self.measureGroup = measureGroup + self.parent = parent + self.value = value + self.goal = goal + self.status = status + self.trend = trend + self.weight = weight + self.time = time + + +class GroupMember(Serialisable): + + tagname = "groupMember" + + uniqueName = String() + group = Bool() + + def __init__(self, + uniqueName=None, + group=None, + ): + self.uniqueName = uniqueName + self.group = group + + +class LevelGroup(Serialisable): + + tagname = "group" + + name = String() + uniqueName = String() + caption = String() + uniqueParent = String() + id = Integer() + groupMembers = NestedSequence(expected_type=GroupMember, count=True) + + __elements__ = ('groupMembers',) + + def __init__(self, + name=None, + uniqueName=None, + caption=None, + uniqueParent=None, + id=None, + groupMembers=(), + ): + self.name = name + self.uniqueName = uniqueName + self.caption = caption + self.uniqueParent = uniqueParent + self.id = id + self.groupMembers = groupMembers + + +class GroupLevel(Serialisable): + + tagname = "groupLevel" + + uniqueName = String() + caption = String() + user = Bool() + customRollUp = Bool() + groups = NestedSequence(expected_type=LevelGroup, count=True) + extLst = Typed(expected_type=ExtensionList, allow_none=True) + + __elements__ = ('groups', 'extLst') + + def __init__(self, + uniqueName=None, + caption=None, + user=None, + customRollUp=None, + groups=(), + extLst=None, + ): + self.uniqueName = uniqueName + self.caption = caption + self.user = user + self.customRollUp = customRollUp + self.groups = groups + self.extLst = extLst + + +class FieldUsage(Serialisable): + + tagname = "fieldUsage" + + x = Integer() + + def __init__(self, + x=None, + ): + self.x = x + + +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 = NestedSequence(expected_type=FieldUsage, count=True) + groupLevels = NestedSequence(expected_type=GroupLevel, count=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=(), + groupLevels=(), + 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 GroupItems(Serialisable): + + tagname = "groupItems" + + m = Sequence(expected_type=Missing) + n = Sequence(expected_type=Number) + b = Sequence(expected_type=Boolean) + e = Sequence(expected_type=Error) + s = Sequence(expected_type=Text) + d = Sequence(expected_type=DateTimeField,) + + __elements__ = ('m', 'n', 'b', 'e', 's', 'd') + __attrs__ = ("count", ) + + def __init__(self, + count=None, + m=(), + n=(), + b=(), + e=(), + s=(), + d=(), + ): + self.m = m + self.n = n + self.b = b + self.e = e + self.s = s + self.d = d + + + @property + def count(self): + return len(self.m + self.n + self.b + self.e + self.s + self.d) + + +class RangePr(Serialisable): + + tagname = "rangePr" + + autoStart = Bool(allow_none=True) + autoEnd = Bool(allow_none=True) + groupBy = NoneSet(values=(['range', 'seconds', 'minutes', 'hours', 'days', + 'months', 'quarters', 'years'])) + startNum = Float(allow_none=True) + endNum = Float(allow_none=True) + startDate = DateTime(allow_none=True) + endDate = DateTime(allow_none=True) + groupInterval = Float(allow_none=True) + + def __init__(self, + autoStart=True, + autoEnd=True, + groupBy="range", + startNum=None, + endNum=None, + startDate=None, + endDate=None, + groupInterval=1, + ): + self.autoStart = autoStart + self.autoEnd = autoEnd + self.groupBy = groupBy + self.startNum = startNum + self.endNum = endNum + self.startDate = startDate + self.endDate = endDate + self.groupInterval = groupInterval + + +class FieldGroup(Serialisable): + + tagname = "fieldGroup" + + par = Integer(allow_none=True) + base = Integer(allow_none=True) + rangePr = Typed(expected_type=RangePr, allow_none=True) + discretePr = NestedSequence(expected_type=NestedInteger, count=True) + groupItems = Typed(expected_type=GroupItems, allow_none=True) + + __elements__ = ('rangePr', 'discretePr', 'groupItems') + + def __init__(self, + par=None, + base=None, + rangePr=None, + discretePr=(), + groupItems=None, + ): + self.par = par + self.base = base + self.rangePr = rangePr + self.discretePr = discretePr + self.groupItems = groupItems + + +class SharedItems(Serialisable): + + tagname = "sharedItems" + + _fields = MultiSequence() + m = MultiSequencePart(expected_type=Missing, store="_fields") + n = MultiSequencePart(expected_type=Number, store="_fields") + b = MultiSequencePart(expected_type=Boolean, store="_fields") + e = MultiSequencePart(expected_type=Error, store="_fields") + s = MultiSequencePart(expected_type=Text, store="_fields") + d = MultiSequencePart(expected_type=DateTimeField, store="_fields") + # attributes are optional and must be derived from associated cache records + containsSemiMixedTypes = Bool(allow_none=True) + containsNonDate = Bool(allow_none=True) + containsDate = Bool(allow_none=True) + containsString = Bool(allow_none=True) + containsBlank = Bool(allow_none=True) + containsMixedTypes = Bool(allow_none=True) + containsNumber = Bool(allow_none=True) + containsInteger = Bool(allow_none=True) + minValue = Float(allow_none=True) + maxValue = Float(allow_none=True) + minDate = DateTime(allow_none=True) + maxDate = DateTime(allow_none=True) + longText = Bool(allow_none=True) + + __attrs__ = ('count', 'containsBlank', 'containsDate', 'containsInteger', + 'containsMixedTypes', 'containsNonDate', 'containsNumber', + 'containsSemiMixedTypes', 'containsString', 'minValue', 'maxValue', + 'minDate', 'maxDate', 'longText') + + def __init__(self, + _fields=(), + containsSemiMixedTypes=None, + containsNonDate=None, + containsDate=None, + containsString=None, + containsBlank=None, + containsMixedTypes=None, + containsNumber=None, + containsInteger=None, + minValue=None, + maxValue=None, + minDate=None, + maxDate=None, + count=None, + longText=None, + ): + self._fields = _fields + self.containsBlank = containsBlank + self.containsDate = containsDate + self.containsNonDate = containsNonDate + self.containsString = containsString + self.containsMixedTypes = containsMixedTypes + self.containsSemiMixedTypes = containsSemiMixedTypes + self.containsNumber = containsNumber + self.containsInteger = containsInteger + self.minValue = minValue + self.maxValue = maxValue + self.minDate = minDate + self.maxDate = maxDate + self.longText = longText + + + @property + def count(self): + return len(self._fields) + + +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 RangeSet(Serialisable): + + tagname = "rangeSet" + + i1 = Integer(allow_none=True) + i2 = Integer(allow_none=True) + i3 = Integer(allow_none=True) + i4 = Integer(allow_none=True) + ref = String() + name = String(allow_none=True) + sheet = String(allow_none=True) + + def __init__(self, + i1=None, + i2=None, + i3=None, + i4=None, + ref=None, + name=None, + sheet=None, + ): + self.i1 = i1 + self.i2 = i2 + self.i3 = i3 + self.i4 = i4 + self.ref = ref + self.name = name + self.sheet = sheet + + +class PageItem(Serialisable): + + tagname = "pageItem" + + name = String() + + def __init__(self, + name=None, + ): + self.name = name + + +class Consolidation(Serialisable): + + tagname = "consolidation" + + autoPage = Bool(allow_none=True) + pages = NestedSequence(expected_type=PageItem, count=True) + rangeSets = NestedSequence(expected_type=RangeSet, count=True) + + __elements__ = ('pages', 'rangeSets') + + def __init__(self, + autoPage=None, + pages=(), + rangeSets=(), + ): + self.autoPage = autoPage + self.pages = pages + self.rangeSets = rangeSets + + +class WorksheetSource(Serialisable): + + tagname = "worksheetSource" + + ref = String(allow_none=True) + name = String(allow_none=True) + sheet = String(allow_none=True) + + def __init__(self, + ref=None, + name=None, + sheet=None, + ): + self.ref = ref + self.name = name + self.sheet = sheet + + +class CacheSource(Serialisable): + + tagname = "cacheSource" + + type = Set(values=(['worksheet', 'external', 'consolidation', 'scenario'])) + connectionId = Integer(allow_none=True) + # some elements are choice + worksheetSource = Typed(expected_type=WorksheetSource, allow_none=True) + consolidation = Typed(expected_type=Consolidation, allow_none=True) + extLst = Typed(expected_type=ExtensionList, allow_none=True) + + __elements__ = ('worksheetSource', 'consolidation',) + + def __init__(self, + type=None, + connectionId=None, + worksheetSource=None, + consolidation=None, + extLst=None, + ): + self.type = type + self.connectionId = connectionId + self.worksheetSource = worksheetSource + self.consolidation = consolidation + + +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) + 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=OLAPKPI, count=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.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().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) diff --git a/.venv/lib/python3.12/site-packages/openpyxl/pivot/fields.py b/.venv/lib/python3.12/site-packages/openpyxl/pivot/fields.py new file mode 100644 index 00000000..cd6bcb28 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/openpyxl/pivot/fields.py @@ -0,0 +1,326 @@ +# Copyright (c) 2010-2024 openpyxl + +from openpyxl.descriptors.serialisable import Serialisable +from openpyxl.descriptors import ( + Typed, + DateTime, + Bool, + Float, + String, + Integer, + Sequence, +) +from openpyxl.descriptors.excel import HexBinary + +class Index(Serialisable): + + tagname = "x" + + v = Integer(allow_none=True) + + def __init__(self, + v=0, + ): + self.v = v + + +class Tuple(Serialisable): + + tagname = "tpl" + + fld = Integer(allow_none=True) + hier = Integer(allow_none=True) + item = Integer() + + def __init__(self, + fld=None, + hier=None, + item=None, + ): + self.fld = fld + self.hier = hier + self.item = item + + +class TupleList(Serialisable): + + tagname = "tpls" + + c = Integer(allow_none=True) + tpl = Typed(expected_type=Tuple, ) + + __elements__ = ('tpl',) + + def __init__(self, + c=None, + tpl=None, + ): + self.c = c + self.tpl = tpl + + +class Missing(Serialisable): + + tagname = "m" + + tpls = Sequence(expected_type=TupleList) + x = Sequence(expected_type=Index) + 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=(), + x=(), + 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.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 Number(Serialisable): + + tagname = "n" + + tpls = Sequence(expected_type=TupleList) + x = Sequence(expected_type=Index) + v = Float() + 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=(), + 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 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 Boolean(Serialisable): + + tagname = "b" + + x = Sequence(expected_type=Index) + v = Bool() + u = Bool(allow_none=True) + f = Bool(allow_none=True) + c = String(allow_none=True) + cp = Integer(allow_none=True) + + __elements__ = ('x',) + + def __init__(self, + x=(), + v=None, + u=None, + f=None, + c=None, + cp=None, + ): + self.x = x + self.v = v + self.u = u + self.f = f + self.c = c + self.cp = cp + + +class Text(Serialisable): + + tagname = "s" + + tpls = Sequence(expected_type=TupleList) + 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=(), + 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 DateTimeField(Serialisable): + + tagname = "d" + + x = Sequence(expected_type=Index) + v = DateTime() + u = Bool(allow_none=True) + f = Bool(allow_none=True) + c = String(allow_none=True) + cp = Integer(allow_none=True) + + __elements__ = ('x',) + + def __init__(self, + x=(), + v=None, + u=None, + f=None, + c=None, + cp=None, + ): + self.x = x + self.v = v + self.u = u + self.f = f + self.c = c + self.cp = cp diff --git a/.venv/lib/python3.12/site-packages/openpyxl/pivot/record.py b/.venv/lib/python3.12/site-packages/openpyxl/pivot/record.py new file mode 100644 index 00000000..42603770 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/openpyxl/pivot/record.py @@ -0,0 +1,111 @@ +# Copyright (c) 2010-2024 openpyxl + +from openpyxl.descriptors.serialisable import Serialisable +from openpyxl.descriptors import ( + Typed, + Integer, + Sequence, +) +from openpyxl.descriptors.sequence import ( + MultiSequence, + MultiSequencePart, +) +from openpyxl.descriptors.excel import ExtensionList +from openpyxl.descriptors.nested import ( + NestedInteger, + NestedBool, +) + +from openpyxl.xml.constants import SHEET_MAIN_NS +from openpyxl.xml.functions import tostring + +from .fields import ( + Boolean, + Error, + Missing, + Number, + Text, + TupleList, + DateTimeField, + Index, +) + + +class Record(Serialisable): + + tagname = "r" + + _fields = MultiSequence() + m = MultiSequencePart(expected_type=Missing, store="_fields") + n = MultiSequencePart(expected_type=Number, store="_fields") + b = MultiSequencePart(expected_type=Boolean, store="_fields") + e = MultiSequencePart(expected_type=Error, store="_fields") + s = MultiSequencePart(expected_type=Text, store="_fields") + d = MultiSequencePart(expected_type=DateTimeField, store="_fields") + x = MultiSequencePart(expected_type=Index, store="_fields") + + + def __init__(self, + _fields=(), + m=None, + n=None, + b=None, + e=None, + s=None, + d=None, + x=None, + ): + self._fields = _fields + + +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().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 diff --git a/.venv/lib/python3.12/site-packages/openpyxl/pivot/table.py b/.venv/lib/python3.12/site-packages/openpyxl/pivot/table.py new file mode 100644 index 00000000..cc3548b1 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/openpyxl/pivot/table.py @@ -0,0 +1,1261 @@ +# Copyright (c) 2010-2024 openpyxl + + +from collections import defaultdict +from openpyxl.descriptors.serialisable import Serialisable +from openpyxl.descriptors import ( + Typed, + Integer, + NoneSet, + Set, + Bool, + String, + Bool, + Sequence, +) + +from openpyxl.descriptors.excel import ExtensionList, Relation +from openpyxl.descriptors.sequence import NestedSequence +from openpyxl.xml.constants import SHEET_MAIN_NS +from openpyxl.xml.functions import tostring +from openpyxl.packaging.relationship import ( + RelationshipList, + Relationship, + get_rels_path +) +from .fields import Index + +from openpyxl.worksheet.filters import ( + AutoFilter, +) + + +class HierarchyUsage(Serialisable): + + tagname = "hierarchyUsage" + + hierarchyUsage = Integer() + + def __init__(self, + hierarchyUsage=None, + ): + self.hierarchyUsage = hierarchyUsage + + +class ColHierarchiesUsage(Serialisable): + + tagname = "colHierarchiesUsage" + + colHierarchyUsage = Sequence(expected_type=HierarchyUsage, ) + + __elements__ = ('colHierarchyUsage',) + __attrs__ = ('count', ) + + def __init__(self, + count=None, + colHierarchyUsage=(), + ): + self.colHierarchyUsage = colHierarchyUsage + + + @property + def count(self): + return len(self.colHierarchyUsage) + + +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 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 PivotFilters(Serialisable): + + count = Integer() + filter = Typed(expected_type=PivotFilter, allow_none=True) + + __elements__ = ('filter',) + + def __init__(self, + count=None, + filter=None, + ): + self.filter = filter + + +class PivotTableStyle(Serialisable): + + tagname = "pivotTableStyleInfo" + + name = String(allow_none=True) + showRowHeaders = Bool() + showColHeaders = Bool() + showRowStripes = Bool() + showColStripes = Bool() + showLastColumn = Bool() + + def __init__(self, + name=None, + showRowHeaders=None, + showColHeaders=None, + showRowStripes=None, + showColStripes=None, + showLastColumn=None, + ): + self.name = name + self.showRowHeaders = showRowHeaders + self.showColHeaders = showColHeaders + self.showRowStripes = showRowStripes + self.showColStripes = showColStripes + self.showLastColumn = showLastColumn + + +class MemberList(Serialisable): + + tagname = "members" + + level = Integer(allow_none=True) + member = NestedSequence(expected_type=String, attribute="name") + + __elements__ = ('member',) + + def __init__(self, + count=None, + level=None, + member=(), + ): + self.level = level + self.member = member + + @property + def count(self): + return len(self.member) + + +class MemberProperty(Serialisable): + + tagname = "mps" + + name = String(allow_none=True) + showCell = Bool(allow_none=True) + showTip = Bool(allow_none=True) + showAsCaption = Bool(allow_none=True) + nameLen = Integer(allow_none=True) + pPos = Integer(allow_none=True) + pLen = Integer(allow_none=True) + level = Integer(allow_none=True) + field = Integer() + + def __init__(self, + name=None, + showCell=None, + showTip=None, + showAsCaption=None, + nameLen=None, + pPos=None, + pLen=None, + level=None, + field=None, + ): + self.name = name + self.showCell = showCell + self.showTip = showTip + self.showAsCaption = showAsCaption + self.nameLen = nameLen + self.pPos = pPos + self.pLen = pLen + self.level = level + self.field = field + + +class PivotHierarchy(Serialisable): + + tagname = "pivotHierarchy" + + outline = Bool() + multipleItemSelectionAllowed = Bool() + subtotalTop = Bool() + showInFieldList = Bool() + dragToRow = Bool() + dragToCol = Bool() + dragToPage = Bool() + dragToData = Bool() + dragOff = Bool() + includeNewItemsInFilter = Bool() + caption = String(allow_none=True) + mps = NestedSequence(expected_type=MemberProperty, count=True) + members = Typed(expected_type=MemberList, allow_none=True) + extLst = Typed(expected_type=ExtensionList, allow_none=True) + + __elements__ = ('mps', 'members',) + + def __init__(self, + outline=None, + multipleItemSelectionAllowed=None, + subtotalTop=None, + showInFieldList=None, + dragToRow=None, + dragToCol=None, + dragToPage=None, + dragToData=None, + dragOff=None, + includeNewItemsInFilter=None, + caption=None, + mps=(), + members=None, + extLst=None, + ): + self.outline = outline + self.multipleItemSelectionAllowed = multipleItemSelectionAllowed + self.subtotalTop = subtotalTop + self.showInFieldList = showInFieldList + self.dragToRow = dragToRow + self.dragToCol = dragToCol + self.dragToPage = dragToPage + self.dragToData = dragToData + self.dragOff = dragOff + self.includeNewItemsInFilter = includeNewItemsInFilter + self.caption = caption + self.mps = mps + self.members = members + self.extLst = extLst + + +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 = Sequence(expected_type=Index) + 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=(), + 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 PivotArea(Serialisable): + + tagname = "pivotArea" + + references = NestedSequence(expected_type=Reference, count=True) + extLst = Typed(expected_type=ExtensionList, allow_none=True) + field = Integer(allow_none=True) + type = NoneSet(values=(['normal', 'data', 'all', 'origin', 'button', + 'topEnd', 'topRight'])) + dataOnly = Bool(allow_none=True) + labelOnly = Bool(allow_none=True) + grandRow = Bool(allow_none=True) + grandCol = Bool(allow_none=True) + cacheIndex = Bool(allow_none=True) + outline = Bool(allow_none=True) + offset = String(allow_none=True) + collapsedLevelsAreSubtotals = Bool(allow_none=True) + axis = NoneSet(values=(['axisRow', 'axisCol', 'axisPage', 'axisValues'])) + fieldPosition = Integer(allow_none=True) + + __elements__ = ('references',) + + def __init__(self, + references=(), + extLst=None, + field=None, + type="normal", + dataOnly=True, + labelOnly=None, + grandRow=None, + grandCol=None, + cacheIndex=None, + outline=True, + offset=None, + collapsedLevelsAreSubtotals=None, + axis=None, + fieldPosition=None, + ): + self.references = references + self.extLst = extLst + self.field = field + self.type = type + self.dataOnly = dataOnly + self.labelOnly = labelOnly + self.grandRow = grandRow + self.grandCol = grandCol + self.cacheIndex = cacheIndex + self.outline = outline + self.offset = offset + self.collapsedLevelsAreSubtotals = collapsedLevelsAreSubtotals + self.axis = axis + self.fieldPosition = fieldPosition + + +class ChartFormat(Serialisable): + + tagname = "chartFormat" + + chart = Integer() + format = Integer() + series = Bool() + pivotArea = Typed(expected_type=PivotArea, ) + + __elements__ = ('pivotArea',) + + def __init__(self, + chart=None, + format=None, + series=None, + pivotArea=None, + ): + self.chart = chart + self.format = format + self.series = series + self.pivotArea = pivotArea + + +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="selection", + type=None, + priority=None, + pivotAreas=(), + extLst=None, + ): + self.scope = scope + self.type = type + self.priority = priority + self.pivotAreas = pivotAreas + self.extLst = extLst + + +class ConditionalFormatList(Serialisable): + + tagname = "conditionalFormats" + + conditionalFormat = Sequence(expected_type=ConditionalFormat) + + __attrs__ = ("count",) + + def __init__(self, conditionalFormat=(), count=None): + self.conditionalFormat = conditionalFormat + + + def by_priority(self): + """ + Return a dictionary of format objects keyed by (field id and format property). + This can be used to map the formats to field but also to dedupe to match + worksheet definitions which are grouped by cell range + """ + + fmts = {} + for fmt in self.conditionalFormat: + for area in fmt.pivotAreas: + for ref in area.references: + for field in ref.x: + key = (field.v, fmt.priority) + fmts[key] = fmt + + return fmts + + + def _dedupe(self): + """ + Group formats by field index and priority. + Sorted to match sorting and grouping for corresponding worksheet formats + + The implemtenters notes contain significant deviance from the OOXML + specification, in particular how conditional formats in tables relate to + those defined in corresponding worksheets and how to determine which + format applies to which fields. + + There are some magical interdependencies: + + * Every pivot table fmt must have a worksheet cxf with the same priority. + + * In the reference part the field 4294967294 refers to a data field, the + spec says -2 + + * Data fields are referenced by the 0-index reference.x.v value + + Things are made more complicated by the fact that field items behave + diffently if the parent is a reference or shared item: "In Office if the + parent is the reference element, then restrictions of this value are + defined by reference@field. If the parent is the tables element, then + this value specifies the index into the table tag position in @url." + Yeah, right! + """ + fmts = self.by_priority() + # sort by priority in order, keeping the highest numerical priority, least when + # actually applied + # this is not documented but it's what Excel is happy with + fmts = {field:fmt for (field, priority), fmt in sorted(fmts.items(), reverse=True)} + #fmts = {field:fmt for (field, priority), fmt in fmts.items()} + if fmts: + self.conditionalFormat = list(fmts.values()) + + + @property + def count(self): + return len(self.conditionalFormat) + + + def to_tree(self, tagname=None): + self._dedupe() + return super().to_tree(tagname) + + +class Format(Serialisable): + + tagname = "format" + + action = NoneSet(values=(['blank', 'formatting', 'drill', 'formula'])) + dxfId = Integer(allow_none=True) + pivotArea = Typed(expected_type=PivotArea, ) + extLst = Typed(expected_type=ExtensionList, allow_none=True) + + __elements__ = ('pivotArea',) + + def __init__(self, + action="formatting", + dxfId=None, + pivotArea=None, + extLst=None, + ): + self.action = action + self.dxfId = dxfId + self.pivotArea = pivotArea + self.extLst = extLst + + +class DataField(Serialisable): + + tagname = "dataField" + + name = String(allow_none=True) + fld = Integer() + subtotal = Set(values=(['average', 'count', 'countNums', 'max', 'min', + 'product', 'stdDev', 'stdDevp', 'sum', 'var', 'varp'])) + showDataAs = Set(values=(['normal', 'difference', 'percent', + 'percentDiff', 'runTotal', 'percentOfRow', 'percentOfCol', + 'percentOfTotal', 'index'])) + baseField = Integer() + baseItem = Integer() + numFmtId = Integer(allow_none=True) + extLst = Typed(expected_type=ExtensionList, allow_none=True) + + __elements__ = () + + + def __init__(self, + name=None, + fld=None, + subtotal="sum", + showDataAs="normal", + baseField=-1, + baseItem=1048832, + numFmtId=None, + extLst=None, + ): + self.name = name + self.fld = fld + self.subtotal = subtotal + self.showDataAs = showDataAs + self.baseField = baseField + self.baseItem = baseItem + self.numFmtId = numFmtId + self.extLst = extLst + + +class PageField(Serialisable): + + tagname = "pageField" + + fld = Integer() + item = Integer(allow_none=True) + hier = Integer(allow_none=True) + name = String(allow_none=True) + cap = String(allow_none=True) + extLst = Typed(expected_type=ExtensionList, allow_none=True) + + __elements__ = () + + def __init__(self, + fld=None, + item=None, + hier=None, + name=None, + cap=None, + extLst=None, + ): + self.fld = fld + self.item = item + self.hier = hier + self.name = name + self.cap = cap + self.extLst = extLst + + +class RowColItem(Serialisable): + + tagname = "i" + + t = Set(values=(['data', 'default', 'sum', 'countA', 'avg', 'max', 'min', + 'product', 'count', 'stdDev', 'stdDevP', 'var', 'varP', 'grand', + 'blank'])) + r = Integer() + i = Integer() + x = Sequence(expected_type=Index, attribute="v") + + __elements__ = ('x',) + + def __init__(self, + t="data", + r=0, + i=0, + x=(), + ): + self.t = t + self.r = r + self.i = i + self.x = x + + +class RowColField(Serialisable): + + tagname = "field" + + x = Integer() + + def __init__(self, + x=None, + ): + self.x = x + + +class AutoSortScope(Serialisable): + + pivotArea = Typed(expected_type=PivotArea, ) + + __elements__ = ('pivotArea',) + + def __init__(self, + pivotArea=None, + ): + self.pivotArea = pivotArea + + +class FieldItem(Serialisable): + + tagname = "item" + + n = String(allow_none=True) + t = Set(values=(['data', 'default', 'sum', 'countA', 'avg', 'max', 'min', + 'product', 'count', 'stdDev', 'stdDevP', 'var', 'varP', 'grand', + 'blank'])) + h = Bool(allow_none=True) + s = Bool(allow_none=True) + sd = Bool(allow_none=True) + f = Bool(allow_none=True) + m = Bool(allow_none=True) + c = Bool(allow_none=True) + x = Integer(allow_none=True) + d = Bool(allow_none=True) + e = Bool(allow_none=True) + + def __init__(self, + n=None, + t="data", + h=None, + s=None, + sd=True, + f=None, + m=None, + c=None, + x=None, + d=None, + e=None, + ): + self.n = n + self.t = t + self.h = h + self.s = s + self.sd = sd + self.f = f + self.m = m + self.c = c + self.x = x + self.d = d + self.e = e + + +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 Location(Serialisable): + + tagname = "location" + + ref = String() + firstHeaderRow = Integer() + firstDataRow = Integer() + firstDataCol = Integer() + rowPageCount = Integer(allow_none=True) + colPageCount = Integer(allow_none=True) + + def __init__(self, + ref=None, + firstHeaderRow=None, + firstDataRow=None, + firstDataCol=None, + rowPageCount=None, + colPageCount=None, + ): + self.ref = ref + self.firstHeaderRow = firstHeaderRow + self.firstDataRow = firstDataRow + self.firstDataCol = firstDataCol + self.rowPageCount = rowPageCount + self.colPageCount = colPageCount + + +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 = Typed(expected_type=ConditionalFormatList, allow_none=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=None, + 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.conditionalFormats = None + 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().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) + + + def formatted_fields(self): + """Map fields to associated conditional formats by priority""" + if not self.conditionalFormats: + return {} + fields = defaultdict(list) + for idx, prio in self.conditionalFormats.by_priority(): + name = self.dataFields[idx].name + fields[name].append(prio) + return fields + + + @property + def summary(self): + """ + Provide a simplified summary of the table + """ + + return f"{self.name} {dict(self.location)}" |