def _write_style(self, node): """ write style theme """ style = SubElement(node, '{%s}style' % CHART_DRAWING_NS) ln_ref = SubElement(style, '{%s}lnRef' % DRAWING_NS, {'idx': '2'}) scheme_clr = SubElement(ln_ref, '{%s}schemeClr' % DRAWING_NS, {'val': 'accent1'}) SubElement(scheme_clr, '{%s}shade' % DRAWING_NS, {'val': '50000'}) fill_ref = SubElement(style, '{%s}fillRef' % DRAWING_NS, {'idx': '1'}) SubElement(fill_ref, '{%s}schemeClr' % DRAWING_NS, {'val': 'accent1'}) effect_ref = SubElement(style, '{%s}effectRef' % DRAWING_NS, {'idx': '0'}) SubElement(effect_ref, '{%s}schemeClr' % DRAWING_NS, {'val': 'accent1'}) font_ref = SubElement(style, '{%s}fontRef' % DRAWING_NS, {'idx': 'minor'}) SubElement(font_ref, '{%s}schemeClr' % DRAWING_NS, {'val': 'lt1'})
def _write_error_bar(self, node, serie): flag = { ErrorBar.PLUS_MINUS: 'both', ErrorBar.PLUS: 'plus', ErrorBar.MINUS: 'minus' } eb = SubElement(node, 'c:errBars') SubElement(eb, 'c:errBarType', {'val': flag[serie.error_bar.type]}) SubElement(eb, 'c:errValType', {'val': 'cust'}) plus = SubElement(eb, 'c:plus') self._write_serial(plus, serie.error_bar.values, literal=(serie.error_bar.type == ErrorBar.MINUS)) minus = SubElement(eb, 'c:minus') self._write_serial(minus, serie.error_bar.values, literal=(serie.error_bar.type == ErrorBar.PLUS))
def write_workbook_rels(workbook): """Write the workbook relationships xml.""" root = Element('{%s}Relationships' % PKG_REL_NS) for i in range(1, len(workbook.worksheets) + 1): SubElement( root, '{%s}Relationship' % PKG_REL_NS, { 'Id': 'rId%d' % i, 'Target': 'worksheets/sheet%s.xml' % i, 'Type': '%s/worksheet' % REL_NS }) rid = len(workbook.worksheets) + 1 SubElement( root, '{%s}Relationship' % PKG_REL_NS, { 'Id': 'rId%d' % rid, 'Target': 'sharedStrings.xml', 'Type': '%s/sharedStrings' % REL_NS }) SubElement( root, '{%s}Relationship' % PKG_REL_NS, { 'Id': 'rId%d' % (rid + 1), 'Target': 'styles.xml', 'Type': '%s/styles' % REL_NS }) SubElement( root, '{%s}Relationship' % PKG_REL_NS, { 'Id': 'rId%d' % (rid + 2), 'Target': 'theme/theme1.xml', 'Type': '%s/theme' % REL_NS }) if workbook.vba_archive: SubElement( root, '{%s}Relationship' % PKG_REL_NS, { 'Id': 'rId%d' % (rid + 3), 'Target': 'vbaProject.bin', 'Type': 'http://schemas.microsoft.com/office/2006/relationships/vbaProject' }) return get_document_content(root)
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.replace("-", "\-") }) return number_format_table
def write_properties_core(properties): """Write the core properties to xml.""" root = Element('{%s}coreProperties' % COREPROPS_NS) SubElement(root, '{%s}creator' % DCORE_NS).text = properties.creator SubElement(root, '{%s}lastModifiedBy' % COREPROPS_NS).text = properties.last_modified_by SubElement(root, '{%s}created' % DCTERMS_NS, {'{%s}type' % XSI_NS: '%s:W3CDTF' % DCTERMS_PREFIX}).text = \ datetime_to_W3CDTF(properties.created) SubElement(root, '{%s}modified' % DCTERMS_NS, {'{%s}type' % XSI_NS: '%s:W3CDTF' % DCTERMS_PREFIX}).text = \ datetime_to_W3CDTF(properties.modified) SubElement(root, '{%s}title' % DCORE_NS).text = properties.title SubElement(root, '{%s}description' % DCORE_NS).text = properties.description SubElement(root, '{%s}subject' % DCORE_NS).text = properties.subject SubElement(root, '{%s}keywords' % COREPROPS_NS).text = properties.keywords SubElement(root, '{%s}category' % COREPROPS_NS).text = properties.category return get_document_content(root)
def write(self): """ write a chart """ root = Element('c:chartSpace', {'xmlns:c':"http://schemas.openxmlformats.org/drawingml/2006/chart", 'xmlns:a':"http://schemas.openxmlformats.org/drawingml/2006/main", 'xmlns:r':"http://schemas.openxmlformats.org/officeDocument/2006/relationships"}) SubElement(root, 'c:lang', {'val':self.chart.lang}) self._write_chart(root) self._write_print_settings(root) self._write_shapes(root) return get_document_content(root)
def write_rels(self, drawing_id): root = Element( 'Relationships', { 'xmlns': 'http://schemas.openxmlformats.org/package/2006/relationships' }) attrs = { 'Id': 'rId1', 'Type': 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chartUserShapes', 'Target': '../drawings/drawing%s.xml' % drawing_id } SubElement(root, 'Relationship', attrs) return get_document_content(root)
def write_root_rels(workbook): """Write the relationships xml.""" root = Element('{%s}Relationships' % PKG_REL_NS) relation_tag = '{%s}Relationship' % PKG_REL_NS SubElement(root, relation_tag, { 'Id': 'rId1', 'Target': ARC_WORKBOOK, 'Type': '%s/officeDocument' % REL_NS }) SubElement( root, relation_tag, { 'Id': 'rId2', 'Target': ARC_CORE, 'Type': '%s/metadata/core-properties' % PKG_REL_NS }) SubElement(root, relation_tag, { 'Id': 'rId3', 'Target': ARC_APP, 'Type': '%s/extended-properties' % REL_NS }) if workbook.vba_archive is not None: # See if there was a customUI relation and reuse its id arc = fromstring(workbook.vba_archive.read(ARC_ROOT_RELS)) rels = arc.findall(relation_tag) rId = None for rel in rels: if rel.get('Target') == ARC_CUSTOM_UI: rId = rel.get('Id') break if rId is not None: SubElement(root, relation_tag, { 'Id': rId, 'Target': ARC_CUSTOM_UI, 'Type': '%s' % CUSTOMUI_NS }) return get_document_content(root)
def write_rels(self, chart_id): root = Element( 'Relationships', { 'xmlns': 'http://schemas.openxmlformats.org/package/2006/relationships' }) for i, chart in enumerate(self._sheet._charts): attrs = { 'Id': 'rId%s' % (i + 1), 'Type': 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart', 'Target': '../charts/chart%s.xml' % (chart_id + i) } SubElement(root, 'Relationship', attrs) return get_document_content(root)
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'}) table = {} index = 2 for st in self._style_list: if hash(st.fill) != hash(style.DEFAULTS.fill) and hash(st.fill) not in table: table[hash(st.fill)] = str(index) fill = SubElement(fills, 'fill') if hash(st.fill.fill_type) != hash(style.DEFAULTS.fill.fill_type): node = SubElement(fill, 'patternFill', {'patternType':st.fill.fill_type}) if hash(st.fill.start_color) != hash(style.DEFAULTS.fill.start_color): SubElement(node, 'fgColor', {'rgb':str(st.fill.start_color.index)}) if hash(st.fill.end_color) != hash(style.DEFAULTS.fill.end_color): SubElement(node, 'bgColor', {'rgb':str(st.fill.start_color.index)}) index += 1 fills.attrib["count"] = str(index) return table
def write_properties_core(properties): """Write the core properties to xml.""" root = Element( 'cp:coreProperties', { 'xmlns:cp': NAMESPACES['cp'], 'xmlns:xsi': NAMESPACES['xsi'], 'xmlns:dc': NAMESPACES['dc'], 'xmlns:dcterms': NAMESPACES['dcterms'], 'xmlns:dcmitype': NAMESPACES['dcmitype'], }) SubElement(root, 'dc:creator').text = properties.creator SubElement(root, 'cp:lastModifiedBy').text = properties.last_modified_by SubElement(root, 'dcterms:created', \ {'xsi:type': 'dcterms:W3CDTF'}).text = \ datetime_to_W3CDTF(properties.created) SubElement(root, 'dcterms:modified', {'xsi:type': 'dcterms:W3CDTF'}).text = \ datetime_to_W3CDTF(properties.modified) SubElement(root, 'dc:title').text = properties.title SubElement(root, 'dc:description').text = properties.description SubElement(root, 'dc:subject').text = properties.subject SubElement(root, 'cp:keywords').text = properties.keywords SubElement(root, 'cp:category').text = properties.category return get_document_content(root)
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.get_coordinate(), 'authorId': self.author_to_id[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 get_document_content(root)
def _write_title(self, chart): if self.chart.title != '': title = SubElement(chart, 'c:title') tx = SubElement(title, 'c:tx') rich = SubElement(tx, 'c:rich') SubElement(rich, 'a:bodyPr') SubElement(rich, 'a:lstStyle') p = SubElement(rich, 'a:p') pPr = SubElement(p, 'a:pPr') SubElement(pPr, 'a:defRPr') r = SubElement(p, 'a:r') SubElement(r, 'a:rPr', {'lang':self.chart.lang}) t = SubElement(r, 'a:t').text = self.chart.title SubElement(title, 'c:layout')
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._style_list: if hash(st.font) != hash(style.DEFAULTS.font) and hash( st.font) not in table: table[hash(st.font)] = str(index) font_node = SubElement(fonts, 'font') SubElement(font_node, 'sz', {'val': str(st.font.size)}) SubElement(font_node, 'color', {'rgb': str(st.font.color.index)}) SubElement(font_node, 'name', {'val': st.font.name}) SubElement(font_node, 'family', {'val': '2'}) # Don't write the 'scheme' element because it appears to prevent # the font name from being applied in Excel. #SubElement(font_node, 'scheme', {'val':'minor'}) if st.font.bold: SubElement(font_node, 'b') if st.font.italic: SubElement(font_node, 'i') if st.font.underline == 'single': SubElement(font_node, 'u') else: SubElement(font_node, 'u', {'val': st.font.underline}) index += 1 fonts.attrib["count"] = str(index) return table
def write_workbook(workbook): """Write the core workbook xml.""" root = Element( 'workbook', { 'xmlns': 'http://schemas.openxmlformats.org/spreadsheetml/2006/main', 'xml:space': 'preserve', 'xmlns:r': 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' }) SubElement( root, 'fileVersion', { 'appName': 'xl', 'lastEdited': '4', 'lowestEdited': '4', 'rupBuild': '4505' }) SubElement(root, 'workbookPr', { 'defaultThemeVersion': '124226', 'codeName': 'ThisWorkbook' }) book_views = SubElement(root, 'bookViews') SubElement( book_views, 'workbookView', { 'activeTab': '%d' % workbook.get_index(workbook.get_active_sheet()), 'autoFilterDateGrouping': '1', 'firstSheet': '0', 'minimized': '0', 'showHorizontalScroll': '1', 'showSheetTabs': '1', 'showVerticalScroll': '1', 'tabRatio': '600', 'visibility': 'visible' }) # worksheets sheets = SubElement(root, 'sheets') for i, sheet in enumerate(workbook.worksheets): sheet_node = SubElement( sheets, 'sheet', { 'name': sheet.title, 'sheetId': '%d' % (i + 1), 'r:id': 'rId%d' % (i + 1) }) if not sheet.sheet_state == sheet.SHEETSTATE_VISIBLE: sheet_node.set('state', sheet.sheet_state) # Defined names defined_names = SubElement(root, 'definedNames') # named ranges for named_range in workbook.get_named_ranges(): name = SubElement(defined_names, 'definedName', {'name': named_range.name}) # as there can be many cells in one range, generate the list of ranges dest_cells = [] cell_ids = [] for worksheet, range_name in named_range.destinations: cell_ids.append(workbook.get_index(worksheet)) dest_cells.append("'%s'!%s" % (worksheet.title.replace( "'", "''"), absolute_coordinate(range_name))) # for local ranges, we must check all the cells belong to the same sheet base_id = cell_ids[0] if named_range.local_only and all([x == base_id for x in cell_ids]): name.set('localSheetId', '%s' % base_id) # finally write the cells list name.text = ','.join(dest_cells) # autoFilter for i, sheet in enumerate(workbook.worksheets): #continue auto_filter = sheet.auto_filter if not auto_filter: continue name = SubElement( defined_names, 'definedName', dict(name='_xlnm._FilterDatabase', localSheetId=str(i), hidden='1')) name.text = "'%s'!%s" % (sheet.title.replace( "'", "''"), absolute_coordinate(auto_filter)) SubElement(root, 'calcPr', { 'calcId': '124519', 'calcMode': 'auto', 'fullCalcOnLoad': '1' }) return get_document_content(root)
def _write_dxfs(self): dxfs = SubElement(self._root, 'dxfs', {'count': '0'})
def write_content_types(workbook): """Write the content-types xml.""" root = Element('Types', { 'xmlns': 'http://schemas.openxmlformats.org/package/2006/content-types' }) SubElement( root, 'Override', { 'PartName': '/' + ARC_THEME, 'ContentType': 'application/vnd.openxmlformats-officedocument.theme+xml' }) SubElement( root, 'Override', { 'PartName': '/' + ARC_STYLE, 'ContentType': 'application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml' }) SubElement( root, 'Default', { 'Extension': 'rels', 'ContentType': 'application/vnd.openxmlformats-package.relationships+xml' }) SubElement(root, 'Default', { 'Extension': 'xml', 'ContentType': 'application/xml' }) SubElement( root, 'Override', { 'PartName': '/' + ARC_WORKBOOK, 'ContentType': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml' }) SubElement( root, 'Override', { 'PartName': '/' + ARC_APP, 'ContentType': 'application/vnd.openxmlformats-officedocument.extended-properties+xml' }) SubElement( root, 'Override', { 'PartName': '/' + ARC_CORE, 'ContentType': 'application/vnd.openxmlformats-package.core-properties+xml' }) SubElement( root, 'Override', { 'PartName': '/' + ARC_SHARED_STRINGS, 'ContentType': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml' }) drawing_id = 1 chart_id = 1 for sheet_id, sheet in enumerate(workbook.worksheets): SubElement( root, 'Override', { 'PartName': '/xl/worksheets/sheet%d.xml' % (sheet_id + 1), 'ContentType': 'application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml' }) if sheet._charts: SubElement( root, 'Override', { 'PartName': '/xl/drawings/drawing%d.xml' % drawing_id, 'ContentType': 'application/vnd.openxmlformats-officedocument.drawing+xml' }) drawing_id += 1 for chart in sheet._charts: SubElement( root, 'Override', { 'PartName': '/xl/charts/chart%d.xml' % chart_id, 'ContentType': 'application/vnd.openxmlformats-officedocument.drawingml.chart+xml' }) chart_id += 1 if chart._shapes: SubElement( root, 'Override', { 'PartName': '/xl/drawings/drawing%d.xml' % drawing_id, 'ContentType': 'application/vnd.openxmlformats-officedocument.drawingml.chartshapes+xml' }) drawing_id += 1 return get_document_content(root)
def _write_cell_style(self): cell_styles = SubElement(self._root, 'cellStyles', {'count':'1'}) cell_style = SubElement(cell_styles, 'cellStyle', {'name':"Normal", 'xfId':"0", 'builtinId':"0"})
def _write_table_styles(self): table_styles = SubElement(self._root, 'tableStyles', {'count':'0', 'defaultTableStyle':'TableStyleMedium9', 'defaultPivotStyle':'PivotStyleLight16'})
def _write_cell_style_xfs(self): cell_style_xfs = SubElement(self._root, 'cellStyleXfs', {'count':'1'}) xf = SubElement(cell_style_xfs, 'xf', {'numFmtId':"0", 'fontId':"0", 'fillId':"0", 'borderId':"0"})
def write(self, shape_id): root = Element('c:userShapes', { 'xmlns:c': 'http://schemas.openxmlformats.org/drawingml/2006/chart' }) for shape in self._shapes: anchor = SubElement( root, 'cdr:relSizeAnchor', { 'xmlns:cdr': "http://schemas.openxmlformats.org/drawingml/2006/chartDrawing" }) xstart, ystart, xend, yend = shape.get_coordinates() _from = SubElement(anchor, 'cdr:from') SubElement(_from, 'cdr:x').text = str(xstart) SubElement(_from, 'cdr:y').text = str(ystart) _to = SubElement(anchor, 'cdr:to') SubElement(_to, 'cdr:x').text = str(xend) SubElement(_to, 'cdr:y').text = str(yend) sp = SubElement(anchor, 'cdr:sp', {'macro': '', 'textlink': ''}) nvspr = SubElement(sp, 'cdr:nvSpPr') SubElement(nvspr, 'cdr:cNvPr', { 'id': str(shape_id), 'name': 'shape %s' % shape_id }) SubElement(nvspr, 'cdr:cNvSpPr') sppr = SubElement(sp, 'cdr:spPr') frm = SubElement(sppr, 'a:xfrm', {'xmlns:a': self.schema}) # no transformation SubElement(frm, 'a:off', {'x': '0', 'y': '0'}) SubElement(frm, 'a:ext', {'cx': '0', 'cy': '0'}) prstgeom = SubElement(sppr, 'a:prstGeom', { 'xmlns:a': self.schema, 'prst': str(shape.style) }) SubElement(prstgeom, 'a:avLst') fill = SubElement(sppr, 'a:solidFill', {'xmlns:a': self.schema}) SubElement(fill, 'a:srgbClr', {'val': shape.color}) border = SubElement(sppr, 'a:ln', { 'xmlns:a': self.schema, 'w': str(shape._border_width) }) sf = SubElement(border, 'a:solidFill') SubElement(sf, 'a:srgbClr', {'val': shape.border_color}) self._write_style(sp) self._write_text(sp, shape) shape_id += 1 return get_document_content(root)
def write(self): """ write drawings for one sheet in one file """ root = Element( 'xdr:wsDr', { 'xmlns:xdr': "http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing", 'xmlns:a': "http://schemas.openxmlformats.org/drawingml/2006/main" }) for i, chart in enumerate(self._sheet._charts): drawing = chart.drawing # anchor = SubElement(root, 'xdr:twoCellAnchor') # (start_row, start_col), (end_row, end_col) = drawing.coordinates # # anchor coordinates # _from = SubElement(anchor, 'xdr:from') # x = SubElement(_from, 'xdr:col').text = str(start_col) # x = SubElement(_from, 'xdr:colOff').text = '0' # x = SubElement(_from, 'xdr:row').text = str(start_row) # x = SubElement(_from, 'xdr:rowOff').text = '0' # _to = SubElement(anchor, 'xdr:to') # x = SubElement(_to, 'xdr:col').text = str(end_col) # x = SubElement(_to, 'xdr:colOff').text = '0' # x = SubElement(_to, 'xdr:row').text = str(end_row) # x = SubElement(_to, 'xdr:rowOff').text = '0' # we only support absolute anchor atm (TODO: oneCellAnchor, twoCellAnchor x, y, w, h = drawing.get_emu_dimensions() anchor = SubElement(root, 'xdr:absoluteAnchor') SubElement(anchor, 'xdr:pos', {'x': str(x), 'y': str(y)}) SubElement(anchor, 'xdr:ext', {'cx': str(w), 'cy': str(h)}) # graph frame frame = SubElement(anchor, 'xdr:graphicFrame', {'macro': ''}) name = SubElement(frame, 'xdr:nvGraphicFramePr') SubElement(name, 'xdr:cNvPr', { 'id': '%s' % i, 'name': 'Graphique %s' % i }) SubElement(name, 'xdr:cNvGraphicFramePr') frm = SubElement(frame, 'xdr:xfrm') # no transformation SubElement(frm, 'a:off', {'x': '0', 'y': '0'}) SubElement(frm, 'a:ext', {'cx': '0', 'cy': '0'}) graph = SubElement(frame, 'a:graphic') data = SubElement(graph, 'a:graphicData', { 'uri': 'http://schemas.openxmlformats.org/drawingml/2006/chart' }) SubElement( data, 'c:chart', { 'xmlns:c': 'http://schemas.openxmlformats.org/drawingml/2006/chart', 'xmlns:r': 'http://schemas.openxmlformats.org/officeDocument/2006/relationships', 'r:id': 'rId%s' % (i + 1) }) SubElement(anchor, 'xdr:clientData') for i, img in enumerate(self._sheet._images): drawing = img.drawing x, y, w, h = drawing.get_emu_dimensions() anchor = SubElement(root, 'xdr:absoluteAnchor') SubElement(anchor, 'xdr:pos', {'x': str(x), 'y': str(y)}) SubElement(anchor, 'xdr:ext', {'cx': str(w), 'cy': str(h)}) pic = SubElement(anchor, 'xdr:pic') name = SubElement(pic, 'xdr:nvPicPr') SubElement(name, 'xdr:cNvPr', { 'id': '%s' % i, 'name': 'Picture %s' % i }) SubElement( SubElement(name, 'xdr:cNvPicPr'), 'a:picLocks', { 'noChangeAspect': "1" if img.nochangeaspect else '0', 'noChangeArrowheads': "1" if img.nochangearrowheads else '0' }) blipfill = SubElement(pic, 'xdr:blipFill') SubElement( blipfill, 'a:blip', { 'xmlns:r': 'http://schemas.openxmlformats.org/officeDocument/2006/relationships', 'r:embed': 'rId%s' % (i + 1), 'cstate': 'print' }) SubElement(blipfill, 'a:srcRect') SubElement(SubElement(blipfill, 'a:stretch'), 'a:fillRect') sppr = SubElement(pic, 'xdr:spPr', {'bwMode': 'auto'}) frm = SubElement(sppr, 'a:xfrm') # no transformation SubElement(frm, 'a:off', {'x': '0', 'y': '0'}) SubElement(frm, 'a:ext', {'cx': '0', 'cy': '0'}) SubElement(SubElement(sppr, 'a:prstGeom', {'prst': 'rect'}), 'a:avLst') SubElement(sppr, 'a:noFill') ln = SubElement(sppr, 'a:ln', {'w': '1'}) SubElement(ln, 'a:noFill') SubElement(ln, 'a:miter', {'lim': '800000'}) SubElement(ln, 'a:headEnd') SubElement(ln, 'a:tailEnd', { 'type': 'none', 'w': 'med', 'len': 'med' }) SubElement(sppr, 'a:effectLst') SubElement(anchor, 'xdr:clientData') return get_document_content(root)
def _write_legend(self, chart): if self.chart.show_legend: legend = SubElement(chart, 'c:legend') SubElement(legend, 'c:legendPos', {'val':self.chart.legend.position}) SubElement(legend, 'c:layout')
def _write_axis(self, plot_area, axis, label): ax = SubElement(plot_area, label) SubElement(ax, 'c:axId', {'val':str(axis.id)}) scaling = SubElement(ax, 'c:scaling') SubElement(scaling, 'c:orientation', {'val':axis.orientation}) if label == 'c:valAx': SubElement(scaling, 'c:max', {'val':str(float(axis.max))}) SubElement(scaling, 'c:min', {'val':str(float(axis.min))}) SubElement(ax, 'c:axPos', {'val':axis.position}) if label == 'c:valAx': SubElement(ax, 'c:majorGridlines') SubElement(ax, 'c:numFmt', {'formatCode':"General", 'sourceLinked':'1'}) if axis.title != '': title = SubElement(ax, 'c:title') tx = SubElement(title, 'c:tx') rich = SubElement(tx, 'c:rich') SubElement(rich, 'a:bodyPr') SubElement(rich, 'a:lstStyle') p = SubElement(rich, 'a:p') pPr = SubElement(p, 'a:pPr') SubElement(pPr, 'a:defRPr') r = SubElement(p, 'a:r') SubElement(r, 'a:rPr', {'lang':self.chart.lang}) t = SubElement(r, 'a:t').text = axis.title SubElement(title, 'c:layout') SubElement(ax, 'c:tickLblPos', {'val':axis.tick_label_position}) SubElement(ax, 'c:crossAx', {'val':str(axis.cross)}) SubElement(ax, 'c:crosses', {'val':axis.crosses}) if axis.auto: SubElement(ax, 'c:auto', {'val':'1'}) if axis.label_align: SubElement(ax, 'c:lblAlgn', {'val':axis.label_align}) if axis.label_offset: SubElement(ax, 'c:lblOffset', {'val':str(axis.label_offset)}) if label == 'c:valAx': if self.chart.type == Chart.SCATTER_CHART: SubElement(ax, 'c:crossBetween', {'val':'midCat'}) else: SubElement(ax, 'c:crossBetween', {'val':'between'}) SubElement(ax, 'c:majorUnit', {'val':str(float(axis.unit))})
def _write_series(self, subchart): for i, serie in enumerate(self.chart._series): ser = SubElement(subchart, 'c:ser') SubElement(ser, 'c:idx', {'val':str(i)}) SubElement(ser, 'c:order', {'val':str(i)}) if serie.legend: tx = SubElement(ser, 'c:tx') self._write_serial(tx, serie.legend) if serie.color: sppr = SubElement(ser, 'c:spPr') if self.chart.type == Chart.BAR_CHART: # fill color fillc = SubElement(sppr, 'a:solidFill') SubElement(fillc, 'a:srgbClr', {'val':serie.color}) # edge color ln = SubElement(sppr, 'a:ln') fill = SubElement(ln, 'a:solidFill') SubElement(fill, 'a:srgbClr', {'val':serie.color}) if serie.error_bar: self._write_error_bar(ser, serie) marker = SubElement(ser, 'c:marker') SubElement(marker, 'c:symbol', {'val':serie.marker}) if serie.labels: cat = SubElement(ser, 'c:cat') self._write_serial(cat, serie.labels) if self.chart.type == Chart.SCATTER_CHART: if serie.xvalues: xval = SubElement(ser, 'c:xVal') self._write_serial(xval, serie.xvalues) yval = SubElement(ser, 'c:yVal') self._write_serial(yval, serie.values) else: val = SubElement(ser, 'c:val') self._write_serial(val, serie.values)
def _write_comment_shape(self, root, comment, idx): # get zero-indexed coordinates of the comment row = comment._parent.row - 1 column = column_index_from_string(comment._parent.column) - 1 attrs = { "id": "_x0000_s%s" % (idx+1026), "type": "#_x0000_t202", "style": "position:absolute; margin-left:59.25pt;margin-top:1.5pt;width:108pt;height:59.25pt;z-index:1;visibility:hidden", "fillcolor": "#ffffe1", "{%s}insetmode" % officens: "auto" } shape = SubElement(root, "{%s}shape" % vmlns, attrs) SubElement(shape, "{%s}fill" % vmlns, {"color2":"#ffffe1"}) SubElement(shape, "{%s}shadow" % vmlns, {"color":"black", "obscured":"t"}) SubElement(shape, "{%s}path" % vmlns, {"{%s}connecttype"%officens:"none"}) textbox = SubElement(shape, "{%s}textbox" % vmlns, {"style":"mso-direction-alt:auto"}) SubElement(textbox, "div", {"style": "text-align:left"}) client_data = SubElement(shape, "{%s}ClientData" % excelns, {"ObjectType": "Note"}) SubElement(client_data, "{%s}MoveWithCells" % excelns) SubElement(client_data, "{%s}SizeWithCells" % excelns) SubElement(client_data, "{%s}AutoFill" % excelns).text = "False" SubElement(client_data, "{%s}Row" % excelns).text = str(row) SubElement(client_data, "{%s}Column" % excelns).text = str(column)
def _write_shapes(self, root): if self.chart._shapes: SubElement(root, 'c:userShapes', {'r:id':'rId1'})
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'}) table = {} index = 2 for st in self._style_list: if hash(st.fill) != hash(style.DEFAULTS.fill) and hash(st.fill) not in table: table[hash(st.fill)] = str(index) fill = SubElement(fills, 'fill') if hash(st.fill.fill_type) != hash(style.DEFAULTS.fill.fill_type): node = SubElement(fill, 'patternFill', {'patternType':st.fill.fill_type}) if hash(st.fill.start_color) != hash(style.DEFAULTS.fill.start_color): if str(st.fill.start_color.index).split(':')[0] == 'theme': # strip prefix theme if marked as such if str(st.fill.start_color.index).split(':')[2]: SubElement(node, 'fgColor', {'theme':str(st.fill.start_color.index).split(':')[1], 'tint':str(st.fill.start_color.index).split(':')[2]}) else: SubElement(node, 'fgColor', {'theme':str(st.fill.start_color.index).split(':')[1]}) else: SubElement(node, 'fgColor', {'rgb':str(st.fill.start_color.index)}) if hash(st.fill.end_color) != hash(style.DEFAULTS.fill.end_color): if str(st.fill.end_color.index).split(':')[0] == 'theme': # strip prefix theme if marked as such if str(st.fill.end_color.index).split(':')[2]: SubElement(node, 'bgColor', {'theme':str(st.fill.end_color.index).split(':')[1], 'tint':str(st.fill.end_color.index).split(':')[2]}) else: SubElement(node, 'bgColor', {'theme':str(st.fill.end_color.index).split(':')[1]}) else: SubElement(node, 'bgColor', {'rgb':str(st.fill.end_color.index)}) index += 1 fills.attrib["count"] = str(index) return table
def _write_chart(self, root): chart = self.chart ch = SubElement(root, 'c:chart') self._write_title(ch) plot_area = SubElement(ch, 'c:plotArea') layout = SubElement(plot_area, 'c:layout') mlayout = SubElement(layout, 'c:manualLayout') SubElement(mlayout, 'c:layoutTarget', {'val':'inner'}) SubElement(mlayout, 'c:xMode', {'val':'edge'}) SubElement(mlayout, 'c:yMode', {'val':'edge'}) SubElement(mlayout, 'c:x', {'val':str(chart._get_margin_left())}) SubElement(mlayout, 'c:y', {'val':str(chart._get_margin_top())}) SubElement(mlayout, 'c:w', {'val':str(chart.width)}) SubElement(mlayout, 'c:h', {'val':str(chart.height)}) if chart.type == Chart.SCATTER_CHART: subchart = SubElement(plot_area, 'c:scatterChart') SubElement(subchart, 'c:scatterStyle', {'val':str('lineMarker')}) else: if chart.type == Chart.BAR_CHART: subchart = SubElement(plot_area, 'c:barChart') SubElement(subchart, 'c:barDir', {'val':'col'}) else: subchart = SubElement(plot_area, 'c:lineChart') SubElement(subchart, 'c:grouping', {'val':chart.grouping}) self._write_series(subchart) SubElement(subchart, 'c:marker', {'val':'1'}) SubElement(subchart, 'c:axId', {'val':str(chart.x_axis.id)}) SubElement(subchart, 'c:axId', {'val':str(chart.y_axis.id)}) if chart.type == Chart.SCATTER_CHART: self._write_axis(plot_area, chart.x_axis, 'c:valAx') else: self._write_axis(plot_area, chart.x_axis, 'c:catAx') self._write_axis(plot_area, chart.y_axis, 'c:valAx') self._write_legend(ch) SubElement(ch, 'c:plotVisOnly', {'val':'1'})
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 hash(st.borders) != hash(style.DEFAULTS.borders) and hash(st.borders) not in table: table[hash(st.borders)] = str(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) attrs = {} else: node = SubElement(border, side, {'style':obj.border_style}) if str(obj.color.index).split(':')[0] == 'theme': # strip prefix theme if marked as such if str(obj.color.index).split(':')[2]: SubElement(node, 'color', {'theme':str(obj.color.index).split(':')[1], 'tint':str(obj.color.index).split(':')[2]}) else: SubElement(node, 'color', {'theme':str(obj.color.index).split(':')[1]}) else: SubElement(node, 'color', {'rgb':str(obj.color.index)}) index += 1 borders.attrib["count"] = str(index) return table