def _write_cell_style(self):
     cell_styles = SubElement(self._root, 'cellStyles', {'count': '1'})
     SubElement(cell_styles, 'cellStyle', {
         'name': "Normal",
         'xfId': "0",
         'builtinId': "0"
     })
Beispiel #2
0
def etree_write_cell(xf, worksheet, cell, styled=None):

    value, attributes = _set_attributes(cell, styled)

    el = Element("c", attributes)
    if value is None or value == "":
        xf.write(el)
        return

    if cell.data_type == 'f':
        shared_formula = worksheet.formula_attributes.get(cell.coordinate, {})
        formula = SubElement(el, 'f', shared_formula)
        if value is not None:
            formula.text = value[1:]
            value = None

    if cell.data_type == 's':
        inline_string = SubElement(el, 'is')
        text = SubElement(inline_string, 't')
        text.text = value
        whitespace(text)


    else:
        cell_content = SubElement(el, 'v')
        if value is not None:
            cell_content.text = safe_string(value)

    xf.write(el)
Beispiel #3
0
    def _write_number_formats(self):

        number_format_table = {}

        number_format_list = []
        exceptions_list = []
        num_fmt_id = 165 # start at a greatly higher value as any builtin can go
        num_fmt_offset = 0

        for style in self._style_list:

            if not style.number_format in number_format_list  :
                number_format_list.append(style.number_format)

        for number_format in number_format_list:

            if number_format.is_builtin():
                btin = number_format.builtin_format_id(number_format.format_code)
                number_format_table[number_format] = btin
            else:
                number_format_table[number_format] = num_fmt_id + num_fmt_offset
                num_fmt_offset += 1
                exceptions_list.append(number_format)

        num_fmts = SubElement(self._root, 'numFmts',
            {'count':'%d' % len(exceptions_list)})

        for number_format in exceptions_list :
            SubElement(num_fmts, 'numFmt',
                {'numFmtId':'%d' % number_format_table[number_format],
                'formatCode':'%s' % number_format.format_code})

        return number_format_table
Beispiel #4
0
    def _write_borders(self):
        borders = SubElement(self._root, 'borders')

        # default
        border = SubElement(borders, 'border')
        SubElement(border, 'left')
        SubElement(border, 'right')
        SubElement(border, 'top')
        SubElement(border, 'bottom')
        SubElement(border, 'diagonal')

        # others
        table = {}
        index = 1
        for st in self._style_list:
            if st.borders != DEFAULTS.borders and st.borders not in table:
                table[st.borders] = index
                border = SubElement(borders, 'border')
                # caution: respect this order
                for side in ('left', 'right', 'top', 'bottom', 'diagonal'):
                    obj = getattr(st.borders, side)
                    if obj.border_style is None or obj.border_style == 'none':
                        node = SubElement(border, side)
                    else:
                        node = SubElement(border, side, {'style':obj.border_style})
                        self._unpack_color(node, obj.color.index)

                index += 1

        borders.attrib["count"] = str(index)
        return table
 def _write_fills(self):
     fills = SubElement(self._root, 'fills', {'count': '2'})
     fill = SubElement(fills, 'fill')
     SubElement(fill, 'patternFill', {'patternType': 'none'})
     fill = SubElement(fills, 'fill')
     SubElement(fill, 'patternFill', {'patternType': 'gray125'})
     return fills
Beispiel #6
0
def _write_series_color_node(node, serie):
    """write series color
    """
    # edge color
    line = SubElement(node, '{%s}ln' % DRAWING_NS)
    fill = SubElement(line, '{%s}solidFill' % DRAWING_NS)
    SubElement(fill, '{%s}srgbClr' % DRAWING_NS, {'val': serie.color})
Beispiel #7
0
    def _write_print_settings(self):

        settings = SubElement(self.root, '{%s}printSettings' % CHART_NS)
        SubElement(settings, '{%s}headerFooter' % CHART_NS)
        margins = dict([(k, safe_string(v)) for (k, v) in iteritems(self.chart.print_margins)])
        SubElement(settings, '{%s}pageMargins' % CHART_NS, margins)
        SubElement(settings, '{%s}pageSetup' % CHART_NS)
Beispiel #8
0
 def write_chart(self):
     """write chart"""
     chart = SubElement(self.root, '{%s}chart' % CHART_NS)
     self._write_title(chart)
     self._write_layout(chart)
     self._write_legend(chart)
     SubElement(chart, '{%s}plotVisOnly' % CHART_NS, {'val': '1'})
Beispiel #9
0
 def to_tree(self, tagname=None):
     if tagname is None:
         tagname = self.tagname
     attrs = dict(self)
     el = Element(tagname, attrs)
     for n in self.__nested__:
         value = getattr(self, n)
         if isinstance(value, tuple):
             if hasattr(el, 'extend'):
                 el.extend(self._serialise_nested(value))
             else: # py26 nolxml
                 for _ in self._serialise_nested(value):
                     el.append(_)
         elif value:
             SubElement(el, n, val=safe_string(value))
     for child in self.__elements__:
         obj = getattr(self, child)
         if isinstance(obj, tuple):
             for v in obj:
                 if hasattr(v, 'to_tree'):
                     el.append(v.to_tree(tagname=child))
                 else:
                     SubElement(el, child).text = v
         elif obj is not None:
             el.append(obj.to_tree(tagname=child))
     return el
 def _write_border(self, node, border):
     """Write the child elements for an individual border section"""
     border_node = SubElement(node, 'border', dict(border))
     for tag, elem in border.children:
         side = SubElement(border_node, tag, dict(elem))
         if elem.color is not None:
             self._write_color(side, elem.color)
Beispiel #11
0
    def write_comments_vml(self):
        root = Element("xml")
        shape_layout = SubElement(root, "{%s}shapelayout" % officens,
                                  {"{%s}ext" % vmlns: "edit"})
        SubElement(shape_layout, "{%s}idmap" % officens, {
            "{%s}ext" % vmlns: "edit",
            "data": "1"
        })
        shape_type = SubElement(
            root, "{%s}shapetype" % vmlns, {
                "id": "_x0000_t202",
                "coordsize": "21600,21600",
                "{%s}spt" % officens: "202",
                "path": "m,l,21600r21600,l21600,xe"
            })
        SubElement(shape_type, "{%s}stroke" % vmlns, {"joinstyle": "miter"})
        SubElement(shape_type, "{%s}path" % vmlns, {
            "gradientshapeok": "t",
            "{%s}connecttype" % officens: "rect"
        })

        for idx, comment in enumerate(self.comments, 1026):

            shape = _shape_factory()
            col, row = coordinate_from_string(comment.ref)
            row -= 1
            column = column_index_from_string(col) - 1

            shape.set('id', "_x0000_s%04d" % idx)
            client_data = shape.find("{%s}ClientData" % excelns)
            client_data.find("{%s}Row" % excelns).text = str(row)
            client_data.find("{%s}Column" % excelns).text = str(column)
            root.append(shape)

        return tostring(root)
Beispiel #12
0
def write_worksheet_rels(worksheet, drawing_id, comments_id):
    """Write relationships for the worksheet to xml."""
    root = Element('{%s}Relationships' % PKG_REL_NS)
    for rel in worksheet.relationships:
        attrs = {'Id': rel.id, 'Type': rel.type, 'Target': rel.target}
        if rel.target_mode:
            attrs['TargetMode'] = rel.target_mode
        SubElement(root, '{%s}Relationship' % PKG_REL_NS, attrs)
    if worksheet._charts or worksheet._images:
        attrs = {
            'Id': 'rId1',
            'Type': '%s/drawing' % REL_NS,
            'Target': '../drawings/drawing%s.xml' % drawing_id
        }
        SubElement(root, '{%s}Relationship' % PKG_REL_NS, attrs)
    if worksheet._comment_count > 0:
        # there's only one comments sheet per worksheet,
        # so there's no reason to call the Id rIdx
        attrs = {
            'Id': 'comments',
            'Type': COMMENTS_NS,
            'Target': '../comments%s.xml' % comments_id
        }
        SubElement(root, '{%s}Relationship' % PKG_REL_NS, attrs)
        attrs = {
            'Id': 'commentsvml',
            'Type': VML_NS,
            'Target': '../drawings/commentsDrawing%s.vml' % comments_id
        }
        SubElement(root, '{%s}Relationship' % PKG_REL_NS, attrs)
    return get_document_content(root)
Beispiel #13
0
def write_cell(worksheet, cell, styled=None):
    coordinate = cell.coordinate
    attributes = {'r': coordinate}
    if styled:
        attributes['s'] = '%d' % cell.style_id

    if cell.data_type != 'f':
        attributes['t'] = cell.data_type

    value = cell._value

    el = Element("c", attributes)
    if value is None or value == "":
        return el

    if cell.data_type == 'f':
        shared_formula = worksheet.formula_attributes.get(coordinate, {})
        if (shared_formula.get('t') == 'shared'
            and 'ref' not in shared_formula):
            value = None
        formula = SubElement(el, 'f', shared_formula)
        if value is not None:
            formula.text = value[1:]
            value = None

    if cell.data_type == 's':
        value = worksheet.parent.shared_strings.add(value)
    cell_content = SubElement(el, 'v')
    if value is not None:
        cell_content.text = safe_string(value)
    return el
Beispiel #14
0
    def write_comments_vml(self):
        root = Element("xml")
        shape_layout = SubElement(root, "{%s}shapelayout" % officens,
                                  {"{%s}ext" % vmlns: "edit"})
        SubElement(shape_layout, "{%s}idmap" % officens, {
            "{%s}ext" % vmlns: "edit",
            "data": "1"
        })
        shape_type = SubElement(
            root, "{%s}shapetype" % vmlns, {
                "id": "_x0000_t202",
                "coordsize": "21600,21600",
                "{%s}spt" % officens: "202",
                "path": "m,l,21600r21600,l21600,xe"
            })
        SubElement(shape_type, "{%s}stroke" % vmlns, {"joinstyle": "miter"})
        SubElement(shape_type, "{%s}path" % vmlns, {
            "gradientshapeok": "t",
            "{%s}connecttype" % officens: "rect"
        })

        for i, comment in enumerate(self.comments, 1026):
            shape = self._write_comment_shape(comment, i)
            root.append(shape)

        return tostring(root)
Beispiel #15
0
    def _write_legend(self, chart):

        if self.chart.show_legend:
            legend = SubElement(chart, '{%s}legend' % CHART_NS)
            SubElement(legend, '{%s}legendPos' % CHART_NS,
                       {'val': self.chart.legend.position})
            SubElement(legend, '{%s}layout' % CHART_NS)
def write_sheetviews(worksheet):
    views = Element('sheetViews')
    sheetviewAttrs = {'workbookViewId': '0'}
    if not worksheet.show_gridlines:
        sheetviewAttrs['showGridLines'] = '0'
    view = SubElement(views, 'sheetView', sheetviewAttrs)
    selectionAttrs = {}
    topLeftCell = worksheet.freeze_panes
    if topLeftCell:
        colName, row = coordinate_from_string(topLeftCell)
        column = column_index_from_string(colName)
        pane = 'topRight'
        paneAttrs = {}
        if column > 1:
            paneAttrs['xSplit'] = str(column - 1)
        if row > 1:
            paneAttrs['ySplit'] = str(row - 1)
            pane = 'bottomLeft'
            if column > 1:
                pane = 'bottomRight'
        paneAttrs.update(dict(topLeftCell=topLeftCell,
                              activePane=pane,
                              state='frozen'))
        view.append(Element('pane', paneAttrs))
        selectionAttrs['pane'] = pane
        if row > 1 and column > 1:
            SubElement(view, 'selection', {'pane': 'topRight'})
            SubElement(view, 'selection', {'pane': 'bottomLeft'})

    selectionAttrs.update({'activeCell': worksheet.active_cell,
                           'sqref': worksheet.selected_cell})

    SubElement(view, 'selection', selectionAttrs)
    return views
 def _write_cell_style_xfs(self):
     cell_style_xfs = SubElement(self._root, 'cellStyleXfs', {'count': '1'})
     SubElement(cell_style_xfs, 'xf', {
         'numFmtId': "0",
         'fontId': "0",
         'fillId': "0",
         'borderId': "0"
     })
Beispiel #18
0
def write_external_link(links):
    """Serialise links to ranges in a single external worbook"""
    root = Element("{%s}externalLink" % SHEET_MAIN_NS)
    book =  SubElement(root, "{%s}externalBook" % SHEET_MAIN_NS, {'{%s}id' % REL_NS:'rId1'})
    external_ranges = SubElement(book, "{%s}definedNames" % SHEET_MAIN_NS)
    for l in links:
        external_ranges.append(Element("{%s}definedName" % SHEET_MAIN_NS, dict(l)))
    return root
Beispiel #19
0
    def _write_style_names(self):
        styles = self.wb._named_styles

        cell_styles = SubElement(self._root, 'cellStyles', count=str(len(styles)))

        for idx, style in enumerate(styles.values()):
            attrs = dict(style)
            attrs['xfId'] = str(idx)
            SubElement(cell_styles, 'cellStyle', attrs)
Beispiel #20
0
 def _write_number_formats(self):
     node = SubElement(self._root,
                       'numFmts',
                       count="%d" % len(self.number_formats))
     for idx, nf in enumerate(self.number_formats, 164):
         SubElement(node, 'numFmt', {
             'numFmtId': '%d' % idx,
             'formatCode': '%s' % nf
         })
Beispiel #21
0
def write_header_footer(worksheet):
    header = worksheet.header_footer.getHeader()
    footer = worksheet.header_footer.getFooter()
    if header or footer:
        tag = Element('headerFooter')
        if header:
            SubElement(tag, 'oddHeader').text = header
        if footer:
            SubElement(tag, 'oddFooter').text = footer
        return tag
Beispiel #22
0
def write_workbook(workbook):
    """Write the core workbook xml."""

    root = Element('{%s}workbook' % SHEET_MAIN_NS)
    if LXML:
        _nsmap = {'r':REL_NS}
        root = Element('{%s}workbook' % SHEET_MAIN_NS, nsmap=_nsmap)

    wb_props = {}
    if workbook.code_name is not None:
        wb_props['codeName'] = workbook.code_name
    SubElement(root, '{%s}workbookPr' % SHEET_MAIN_NS, wb_props)

    # book views
    book_views = SubElement(root, '{%s}bookViews' % SHEET_MAIN_NS)
    SubElement(book_views, '{%s}workbookView' % SHEET_MAIN_NS,
               {'activeTab': '%d' % workbook._active_sheet_index}
               )

    # worksheets
    sheets = SubElement(root, '{%s}sheets' % SHEET_MAIN_NS)
    for idx, sheet in enumerate(workbook.worksheets + workbook.chartsheets, 1):
        sheet_node = SubElement(
            sheets, '{%s}sheet' % SHEET_MAIN_NS,
            {'name': sheet.title, 'sheetId': '%d' % idx,
             '{%s}id' % REL_NS: 'rId%d' % idx})
        if not sheet.sheet_state == 'visible':
            if len(workbook._sheets) == 1:
                raise ValueError("The only worksheet of a workbook cannot be hidden")
            sheet_node.set('state', sheet.sheet_state)

    # external references
    if getattr(workbook, '_external_links', []):
        external_references = SubElement(root, '{%s}externalReferences' % SHEET_MAIN_NS)
        # need to match a counter with a workbook's relations
        counter = len(workbook.worksheets) + 3 # strings, styles, theme
        if workbook.vba_archive:
            counter += 1
        for idx, _ in enumerate(workbook._external_links, counter+1):
            ext = Element("{%s}externalReference" % SHEET_MAIN_NS, {"{%s}id" % REL_NS:"rId%d" % idx})
            external_references.append(ext)

    # Defined names
    defined_names = SubElement(root, '{%s}definedNames' % SHEET_MAIN_NS)
    _write_defined_names(workbook, defined_names)

    # Defined names -> autoFilter
    for i, sheet in enumerate(workbook.worksheets):
        auto_filter = sheet.auto_filter.ref
        if not auto_filter:
            continue
        name = SubElement(
            defined_names, '{%s}definedName' % SHEET_MAIN_NS,
            dict(name='_xlnm._FilterDatabase', localSheetId=str(i), hidden='1'))
        name.text = "'%s'!%s" % (sheet.title.replace("'", "''"),
                                 absolute_coordinate(auto_filter))

    SubElement(root, '{%s}calcPr' % SHEET_MAIN_NS,
               {'calcId': '124519', 'fullCalcOnLoad': '1'})
    return tostring(root)
Beispiel #23
0
    def _write_anchor(self, node, drawing):
        x, y, w, h = drawing.get_emu_dimensions()

        if drawing.anchortype == "oneCell":
            anchor = SubElement(node, '{%s}oneCellAnchor' % SHEET_DRAWING_NS)
            xdrfrom = SubElement(anchor, '{%s}from' % SHEET_DRAWING_NS)
            SubElement(xdrfrom, '{%s}col' %
                       SHEET_DRAWING_NS).text = safe_string(drawing.anchorcol)
            SubElement(xdrfrom,
                       '{%s}colOff' % SHEET_DRAWING_NS).text = safe_string(x)
            SubElement(xdrfrom, '{%s}row' %
                       SHEET_DRAWING_NS).text = safe_string(drawing.anchorrow)
            SubElement(xdrfrom,
                       '{%s}rowOff' % SHEET_DRAWING_NS).text = safe_string(y)
        else:
            anchor = SubElement(node, '{%s}absoluteAnchor' % SHEET_DRAWING_NS)
            SubElement(anchor, '{%s}pos' % SHEET_DRAWING_NS, {
                'x': safe_string(x),
                'y': safe_string(y)
            })

        SubElement(anchor, '{%s}ext' % SHEET_DRAWING_NS, {
            'cx': safe_string(w),
            'cy': safe_string(h)
        })

        return anchor
Beispiel #24
0
    def _write_series(self, subchart):

        for i, series in enumerate(self.chart):
            ser = SubElement(subchart, '{%s}ser' % CHART_NS)
            SubElement(ser, '{%s}idx' % CHART_NS, {'val':safe_string(i)})
            SubElement(ser, '{%s}order' % CHART_NS, {'val':safe_string(i)})

            if series.title:
                tx = SubElement(ser, '{%s}tx' % CHART_NS)
                SubElement(tx, '{%s}v' % CHART_NS).text = series.title

            if isinstance(self, LineChart):
                marker = SubElement(ser, "{%s}marker" % CHART_NS)
                SubElement(marker, "{%s}symbol" % CHART_NS, val=safe_string(series.marker))

            if series.color:
                sppr = SubElement(ser, '{%s}spPr' % CHART_NS)
                self._write_series_color(sppr, series)

            if series.error_bar:
                self._write_error_bar(ser, series)

            if series.labels:
                self._write_series_labels(ser, series)

            if series.xvalues:
                self._write_series_xvalues(ser, series)

            val = SubElement(ser, self.series_type)
            self._write_serial(val, series.reference)
Beispiel #25
0
    def _write_colors(self):
        """
        Workbook contains a different colour index.
        """

        if self.wb._colors == COLOR_INDEX:
            return

        cols = SubElement(self._root, "colors")
        rgb = SubElement(cols, "indexedColors")
        for color in self.wb._colors:
            SubElement(rgb, "rgbColor", rgb=color)
Beispiel #26
0
    def _write_fonts(self):
        """ add fonts part to root
            return {font.crc => index}
        """

        fonts = SubElement(self._root, 'fonts')

        # default
        font_node = SubElement(fonts, 'font')
        SubElement(font_node, 'sz', {'val': '11'})
        SubElement(font_node, 'color', {'theme': '1'})
        SubElement(font_node, 'name', {'val': 'Calibri'})
        SubElement(font_node, 'family', {'val': '2'})
        SubElement(font_node, 'scheme', {'val': 'minor'})

        # others
        table = {}
        index = 1
        for st in self.styles:
            if st.font != DEFAULTS.font and st.font not in table:
                font_node = SubElement(fonts, 'font')
                table[st.font] = index
                index += 1
                self._write_font(font_node, st.font)

        fonts.attrib["count"] = "%d" % index
        return table
Beispiel #27
0
    def write_comments(self):
        # produce xml
        root = Element("{%s}comments" % SHEET_MAIN_NS)
        authorlist_tag = SubElement(root, "{%s}authors" % SHEET_MAIN_NS)
        for author in self.authors:
            leaf = SubElement(authorlist_tag, "{%s}author" % SHEET_MAIN_NS)
            leaf.text = author

        commentlist_tag = SubElement(root, "{%s}commentList" % SHEET_MAIN_NS)
        for comment in self.comments:
            attrs = {
                'ref': comment._parent.coordinate,
                'authorId': '%d' % self.authors.index(comment.author),
                'shapeId': '0'
            }
            comment_tag = SubElement(commentlist_tag,
                                     "{%s}comment" % SHEET_MAIN_NS, attrs)

            text_tag = SubElement(comment_tag, "{%s}text" % SHEET_MAIN_NS)
            run_tag = SubElement(text_tag, "{%s}r" % SHEET_MAIN_NS)
            SubElement(run_tag, "{%s}rPr" % SHEET_MAIN_NS)
            t_tag = SubElement(run_tag, "{%s}t" % SHEET_MAIN_NS)
            t_tag.text = comment.text

        return tostring(root)
Beispiel #28
0
    def _write_serial(self, node, reference, literal=False):
        is_ref = hasattr(reference, 'pos1')
        data_type = reference.data_type
        number_format = getattr(reference, 'number_format')

        mapping = {'n':{'ref':'numRef', 'cache':'numCache'},
                   's':{'ref':'strRef', 'cache':'strCache'}}

        if is_ref:
            ref = SubElement(node, '{%s}%s' %(CHART_NS, mapping[data_type]['ref']))
            SubElement(ref, '{%s}f' % CHART_NS).text = str(reference)
            data = SubElement(ref, '{%s}%s' %(CHART_NS, mapping[data_type]['cache']))
            values = reference.values
        else:
            data = SubElement(node, '{%s}numLit' % CHART_NS)
            values = (1,)

        if data_type == 'n':
            SubElement(data, '{%s}formatCode' % CHART_NS).text = number_format or 'General'

        SubElement(data, '{%s}ptCount' % CHART_NS, {'val':str(len(values))})
        for j, val in enumerate(values):
            point = SubElement(data, '{%s}pt' % CHART_NS, {'idx':str(j)})
            val = safe_string(val)
            SubElement(point, '{%s}v' % CHART_NS).text = val
Beispiel #29
0
    def write_rels(self, chart_id, image_id):

        root = Element("{%s}Relationships" % PKG_REL_NS)
        i = 0
        for i, chart in enumerate(self._sheet._charts):
            attrs = {'Id' : 'rId%s' % (i + 1),
                'Type' : '%s/chart' % REL_NS,
                'Target' : '../charts/chart%s.xml' % (chart_id + i) }
            SubElement(root, '{%s}Relationship' % PKG_REL_NS, attrs)
        for j, img in enumerate(self._sheet._images):
            attrs = {'Id' : 'rId%s' % (i + j + 1),
                'Type' : '%s/image' % REL_NS,
                'Target' : '../media/image%s.png' % (image_id + j) }
            SubElement(root, '{%s}Relationship' % PKG_REL_NS, attrs)
        return tostring(root)
Beispiel #30
0
    def _write_dxfs(self):
        if self._style_properties and 'dxf_list' in self._style_properties:
            dxfs = SubElement(
                self._root, 'dxfs',
                {'count': str(len(self._style_properties['dxf_list']))})
            for d in self._style_properties['dxf_list']:
                dxf = SubElement(dxfs, 'dxf')
                if 'font' in d and d['font'] is not None:
                    font_node = SubElement(dxf, 'font')
                    if d['font'].color is not None:
                        self._write_color(font_node, d['font'].color)
                    ConditionalElement(font_node, 'b', d['font'].bold, 'val')
                    ConditionalElement(font_node, 'i', d['font'].italic, 'val')
                    ConditionalElement(font_node, 'u',
                                       d['font'].underline != 'none',
                                       {'val': d['font'].underline})
                    ConditionalElement(font_node, 'strike',
                                       d['font'].strikethrough)

                if 'fill' in d:
                    f = d['fill']
                    fill = SubElement(dxf, 'fill')
                    if f.fill_type:
                        node = SubElement(fill, 'patternFill',
                                          {'patternType': f.fill_type})
                    else:
                        node = SubElement(fill, 'patternFill')
                    if f.start_color != DEFAULTS.fill.start_color:
                        self._write_color(node, f.start_color, 'fgColor')

                    if f.end_color != DEFAULTS.fill.end_color:
                        self._write_color(node, f.end_color, 'bgColor')

                if 'border' in d:
                    borders = d['border']
                    border = SubElement(dxf, 'border')
                    # caution: respect this order
                    for side in ('left', 'right', 'top', 'bottom'):
                        obj = getattr(borders, side)
                        if obj.border_style is None or obj.border_style == 'none':
                            node = SubElement(border, side)
                        else:
                            node = SubElement(border, side,
                                              {'style': obj.border_style})
                            self._write_color(node, obj.color)
        else:
            dxfs = SubElement(self._root, 'dxfs', {'count': '0'})
        return dxfs