about summary refs log tree commit diff
path: root/.venv/lib/python3.12/site-packages/xlsxwriter/styles.py
diff options
context:
space:
mode:
authorS. Solomon Darnell2025-03-28 21:52:21 -0500
committerS. Solomon Darnell2025-03-28 21:52:21 -0500
commit4a52a71956a8d46fcb7294ac71734504bb09bcc2 (patch)
treeee3dc5af3b6313e921cd920906356f5d4febc4ed /.venv/lib/python3.12/site-packages/xlsxwriter/styles.py
parentcc961e04ba734dd72309fb548a2f97d67d578813 (diff)
downloadgn-ai-master.tar.gz
two version of R2R are here HEAD master
Diffstat (limited to '.venv/lib/python3.12/site-packages/xlsxwriter/styles.py')
-rw-r--r--.venv/lib/python3.12/site-packages/xlsxwriter/styles.py803
1 files changed, 803 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/xlsxwriter/styles.py b/.venv/lib/python3.12/site-packages/xlsxwriter/styles.py
new file mode 100644
index 00000000..a14035a9
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/xlsxwriter/styles.py
@@ -0,0 +1,803 @@
+###############################################################################
+#
+# Styles - A class for writing the Excel XLSX Worksheet file.
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2013-2025, John McNamara, jmcnamara@cpan.org
+#
+
+# Package imports.
+from . import xmlwriter
+
+
+class Styles(xmlwriter.XMLwriter):
+    """
+    A class for writing the Excel XLSX Styles file.
+
+
+    """
+
+    ###########################################################################
+    #
+    # Public API.
+    #
+    ###########################################################################
+
+    def __init__(self):
+        """
+        Constructor.
+
+        """
+
+        super().__init__()
+
+        self.xf_formats = []
+        self.palette = []
+        self.font_count = 0
+        self.num_formats = []
+        self.border_count = 0
+        self.fill_count = 0
+        self.custom_colors = []
+        self.dxf_formats = []
+        self.has_hyperlink = False
+        self.hyperlink_font_id = 0
+        self.has_comments = False
+
+    ###########################################################################
+    #
+    # Private API.
+    #
+    ###########################################################################
+
+    def _assemble_xml_file(self):
+        # Assemble and write the XML file.
+
+        # Write the XML declaration.
+        self._xml_declaration()
+
+        # Add the style sheet.
+        self._write_style_sheet()
+
+        # Write the number formats.
+        self._write_num_fmts()
+
+        # Write the fonts.
+        self._write_fonts()
+
+        # Write the fills.
+        self._write_fills()
+
+        # Write the borders element.
+        self._write_borders()
+
+        # Write the cellStyleXfs element.
+        self._write_cell_style_xfs()
+
+        # Write the cellXfs element.
+        self._write_cell_xfs()
+
+        # Write the cellStyles element.
+        self._write_cell_styles()
+
+        # Write the dxfs element.
+        self._write_dxfs()
+
+        # Write the tableStyles element.
+        self._write_table_styles()
+
+        # Write the colors element.
+        self._write_colors()
+
+        # Close the style sheet tag.
+        self._xml_end_tag("styleSheet")
+
+        # Close the file.
+        self._xml_close()
+
+    def _set_style_properties(self, properties):
+        # Pass in the Format objects and other properties used in the styles.
+
+        self.xf_formats = properties[0]
+        self.palette = properties[1]
+        self.font_count = properties[2]
+        self.num_formats = properties[3]
+        self.border_count = properties[4]
+        self.fill_count = properties[5]
+        self.custom_colors = properties[6]
+        self.dxf_formats = properties[7]
+        self.has_comments = properties[8]
+
+    def _get_palette_color(self, color):
+        # Special handling for automatic color.
+        if color == "Automatic":
+            return color
+
+        # Convert the RGB color.
+        if color[0] == "#":
+            color = color[1:]
+
+        return "FF" + color.upper()
+
+    ###########################################################################
+    #
+    # XML methods.
+    #
+    ###########################################################################
+
+    def _write_style_sheet(self):
+        # Write the <styleSheet> element.
+        xmlns = "http://schemas.openxmlformats.org/spreadsheetml/2006/main"
+
+        attributes = [("xmlns", xmlns)]
+        self._xml_start_tag("styleSheet", attributes)
+
+    def _write_num_fmts(self):
+        # Write the <numFmts> element.
+        if not self.num_formats:
+            return
+
+        attributes = [("count", len(self.num_formats))]
+        self._xml_start_tag("numFmts", attributes)
+
+        # Write the numFmts elements.
+        for index, num_format in enumerate(self.num_formats, 164):
+            self._write_num_fmt(index, num_format)
+
+        self._xml_end_tag("numFmts")
+
+    def _write_num_fmt(self, num_fmt_id, format_code):
+        # Write the <numFmt> element.
+        format_codes = {
+            0: "General",
+            1: "0",
+            2: "0.00",
+            3: "#,##0",
+            4: "#,##0.00",
+            5: "($#,##0_);($#,##0)",
+            6: "($#,##0_);[Red]($#,##0)",
+            7: "($#,##0.00_);($#,##0.00)",
+            8: "($#,##0.00_);[Red]($#,##0.00)",
+            9: "0%",
+            10: "0.00%",
+            11: "0.00E+00",
+            12: "# ?/?",
+            13: "# ??/??",
+            14: "m/d/yy",
+            15: "d-mmm-yy",
+            16: "d-mmm",
+            17: "mmm-yy",
+            18: "h:mm AM/PM",
+            19: "h:mm:ss AM/PM",
+            20: "h:mm",
+            21: "h:mm:ss",
+            22: "m/d/yy h:mm",
+            37: "(#,##0_);(#,##0)",
+            38: "(#,##0_);[Red](#,##0)",
+            39: "(#,##0.00_);(#,##0.00)",
+            40: "(#,##0.00_);[Red](#,##0.00)",
+            41: '_(* #,##0_);_(* (#,##0);_(* "-"_);_(_)',
+            42: '_($* #,##0_);_($* (#,##0);_($* "-"_);_(_)',
+            43: '_(* #,##0.00_);_(* (#,##0.00);_(* "-"??_);_(_)',
+            44: '_($* #,##0.00_);_($* (#,##0.00);_($* "-"??_);_(_)',
+            45: "mm:ss",
+            46: "[h]:mm:ss",
+            47: "mm:ss.0",
+            48: "##0.0E+0",
+            49: "@",
+        }
+
+        # Set the format code for built-in number formats.
+        if num_fmt_id < 164:
+            format_code = format_codes.get(num_fmt_id, "General")
+
+        attributes = [
+            ("numFmtId", num_fmt_id),
+            ("formatCode", format_code),
+        ]
+
+        self._xml_empty_tag("numFmt", attributes)
+
+    def _write_fonts(self):
+        # Write the <fonts> element.
+        if self.has_comments:
+            # Add extra font for comments.
+            attributes = [("count", self.font_count + 1)]
+        else:
+            attributes = [("count", self.font_count)]
+
+        self._xml_start_tag("fonts", attributes)
+
+        # Write the font elements for xf_format objects that have them.
+        for xf_format in self.xf_formats:
+            if xf_format.has_font:
+                self._write_font(xf_format)
+
+        if self.has_comments:
+            self._write_comment_font()
+
+        self._xml_end_tag("fonts")
+
+    def _write_font(self, xf_format, is_dxf_format=False):
+        # Write the <font> element.
+        self._xml_start_tag("font")
+
+        # The condense and extend elements are mainly used in dxf formats.
+        if xf_format.font_condense:
+            self._write_condense()
+
+        if xf_format.font_extend:
+            self._write_extend()
+
+        if xf_format.bold:
+            self._xml_empty_tag("b")
+
+        if xf_format.italic:
+            self._xml_empty_tag("i")
+
+        if xf_format.font_strikeout:
+            self._xml_empty_tag("strike")
+
+        if xf_format.font_outline:
+            self._xml_empty_tag("outline")
+
+        if xf_format.font_shadow:
+            self._xml_empty_tag("shadow")
+
+        # Handle the underline variants.
+        if xf_format.underline:
+            self._write_underline(xf_format.underline)
+
+        if xf_format.font_script == 1:
+            self._write_vert_align("superscript")
+
+        if xf_format.font_script == 2:
+            self._write_vert_align("subscript")
+
+        if not is_dxf_format:
+            self._xml_empty_tag("sz", [("val", xf_format.font_size)])
+
+        if xf_format.theme == -1:
+            # Ignore for excel2003_style.
+            pass
+        elif xf_format.theme:
+            self._write_color("theme", xf_format.theme)
+        elif xf_format.color_indexed:
+            self._write_color("indexed", xf_format.color_indexed)
+        elif xf_format.font_color:
+            color = self._get_palette_color(xf_format.font_color)
+            if color != "Automatic":
+                self._write_color("rgb", color)
+        elif not is_dxf_format:
+            self._write_color("theme", 1)
+
+        if not is_dxf_format:
+            self._xml_empty_tag("name", [("val", xf_format.font_name)])
+
+            if xf_format.font_family:
+                self._xml_empty_tag("family", [("val", xf_format.font_family)])
+
+            if xf_format.font_charset:
+                self._xml_empty_tag("charset", [("val", xf_format.font_charset)])
+
+            if xf_format.font_name == "Calibri" and not xf_format.hyperlink:
+                self._xml_empty_tag("scheme", [("val", xf_format.font_scheme)])
+
+            if xf_format.hyperlink:
+                self.has_hyperlink = True
+                if self.hyperlink_font_id == 0:
+                    self.hyperlink_font_id = xf_format.font_index
+
+        self._xml_end_tag("font")
+
+    def _write_comment_font(self):
+        # Write the <font> element for comments.
+        self._xml_start_tag("font")
+
+        self._xml_empty_tag("sz", [("val", 8)])
+        self._write_color("indexed", 81)
+        self._xml_empty_tag("name", [("val", "Tahoma")])
+        self._xml_empty_tag("family", [("val", 2)])
+
+        self._xml_end_tag("font")
+
+    def _write_underline(self, underline):
+        # Write the underline font element.
+
+        if underline == 2:
+            attributes = [("val", "double")]
+        elif underline == 33:
+            attributes = [("val", "singleAccounting")]
+        elif underline == 34:
+            attributes = [("val", "doubleAccounting")]
+        else:
+            # Default to single underline.
+            attributes = []
+
+        self._xml_empty_tag("u", attributes)
+
+    def _write_vert_align(self, val):
+        # Write the <vertAlign> font sub-element.
+        attributes = [("val", val)]
+
+        self._xml_empty_tag("vertAlign", attributes)
+
+    def _write_color(self, name, value):
+        # Write the <color> element.
+        attributes = [(name, value)]
+
+        self._xml_empty_tag("color", attributes)
+
+    def _write_fills(self):
+        # Write the <fills> element.
+        attributes = [("count", self.fill_count)]
+
+        self._xml_start_tag("fills", attributes)
+
+        # Write the default fill element.
+        self._write_default_fill("none")
+        self._write_default_fill("gray125")
+
+        # Write the fill elements for xf_format objects that have them.
+        for xf_format in self.xf_formats:
+            if xf_format.has_fill:
+                self._write_fill(xf_format)
+
+        self._xml_end_tag("fills")
+
+    def _write_default_fill(self, pattern_type):
+        # Write the <fill> element for the default fills.
+        self._xml_start_tag("fill")
+        self._xml_empty_tag("patternFill", [("patternType", pattern_type)])
+        self._xml_end_tag("fill")
+
+    def _write_fill(self, xf_format, is_dxf_format=False):
+        # Write the <fill> element.
+        pattern = xf_format.pattern
+        bg_color = xf_format.bg_color
+        fg_color = xf_format.fg_color
+
+        # Colors for dxf formats are handled differently from normal formats
+        # since the normal xf_format reverses the meaning of BG and FG for
+        # solid fills.
+        if is_dxf_format:
+            bg_color = xf_format.dxf_bg_color
+            fg_color = xf_format.dxf_fg_color
+
+        patterns = (
+            "none",
+            "solid",
+            "mediumGray",
+            "darkGray",
+            "lightGray",
+            "darkHorizontal",
+            "darkVertical",
+            "darkDown",
+            "darkUp",
+            "darkGrid",
+            "darkTrellis",
+            "lightHorizontal",
+            "lightVertical",
+            "lightDown",
+            "lightUp",
+            "lightGrid",
+            "lightTrellis",
+            "gray125",
+            "gray0625",
+        )
+
+        # Special handling for pattern only case.
+        if not fg_color and not bg_color and patterns[pattern]:
+            self._write_default_fill(patterns[pattern])
+            return
+
+        self._xml_start_tag("fill")
+
+        # The "none" pattern is handled differently for dxf formats.
+        if is_dxf_format and pattern <= 1:
+            self._xml_start_tag("patternFill")
+        else:
+            self._xml_start_tag("patternFill", [("patternType", patterns[pattern])])
+
+        if fg_color:
+            fg_color = self._get_palette_color(fg_color)
+            if fg_color != "Automatic":
+                self._xml_empty_tag("fgColor", [("rgb", fg_color)])
+
+        if bg_color:
+            bg_color = self._get_palette_color(bg_color)
+            if bg_color != "Automatic":
+                self._xml_empty_tag("bgColor", [("rgb", bg_color)])
+        else:
+            if not is_dxf_format and pattern <= 1:
+                self._xml_empty_tag("bgColor", [("indexed", 64)])
+
+        self._xml_end_tag("patternFill")
+        self._xml_end_tag("fill")
+
+    def _write_borders(self):
+        # Write the <borders> element.
+        attributes = [("count", self.border_count)]
+
+        self._xml_start_tag("borders", attributes)
+
+        # Write the border elements for xf_format objects that have them.
+        for xf_format in self.xf_formats:
+            if xf_format.has_border:
+                self._write_border(xf_format)
+
+        self._xml_end_tag("borders")
+
+    def _write_border(self, xf_format, is_dxf_format=False):
+        # Write the <border> element.
+        attributes = []
+
+        # Diagonal borders add attributes to the <border> element.
+        if xf_format.diag_type == 1:
+            attributes.append(("diagonalUp", 1))
+        elif xf_format.diag_type == 2:
+            attributes.append(("diagonalDown", 1))
+        elif xf_format.diag_type == 3:
+            attributes.append(("diagonalUp", 1))
+            attributes.append(("diagonalDown", 1))
+
+        # Ensure that a default diag border is set if the diag type is set.
+        if xf_format.diag_type and not xf_format.diag_border:
+            xf_format.diag_border = 1
+
+        # Write the start border tag.
+        self._xml_start_tag("border", attributes)
+
+        # Write the <border> sub elements.
+        self._write_sub_border("left", xf_format.left, xf_format.left_color)
+
+        self._write_sub_border("right", xf_format.right, xf_format.right_color)
+
+        self._write_sub_border("top", xf_format.top, xf_format.top_color)
+
+        self._write_sub_border("bottom", xf_format.bottom, xf_format.bottom_color)
+
+        # Condition DXF formats don't allow diagonal borders.
+        if not is_dxf_format:
+            self._write_sub_border(
+                "diagonal", xf_format.diag_border, xf_format.diag_color
+            )
+
+        if is_dxf_format:
+            self._write_sub_border("vertical", None, None)
+            self._write_sub_border("horizontal", None, None)
+
+        self._xml_end_tag("border")
+
+    def _write_sub_border(self, border_type, style, color):
+        # Write the <border> sub elements such as <right>, <top>, etc.
+        attributes = []
+
+        if not style:
+            self._xml_empty_tag(border_type)
+            return
+
+        border_styles = (
+            "none",
+            "thin",
+            "medium",
+            "dashed",
+            "dotted",
+            "thick",
+            "double",
+            "hair",
+            "mediumDashed",
+            "dashDot",
+            "mediumDashDot",
+            "dashDotDot",
+            "mediumDashDotDot",
+            "slantDashDot",
+        )
+
+        attributes.append(("style", border_styles[style]))
+
+        self._xml_start_tag(border_type, attributes)
+
+        if color and color != "Automatic":
+            color = self._get_palette_color(color)
+            self._xml_empty_tag("color", [("rgb", color)])
+        else:
+            self._xml_empty_tag("color", [("auto", 1)])
+
+        self._xml_end_tag(border_type)
+
+    def _write_cell_style_xfs(self):
+        # Write the <cellStyleXfs> element.
+        count = 1
+
+        if self.has_hyperlink:
+            count = 2
+
+        attributes = [("count", count)]
+
+        self._xml_start_tag("cellStyleXfs", attributes)
+        self._write_style_xf()
+
+        if self.has_hyperlink:
+            self._write_style_xf(True, self.hyperlink_font_id)
+
+        self._xml_end_tag("cellStyleXfs")
+
+    def _write_cell_xfs(self):
+        # Write the <cellXfs> element.
+        formats = self.xf_formats
+
+        # Workaround for when the last xf_format is used for the comment font
+        # and shouldn't be used for cellXfs.
+        last_format = formats[-1]
+        if last_format.font_only:
+            formats.pop()
+
+        attributes = [("count", len(formats))]
+        self._xml_start_tag("cellXfs", attributes)
+
+        # Write the xf elements.
+        for xf_format in formats:
+            self._write_xf(xf_format)
+
+        self._xml_end_tag("cellXfs")
+
+    def _write_style_xf(self, has_hyperlink=False, font_id=0):
+        # Write the style <xf> element.
+        num_fmt_id = 0
+        fill_id = 0
+        border_id = 0
+
+        attributes = [
+            ("numFmtId", num_fmt_id),
+            ("fontId", font_id),
+            ("fillId", fill_id),
+            ("borderId", border_id),
+        ]
+
+        if has_hyperlink:
+            attributes.append(("applyNumberFormat", 0))
+            attributes.append(("applyFill", 0))
+            attributes.append(("applyBorder", 0))
+            attributes.append(("applyAlignment", 0))
+            attributes.append(("applyProtection", 0))
+
+            self._xml_start_tag("xf", attributes)
+            self._xml_empty_tag("alignment", [("vertical", "top")])
+            self._xml_empty_tag("protection", [("locked", 0)])
+            self._xml_end_tag("xf")
+
+        else:
+            self._xml_empty_tag("xf", attributes)
+
+    def _write_xf(self, xf_format):
+        # Write the <xf> element.
+        xf_id = xf_format.xf_id
+        font_id = xf_format.font_index
+        fill_id = xf_format.fill_index
+        border_id = xf_format.border_index
+        num_fmt_id = xf_format.num_format_index
+
+        has_checkbox = xf_format.checkbox
+        has_alignment = False
+        has_protection = False
+
+        attributes = [
+            ("numFmtId", num_fmt_id),
+            ("fontId", font_id),
+            ("fillId", fill_id),
+            ("borderId", border_id),
+            ("xfId", xf_id),
+        ]
+
+        if xf_format.quote_prefix:
+            attributes.append(("quotePrefix", 1))
+
+        if xf_format.num_format_index > 0:
+            attributes.append(("applyNumberFormat", 1))
+
+        # Add applyFont attribute if XF format uses a font element.
+        if xf_format.font_index > 0 and not xf_format.hyperlink:
+            attributes.append(("applyFont", 1))
+
+        # Add applyFill attribute if XF format uses a fill element.
+        if xf_format.fill_index > 0:
+            attributes.append(("applyFill", 1))
+
+        # Add applyBorder attribute if XF format uses a border element.
+        if xf_format.border_index > 0:
+            attributes.append(("applyBorder", 1))
+
+        # Check if XF format has alignment properties set.
+        (apply_align, align) = xf_format._get_align_properties()
+
+        # Check if an alignment sub-element should be written.
+        if apply_align and align:
+            has_alignment = True
+
+        # We can also have applyAlignment without a sub-element.
+        if apply_align or xf_format.hyperlink:
+            attributes.append(("applyAlignment", 1))
+
+        # Check for cell protection properties.
+        protection = xf_format._get_protection_properties()
+
+        if protection or xf_format.hyperlink:
+            attributes.append(("applyProtection", 1))
+
+            if not xf_format.hyperlink:
+                has_protection = True
+
+        # Write XF with sub-elements if required.
+        if has_alignment or has_protection or has_checkbox:
+            self._xml_start_tag("xf", attributes)
+
+            if has_alignment:
+                self._xml_empty_tag("alignment", align)
+
+            if has_protection:
+                self._xml_empty_tag("protection", protection)
+
+            if has_checkbox:
+                self._write_xf_format_extensions()
+
+            self._xml_end_tag("xf")
+        else:
+            self._xml_empty_tag("xf", attributes)
+
+    def _write_cell_styles(self):
+        # Write the <cellStyles> element.
+        count = 1
+
+        if self.has_hyperlink:
+            count = 2
+
+        attributes = [("count", count)]
+
+        self._xml_start_tag("cellStyles", attributes)
+
+        if self.has_hyperlink:
+            self._write_cell_style("Hyperlink", 1, 8)
+
+        self._write_cell_style()
+
+        self._xml_end_tag("cellStyles")
+
+    def _write_cell_style(self, name="Normal", xf_id=0, builtin_id=0):
+        # Write the <cellStyle> element.
+        attributes = [
+            ("name", name),
+            ("xfId", xf_id),
+            ("builtinId", builtin_id),
+        ]
+
+        self._xml_empty_tag("cellStyle", attributes)
+
+    def _write_dxfs(self):
+        # Write the <dxfs> element.
+        formats = self.dxf_formats
+        count = len(formats)
+
+        attributes = [("count", len(formats))]
+
+        if count:
+            self._xml_start_tag("dxfs", attributes)
+
+            # Write the font elements for xf_format objects that have them.
+            for dxf_format in self.dxf_formats:
+                self._xml_start_tag("dxf")
+                if dxf_format.has_dxf_font:
+                    self._write_font(dxf_format, True)
+
+                if dxf_format.num_format_index:
+                    self._write_num_fmt(
+                        dxf_format.num_format_index, dxf_format.num_format
+                    )
+
+                if dxf_format.has_dxf_fill:
+                    self._write_fill(dxf_format, True)
+
+                if dxf_format.has_dxf_border:
+                    self._write_border(dxf_format, True)
+
+                if dxf_format.checkbox:
+                    self._write_dxf_format_extensions()
+
+                self._xml_end_tag("dxf")
+
+            self._xml_end_tag("dxfs")
+        else:
+            self._xml_empty_tag("dxfs", attributes)
+
+    def _write_table_styles(self):
+        # Write the <tableStyles> element.
+        count = 0
+        default_table_style = "TableStyleMedium9"
+        default_pivot_style = "PivotStyleLight16"
+
+        attributes = [
+            ("count", count),
+            ("defaultTableStyle", default_table_style),
+            ("defaultPivotStyle", default_pivot_style),
+        ]
+
+        self._xml_empty_tag("tableStyles", attributes)
+
+    def _write_colors(self):
+        # Write the <colors> element.
+        custom_colors = self.custom_colors
+
+        if not custom_colors:
+            return
+
+        self._xml_start_tag("colors")
+        self._write_mru_colors(custom_colors)
+        self._xml_end_tag("colors")
+
+    def _write_mru_colors(self, custom_colors):
+        # Write the <mruColors> element for the most recently used colors.
+
+        # Write the custom custom_colors in reverse order.
+        custom_colors.reverse()
+
+        # Limit the mruColors to the last 10.
+        if len(custom_colors) > 10:
+            custom_colors = custom_colors[0:10]
+
+        self._xml_start_tag("mruColors")
+
+        # Write the custom custom_colors in reverse order.
+        for color in custom_colors:
+            self._write_color("rgb", color)
+
+        self._xml_end_tag("mruColors")
+
+    def _write_condense(self):
+        # Write the <condense> element.
+        attributes = [("val", 0)]
+
+        self._xml_empty_tag("condense", attributes)
+
+    def _write_extend(self):
+        # Write the <extend> element.
+        attributes = [("val", 0)]
+
+        self._xml_empty_tag("extend", attributes)
+
+    def _write_xf_format_extensions(self):
+        # Write the xfComplement <extLst> elements.
+        schema = "http://schemas.microsoft.com/office/spreadsheetml"
+        attributes = [
+            ("uri", "{C7286773-470A-42A8-94C5-96B5CB345126}"),
+            (
+                "xmlns:xfpb",
+                schema + "/2022/featurepropertybag",
+            ),
+        ]
+
+        self._xml_start_tag("extLst")
+        self._xml_start_tag("ext", attributes)
+
+        self._xml_empty_tag("xfpb:xfComplement", [("i", "0")])
+
+        self._xml_end_tag("ext")
+        self._xml_end_tag("extLst")
+
+    def _write_dxf_format_extensions(self):
+        # Write the DXFComplement <extLst> elements.
+        schema = "http://schemas.microsoft.com/office/spreadsheetml"
+        attributes = [
+            ("uri", "{0417FA29-78FA-4A13-93AC-8FF0FAFDF519}"),
+            (
+                "xmlns:xfpb",
+                schema + "/2022/featurepropertybag",
+            ),
+        ]
+
+        self._xml_start_tag("extLst")
+        self._xml_start_tag("ext", attributes)
+
+        self._xml_empty_tag("xfpb:DXFComplement", [("i", "0")])
+
+        self._xml_end_tag("ext")
+        self._xml_end_tag("extLst")