2024-12-04 13:35:57 +05:00

1262 lines
40 KiB
Python

# 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)}"