# Source code for openpyxl.pivot.table

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