class CT_IgnoredErrors(BaseOxmlElement): """ Complex type (sml-sheet.xsd) """ ignoredError = OneOrMore('ssml:ignoredError') # Ignored Error extLst = ZeroOrOne('ssml:extLst') # None
class CT_CustomWorkbookViews(BaseOxmlElement): """ Complex type (sml-workbook.xsd) """ customWorkbookView = OneOrMore( 'ssml:customWorkbookView') # Custom Workbook View
class CT_SheetViews(BaseOxmlElement): """ Complex type (sml-sheet.xsd) """ sheetView = OneOrMore('ssml:sheetView') # Worksheet View extLst = ZeroOrOne('ssml:extLst') # Future Feature Data Storage Area
class CT_ExternalReferences(BaseOxmlElement): """ Complex type (sml-workbook.xsd) """ externalReference = OneOrMore( 'ssml:externalReference') # External Reference
class CT_ChartsheetViews(BaseOxmlElement): """ Complex type (sml-sheet.xsd) """ sheetView = OneOrMore('ssml:sheetView') # Chart Sheet View extLst = ZeroOrOne('ssml:extLst') # None
class CT_CellStyles(BaseOxmlElement): """ Complex type (sml-styles.xsd) """ cellStyle = OneOrMore('ssml:cellStyle') # Cell Style count = OptionalAttribute('count', XsdUnsignedInt) # Style Count
class CT_MergeCells(BaseOxmlElement): """ Complex type (sml-sheet.xsd) """ mergeCell = OneOrMore('ssml:mergeCell') # Merged Cell count = OptionalAttribute('count', XsdUnsignedInt) # Count
class CT_CellSmartTags(BaseOxmlElement): """ Complex type (sml-sheet.xsd) """ cellSmartTag = OneOrMore('ssml:cellSmartTag') # Cell Smart Tag r = RequiredAttribute('r', ST_CellRef) # Reference
class CT_CellXfs(BaseOxmlElement): """ Complex type (sml-styles.xsd) """ xf = OneOrMore('ssml:xf') # Format count = OptionalAttribute('count', XsdUnsignedInt) # Format Count
class CT_WebPublishItems(BaseOxmlElement): """ Complex type (sml-sheet.xsd) """ webPublishItem = OneOrMore('ssml:webPublishItem') # Web Publishing Item count = OptionalAttribute('count', XsdUnsignedInt) # Web Publishing Items Count
class CT_WebPublishObjects(BaseOxmlElement): """ Complex type (sml-workbook.xsd) """ webPublishObject = OneOrMore( 'ssml:webPublishObject') # Web Publishing Object count = OptionalAttribute('count', XsdUnsignedInt) # Count
class CT_Scenarios(BaseOxmlElement): """ Complex type (sml-sheet.xsd) """ scenario = OneOrMore('ssml:scenario') # Scenario current = OptionalAttribute('current', XsdUnsignedInt) # Current Scenario show = OptionalAttribute('show', XsdUnsignedInt) # Last Shown Scenario sqref = OptionalAttribute('sqref', ST_Sqref) # Sequence of References
class CT_ConditionalFormatting(BaseOxmlElement): """ Complex type (sml-sheet.xsd) """ cfRule = OneOrMore('ssml:cfRule') # Conditional Formatting Rule extLst = ZeroOrMore('ssml:extLst') # None pivot = OptionalAttribute('pivot', XsdBoolean) # PivotTable Conditional Formatting sqref = OptionalAttribute('sqref', ST_Sqref) # Sequence of Refernces
class CT_Parent(BaseOxmlElement): """ ``<w:parent>`` element, an invented element for use in testing. """ eg_zooChoice = ZeroOrOneChoice((Choice('w:choice'), Choice('w:choice2')), successors=('w:oomChild', 'w:oooChild')) oomChild = OneOrMore('w:oomChild', successors=('w:oooChild', 'w:zomChild', 'w:zooChild')) oooChild = OneAndOnlyOne('w:oooChild') zomChild = ZeroOrMore('w:zomChild', successors=('w:zooChild', )) zooChild = ZeroOrOne('w:zooChild', successors=()) optAttr = OptionalAttribute('w:optAttr', ST_IntegerType) reqAttr = RequiredAttribute('reqAttr', ST_IntegerType)
class CT_Scenario(BaseOxmlElement): """ Complex type (sml-sheet.xsd) """ inputCells = OneOrMore('ssml:inputCells') # Input Cells name = RequiredAttribute('name', ST_Xstring) # Scenario Name locked = OptionalAttribute('locked', XsdBoolean, False) # Scenario Locked hidden = OptionalAttribute('hidden', XsdBoolean, False) # Hidden Scenario count = OptionalAttribute('count', XsdUnsignedInt) # Changing Cell Count user = OptionalAttribute('user', ST_Xstring) # User Name comment = OptionalAttribute('comment', ST_Xstring) # Scenario Comment
class CT_DataValidations(BaseOxmlElement): """ Complex type (sml-sheet.xsd) """ dataValidation = OneOrMore('ssml:dataValidation') # Data Validation disablePrompts = OptionalAttribute('disablePrompts', XsdBoolean, False) # Disable Prompts xWindow = OptionalAttribute( 'xWindow', XsdUnsignedInt) # Top Left Corner (X Coodrinate) yWindow = OptionalAttribute( 'yWindow', XsdUnsignedInt) # Top Left Corner (Y Coordinate) count = OptionalAttribute('count', XsdUnsignedInt) # Data Validation Item Count
class CT_TabStops(BaseOxmlElement): """ ``<w:tabs>`` element, container for a sorted sequence of tab stops. """ tab = OneOrMore('w:tab', successors=()) def insert_tab_in_order(self, pos, align, leader): """ Insert a newly created `w:tab` child element in *pos* order. """ new_tab = self._new_tab() new_tab.pos, new_tab.val, new_tab.leader = pos, align, leader for tab in self.tab_lst: if new_tab.pos < tab.pos: tab.addprevious(new_tab) return new_tab self.append(new_tab) return new_tab
class CT_Tc(BaseOxmlElement): """`w:tc` table cell element""" tcPr = ZeroOrOne('w:tcPr') # bunches of successors, overriding insert p = OneOrMore('w:p') tbl = OneOrMore('w:tbl') @property def bottom(self): """ The row index that marks the bottom extent of the vertical span of this cell. This is one greater than the index of the bottom-most row of the span, similar to how a slice of the cell's rows would be specified. """ if self.vMerge is not None: tc_below = self._tc_below if tc_below is not None and tc_below.vMerge == ST_Merge.CONTINUE: return tc_below.bottom return self._tr_idx + 1 def clear_content(self): """ Remove all content child elements, preserving the ``<w:tcPr>`` element if present. Note that this leaves the ``<w:tc>`` element in an invalid state because it doesn't contain at least one block-level element. It's up to the caller to add a ``<w:p>``child element as the last content element. """ new_children = [] tcPr = self.tcPr if tcPr is not None: new_children.append(tcPr) self[:] = new_children @property def grid_span(self): """ The integer number of columns this cell spans. Determined by ./w:tcPr/w:gridSpan/@val, it defaults to 1. """ tcPr = self.tcPr if tcPr is None: return 1 return tcPr.grid_span @grid_span.setter def grid_span(self, value): tcPr = self.get_or_add_tcPr() tcPr.grid_span = value def iter_block_items(self): """ Generate a reference to each of the block-level content elements in this cell, in the order they appear. """ block_item_tags = (qn('w:p'), qn('w:tbl'), qn('w:sdt')) for child in self: if child.tag in block_item_tags: yield child @property def left(self): """ The grid column index at which this ``<w:tc>`` element appears. """ return self._grid_col def merge(self, other_tc): """ Return the top-left ``<w:tc>`` element of a new span formed by merging the rectangular region defined by using this tc element and *other_tc* as diagonal corners. """ top, left, height, width = self._span_dimensions(other_tc) top_tc = self._tbl.tr_lst[top].tc_at_grid_col(left) top_tc._grow_to(width, height) return top_tc @classmethod def new(cls): """ Return a new ``<w:tc>`` element, containing an empty paragraph as the required EG_BlockLevelElt. """ return parse_xml('<w:tc %s>\n' ' <w:p/>\n' '</w:tc>' % nsdecls('w')) @property def right(self): """ The grid column index that marks the right-side extent of the horizontal span of this cell. This is one greater than the index of the right-most column of the span, similar to how a slice of the cell's columns would be specified. """ return self._grid_col + self.grid_span @property def top(self): """ The top-most row index in the vertical span of this cell. """ if self.vMerge is None or self.vMerge == ST_Merge.RESTART: return self._tr_idx return self._tc_above.top @property def vMerge(self): """ The value of the ./w:tcPr/w:vMerge/@val attribute, or |None| if the w:vMerge element is not present. """ tcPr = self.tcPr if tcPr is None: return None return tcPr.vMerge_val @vMerge.setter def vMerge(self, value): tcPr = self.get_or_add_tcPr() tcPr.vMerge_val = value @property def width(self): """ Return the EMU length value represented in the ``./w:tcPr/w:tcW`` child element or |None| if not present. """ tcPr = self.tcPr if tcPr is None: return None return tcPr.width @width.setter def width(self, value): tcPr = self.get_or_add_tcPr() tcPr.width = value def _add_width_of(self, other_tc): """ Add the width of *other_tc* to this cell. Does nothing if either this tc or *other_tc* does not have a specified width. """ if self.width and other_tc.width: self.width += other_tc.width @property def _grid_col(self): """ The grid column at which this cell begins. """ tr = self._tr idx = tr.tc_lst.index(self) preceding_tcs = tr.tc_lst[:idx] return sum(tc.grid_span for tc in preceding_tcs) def _grow_to(self, width, height, top_tc=None): """ Grow this cell to *width* grid columns and *height* rows by expanding horizontal spans and creating continuation cells to form vertical spans. """ def vMerge_val(top_tc): if top_tc is not self: return ST_Merge.CONTINUE if height == 1: return None return ST_Merge.RESTART top_tc = self if top_tc is None else top_tc self._span_to_width(width, top_tc, vMerge_val(top_tc)) if height > 1: self._tc_below._grow_to(width, height - 1, top_tc) def _insert_tcPr(self, tcPr): """ ``tcPr`` has a bunch of successors, but it comes first if it appears, so just overriding and using insert(0, ...) rather than spelling out successors. """ self.insert(0, tcPr) return tcPr @property def _is_empty(self): """ True if this cell contains only a single empty ``<w:p>`` element. """ block_items = list(self.iter_block_items()) if len(block_items) > 1: return False p = block_items[0] # cell must include at least one <w:p> element if len(p.r_lst) == 0: return True return False def _move_content_to(self, other_tc): """ Append the content of this cell to *other_tc*, leaving this cell with a single empty ``<w:p>`` element. """ if other_tc is self: return if self._is_empty: return other_tc._remove_trailing_empty_p() # appending moves each element from self to other_tc for block_element in self.iter_block_items(): other_tc.append(block_element) # add back the required minimum single empty <w:p> element self.append(self._new_p()) def _new_tbl(self): return CT_Tbl.new() @property def _next_tc(self): """ The `w:tc` element immediately following this one in this row, or |None| if this is the last `w:tc` element in the row. """ following_tcs = self.xpath('./following-sibling::w:tc') return following_tcs[0] if following_tcs else None def _remove(self): """ Remove this `w:tc` element from the XML tree. """ self.getparent().remove(self) def _remove_trailing_empty_p(self): """ Remove the last content element from this cell if it is an empty ``<w:p>`` element. """ block_items = list(self.iter_block_items()) last_content_elm = block_items[-1] if last_content_elm.tag != qn('w:p'): return p = last_content_elm if len(p.r_lst) > 0: return self.remove(p) def _span_dimensions(self, other_tc): """ Return a (top, left, height, width) 4-tuple specifying the extents of the merged cell formed by using this tc and *other_tc* as opposite corner extents. """ def raise_on_inverted_L(a, b): if a.top == b.top and a.bottom != b.bottom: raise InvalidSpanError('requested span not rectangular') if a.left == b.left and a.right != b.right: raise InvalidSpanError('requested span not rectangular') def raise_on_tee_shaped(a, b): top_most, other = (a, b) if a.top < b.top else (b, a) if top_most.top < other.top and top_most.bottom > other.bottom: raise InvalidSpanError('requested span not rectangular') left_most, other = (a, b) if a.left < b.left else (b, a) if left_most.left < other.left and left_most.right > other.right: raise InvalidSpanError('requested span not rectangular') raise_on_inverted_L(self, other_tc) raise_on_tee_shaped(self, other_tc) top = min(self.top, other_tc.top) left = min(self.left, other_tc.left) bottom = max(self.bottom, other_tc.bottom) right = max(self.right, other_tc.right) return top, left, bottom - top, right - left def _span_to_width(self, grid_width, top_tc, vMerge): """ Incorporate and then remove `w:tc` elements to the right of this one until this cell spans *grid_width*. Raises |ValueError| if *grid_width* cannot be exactly achieved, such as when a merged cell would drive the span width greater than *grid_width* or if not enough grid columns are available to make this cell that wide. All content from incorporated cells is appended to *top_tc*. The val attribute of the vMerge element on the single remaining cell is set to *vMerge*. If *vMerge* is |None|, the vMerge element is removed if present. """ self._move_content_to(top_tc) while self.grid_span < grid_width: self._swallow_next_tc(grid_width, top_tc) self.vMerge = vMerge def _swallow_next_tc(self, grid_width, top_tc): """ Extend the horizontal span of this `w:tc` element to incorporate the following `w:tc` element in the row and then delete that following `w:tc` element. Any content in the following `w:tc` element is appended to the content of *top_tc*. The width of the following `w:tc` element is added to this one, if present. Raises |InvalidSpanError| if the width of the resulting cell is greater than *grid_width* or if there is no next `<w:tc>` element in the row. """ def raise_on_invalid_swallow(next_tc): if next_tc is None: raise InvalidSpanError('not enough grid columns') if self.grid_span + next_tc.grid_span > grid_width: raise InvalidSpanError('span is not rectangular') next_tc = self._next_tc raise_on_invalid_swallow(next_tc) next_tc._move_content_to(top_tc) self._add_width_of(next_tc) self.grid_span += next_tc.grid_span next_tc._remove() @property def _tbl(self): """ The tbl element this tc element appears in. """ return self.xpath('./ancestor::w:tbl[position()=1]')[0] @property def _tc_above(self): """ The `w:tc` element immediately above this one in its grid column. """ return self._tr_above.tc_at_grid_col(self._grid_col) @property def _tc_below(self): """ The tc element immediately below this one in its grid column. """ tr_below = self._tr_below if tr_below is None: return None return tr_below.tc_at_grid_col(self._grid_col) @property def _tr(self): """ The tr element this tc element appears in. """ return self.xpath('./ancestor::w:tr[position()=1]')[0] @property def _tr_above(self): """ The tr element prior in sequence to the tr this cell appears in. Raises |ValueError| if called on a cell in the top-most row. """ tr_lst = self._tbl.tr_lst tr_idx = tr_lst.index(self._tr) if tr_idx == 0: raise ValueError('no tr above topmost tr') return tr_lst[tr_idx - 1] @property def _tr_below(self): """ The tr element next in sequence after the tr this cell appears in, or |None| if this cell appears in the last row. """ tr_lst = self._tbl.tr_lst tr_idx = tr_lst.index(self._tr) try: return tr_lst[tr_idx + 1] except IndexError: return None @property def _tr_idx(self): """ The row index of the tr element this tc element appears in. """ return self._tbl.tr_lst.index(self._tr)
class CT_BookViews(BaseOxmlElement): """ Complex type (sml-workbook.xsd) """ workbookView = OneOrMore('ssml:workbookView') # Workbook View
class CT_SmartTags(BaseOxmlElement): """ Complex type (sml-sheet.xsd) """ cellSmartTags = OneOrMore('ssml:cellSmartTags') # Cell Smart Tags
class CT_PivotCaches(BaseOxmlElement): """ Complex type (sml-workbook.xsd) """ pivotCache = OneOrMore('ssml:pivotCache') # PivotCache
class CT_CustomSheetViews(BaseOxmlElement): """ Complex type (sml-sheet.xsd) """ customSheetView = OneOrMore('ssml:customSheetView') # Custom Sheet View
class CT_Sheets(BaseOxmlElement): """ Complex type (sml-workbook.xsd) """ sheet = OneOrMore('ssml:sheet') # Sheet Information
class CT_Hyperlinks(BaseOxmlElement): """ Complex type (sml-sheet.xsd) """ hyperlink = OneOrMore('ssml:hyperlink') # Hyperlink
class CT_OleObjects(BaseOxmlElement): """ Complex type (sml-sheet.xsd) """ oleObject = OneOrMore('ssml:oleObject') # OLE Object
class CT_IndexedColors(BaseOxmlElement): """ Complex type (sml-styles.xsd) """ rgbColor = OneOrMore('ssml:rgbColor') # RGB Color
class CT_Controls(BaseOxmlElement): """ Complex type (sml-sheet.xsd) """ control = OneOrMore('ssml:control') # Embedded Control
class CT_Cols(BaseOxmlElement): """ Complex type (sml-sheet.xsd) """ col = OneOrMore('ssml:col') # Column Width & Formatting
class CT_MRUColors(BaseOxmlElement): """ Complex type (sml-styles.xsd) """ color = OneOrMore('ssml:color') # Color
class CT_ProtectedRanges(BaseOxmlElement): """ Complex type (sml-sheet.xsd) """ protectedRange = OneOrMore('ssml:protectedRange') # Protected Range