def write_rels(worksheet, comments_id=None, vba_controls_id=None): """Write relationships for the worksheet to xml.""" root = Element('Relationships', xmlns=PKG_REL_NS) rels = worksheet._rels # VBA if worksheet.vba_controls is not None: rel = Relationship("vmlDrawing", id=worksheet.vba_controls, target='/xl/drawings/vmlDrawing%s.vml' % vba_controls_id) rels.append(rel) # Comments if worksheet._comment_count > 0: rel = Relationship(type="comments", id="comments", target='/xl/comments%s.xml' % comments_id) rels.append(rel) if worksheet.vba_controls is None: rel = Relationship(type="vmlDrawing", id="commentsvml", target='/xl/drawings/commentsDrawing%s.vml' % comments_id) rels.append(rel) for idx, rel in enumerate(rels, 1): if rel.id is None: rel.id = "rId{0}".format(idx) root.append(rel.to_tree()) return root
def write_external_book_rel(book): """Serialise link to external file""" root = Element("Relationships", xmlns=PKG_REL_NS) rel = Relationship("", target=book.Target, targetMode=book.TargetMode, id="rId1") rel.type = book.Type root.append(rel.to_tree()) return root
def write_workbook_rels(workbook): """Write the workbook relationships xml.""" rels = RelationshipList() rId = 0 for idx, _ in enumerate(workbook.worksheets, 1): rId += 1 rel = Relationship(type='worksheet', target='worksheets/sheet%s.xml' % idx, id='rId%d' % rId) rels.append(rel) for idx, _ in enumerate(workbook.chartsheets, 1): rId += 1 rel = Relationship(type='chartsheet', target='chartsheets/sheet%s.xml' % idx, id='rId%d' % rId) rels.append(rel) rId += 1 strings = Relationship(type='sharedStrings', target='sharedStrings.xml', id='rId%d' % rId) rels.append(strings) rId += 1 styles = Relationship(type='styles', target='styles.xml', id='rId%d' % rId) rels.append(styles) rId += 1 theme = Relationship(type='theme', target='theme/theme1.xml', id='rId%d' % rId) rels.append(theme) if workbook.vba_archive: rId += 1 vba = Relationship(type='vbaProject', target='vbaProject.bin', id='rId%d' % rId) vba.type ='http://schemas.microsoft.com/office/2006/relationships/vbaProject' rels.append(vba) external_links = workbook._external_links if external_links: for idx, link in enumerate(external_links, 1): ext = Relationship(type='externalLink', target='externalLinks/externalLink%d.xml' % idx, id='rId%d' % (rId +idx)) rels.append(ext) return tostring(rels.to_tree())
def write_workbook_rels(workbook): """Write the workbook relationships xml.""" wb = workbook strings = Relationship(type='sharedStrings', Target='sharedStrings.xml') wb.rels.append(strings) styles = Relationship(type='styles', Target='styles.xml') wb.rels.append(styles) theme = Relationship(type='theme', Target='theme/theme1.xml') wb.rels.append(theme) if workbook.vba_archive: vba = Relationship(type='', Target='vbaProject.bin') vba.Type ='http://schemas.microsoft.com/office/2006/relationships/vbaProject' wb.rels.append(vba) return tostring(wb.rels.to_tree())
def write_root_rels(workbook): """Write the relationships xml.""" rels = RelationshipList() rel = Relationship(type="officeDocument", Target=ARC_WORKBOOK) rels.append(rel) rel = Relationship(Target=ARC_CORE, Type="%s/metadata/core-properties" % PKG_REL_NS) rels.append(rel) rel = Relationship(type="extended-properties", Target=ARC_APP) rels.append(rel) if workbook.vba_archive is not None: # See if there was a customUI relation and reuse it xml = fromstring(workbook.vba_archive.read(ARC_ROOT_RELS)) root_rels = RelationshipList.from_tree(xml) for rel in root_rels.find(CUSTOMUI_NS): rels.append(rel) return tostring(rels.to_tree())
def _write(self): """ create required structure and the serialise """ anchors = [] for idx, obj in enumerate(self.charts + self.images, 1): if isinstance(obj, ChartBase): rel = Relationship(type="chart", Target='../charts/chart%s.xml' % obj._id) anchor = obj.anchor if not isinstance(anchor, _AnchorBase): row, col = coordinate_to_tuple(anchor) anchor = OneCellAnchor() anchor._from.row = row - 1 anchor._from.col = col - 1 anchor.ext.width = cm_to_EMU(obj.width) anchor.ext.height = cm_to_EMU(obj.height) anchor.graphicFrame = self._chart_frame(idx) elif isinstance(obj, Image): rel = Relationship(type="image", Target='../media/image%s.png' % obj._id) anchor = obj.drawing.anchor anchor.pic = self._picture_frame(idx) anchors.append(anchor) self._rels.append(rel) for a in anchors: if isinstance(a, OneCellAnchor): self.oneCellAnchor.append(a) elif isinstance(a, TwoCellAnchor): self.twoCellAnchor.append(a) else: self.absoluteAnchor.append(a) tree = self.to_tree() tree.set('xmlns', SHEET_DRAWING_NS) return tree
def write_hyperlinks(worksheet): """Write worksheet hyperlinks to xml.""" links = HyperlinkList() for link in worksheet._hyperlinks: if link.target: rel = Relationship(type="hyperlink", TargetMode="External", Target=link.target) worksheet._rels.append(rel) link.id = rel.id links.hyperlink.append(link) return links
def test_internal_hyperlinks(self, PrimedWorksheetReader): reader = PrimedWorksheetReader reader.bind_cells() ws = reader.ws r = Relationship(type="hyperlink", Id="rId1", Target="../") rels = RelationshipList() rels.append(r) ws._rels = rels reader.bind_hyperlinks() assert ws['B4'].hyperlink.location == "'STP nn000TL-10, PKG 2.52'!A1" assert ws['B4'].hyperlink.ref == "B4"
def write_worksheets(self): for idx, sheet in enumerate(self.wb._sheets, 1): sheet_node = ChildSheet(name=sheet.title, sheetId=idx, id="rId{0}".format(idx)) rel = Relationship(type=sheet._rel_type, Target=sheet.path) self.rels.append(rel) if not sheet.sheet_state == 'visible': if len(self.wb._sheets) == 1: raise ValueError( "The only worksheet of a workbook cannot be hidden") sheet_node.state = sheet.sheet_state self.package.sheets.append(sheet_node)
def write_hyperlinks(self): links = HyperlinkList() for link in self.ws._hyperlinks: if link.target: rel = Relationship(type="hyperlink", TargetMode="External", Target=link.target) self._rels.append(rel) link.id = rel.id links.hyperlink.append(link) if links: self.xf.send(links.to_tree())
def test_write_rels(self, SpreadsheetDrawing): from openpyxl.packaging.relationship import Relationship rel = Relationship(type="drawing", Target="../file.xml") drawing = SpreadsheetDrawing() drawing._rels.append(rel) xml = tostring(drawing._write_rels()) expected = """ <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"> <Relationship Id="rId1" Target="../file.xml" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing"/> </Relationships> """ diff = compare_xml(xml, expected) assert diff is None, diff
def write_rels(worksheet, comments_id=None, vba_controls_id=None): """Write relationships for the worksheet to xml.""" rels = RelationshipList(worksheet._rels) # VBA if worksheet.vba_controls is not None: rel = Relationship("vmlDrawing", id=worksheet.vba_controls, target='/xl/drawings/vmlDrawing%s.vml' % vba_controls_id) rels.append(rel) # Comments if worksheet._comment_count > 0: rel = Relationship(type="comments", id="comments", target='/xl/comments%s.xml' % comments_id) rels.append(rel) if worksheet.vba_controls is None: rel = Relationship(type="vmlDrawing", id="commentsvml", target='/xl/drawings/commentsDrawing%s.vml' % comments_id) rels.append(rel) return rels.to_tree()
def write_hyperlinks(worksheet): """Write worksheet hyperlinks to xml.""" if not worksheet._hyperlinks: return tag = Element('hyperlinks') for link in worksheet._hyperlinks: rel = Relationship(type="hyperlink", targetMode="External", target=link.target) worksheet._rels.append(rel) link.id = "rId{0}".format(len(worksheet._rels)) tag.append(link.to_tree()) return tag
def write_rels(worksheet, comments_id=None): """Write relationships for the worksheet to xml.""" rels = RelationshipList(worksheet._rels) # If there is an existing vml file that is preserved or extended then # create its relation. if worksheet.legacy_drawing is not None: rel = Relationship("vmlDrawing", id="anysvml", target='/' + worksheet.legacy_drawing) rels.append(rel) # Comments if worksheet._comment_count > 0: rel = Relationship(type="comments", id="comments", target='/xl/comments%s.xml' % comments_id) rels.append(rel) if worksheet.legacy_drawing is None: rel = Relationship(type="vmlDrawing", id="anysvml", target='/xl/drawings/commentsDrawing%s.vml' % comments_id) rels.append(rel) return rels.to_tree()
def test_tables(self, PrimedWorksheetReader): reader = PrimedWorksheetReader reader.bind_cells() ws = reader.ws r = Relationship(type="table", Id="rId1", Target="../tables/table1.xml") rels = RelationshipList() rels.append(r) ws._rels = rels reader.bind_tables() assert reader.tables == ["../tables/table1.xml"]
def test_read_chartsheet(self, datadir): datadir.chdir() reader = ExcelReader("contains_chartsheets.xlsx") reader.read_manifest() reader.read_workbook() rel = Relationship(Target="xl/chartsheets/sheet1.xml", type="chartsheet") class Sheet: pass sheet = Sheet() sheet.name = "chart" reader.read_chartsheet(sheet, rel) assert reader.wb['chart'].title == "chart"
def test_merged_hyperlinks(self, PrimedWorksheetReader): reader = PrimedWorksheetReader reader.bind_cells() ws = reader.ws r = Relationship(type="hyperlink", Id="rId1", Target="../") rels = RelationshipList() rels.append(r) ws._rels = rels reader.bind_merged_cells() reader.bind_hyperlinks() assert ws.merged_cells == "G18:H18 G23:H24 A18:B18" assert ws['A18'].hyperlink.display == 'http://test.com' assert ws['B18'].hyperlink is None
def _write_rels(self, archive, manifest): """ Write the relevant child objects and add links """ if self.cache is None: return rels = RelationshipList() r = Relationship(Type=self.cache.rel_type, Target=self.cache.path) rels.append(r) self.id = r.id if self.cache.path[1:] not in archive.namelist(): self.cache._write(archive, manifest) path = get_rels_path(self.path) xml = tostring(rels.to_tree()) archive.writestr(path[1:], xml)
def write_tables(self): tables = TablePartList() for table in self.ws._tables: if not table.tableColumns: table._initialise_columns() if table.headerRowCount: row = self.ws[table.ref][0] for cell, col in zip(row, table.tableColumns): if cell.data_type != "s": warn("File may not be readable: column headings must be strings.") col.name = str(cell.value) rel = Relationship(Type=table._rel_type, Target="") self._rels.append(rel) table._rel_id = rel.Id tables.append(Related(id=rel.Id)) if tables: self.xf.send(tables.to_tree())
def _write_chartsheets(self): for idx, sheet in enumerate(self.workbook.chartsheets, 1): sheet._id = idx xml = tostring(sheet.to_tree()) self._archive.writestr(sheet.path[1:], xml) self.manifest.append(sheet) if sheet._drawing: self._write_drawing(sheet._drawing) rel = Relationship(type="drawing", Target=sheet._drawing.path) rels = RelationshipList() rels.append(rel) tree = rels.to_tree() rels_path = get_rels_path(sheet.path[1:]) self._archive.writestr(rels_path, tostring(tree))
def test_tables(WorkSheetParser): src = """ <sheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"> <tableParts count="1"> <tablePart r:id="rId1"/> </tableParts> </sheet> """ parser = WorkSheetParser r = Relationship(type="table", Id="rId1", Target="../tables/table1.xml") rels = RelationshipList() rels.append(r) parser.ws._rels = rels parser.source = src parser.parse() assert parser.tables == ["../tables/table1.xml"]
def test_external_hyperlinks(WorkSheetParser): src = """ <sheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"> <hyperlink xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" display="http://test.com" r:id="rId1" ref="A1"/> </sheet> """ from openpyxl.packaging.relationship import Relationship, RelationshipList r = Relationship(type="hyperlink", Id="rId1", Target="../") rels = RelationshipList() rels.append(r) parser = WorkSheetParser parser.source = src parser.ws._rels = rels parser.parse() assert parser.ws['A1'].hyperlink.target == "../"
def test_merged_hyperlinks(self, PrimedWorksheetReader): reader = PrimedWorksheetReader reader.bind_cells() ws = reader.ws r = Relationship(type="hyperlink", Id="rId1", Target="../") rels = RelationshipList() rels.append(r) ws._rels = rels reader.bind_merged_cells() reader.bind_hyperlinks() assert ws.merged_cells == "G18:H18 G23:H24 A18:B18" assert ws['A18'].hyperlink.display == 'http://test.com' assert ws['B18'].hyperlink is None # Link referencing H24 should be placed on G23 because H24 is a merged cell # and G23 is the top-left cell in the merged range assert ws["G23"].hyperlink.tooltip == "openpyxl" assert ws["H24"].hyperlink is None
def _write_comment(self, ws): cs = CommentSheet.from_comments(ws._comments) self._comments.append(cs) cs._id = len(self._comments) self._archive.writestr(cs.path[1:], tostring(cs.to_tree())) self.manifest.append(cs) if ws.legacy_drawing is None: ws.legacy_drawing = 'xl/drawings/commentsDrawing{0}.vml'.format(cs._id) vml = None else: vml = fromstring(self.workbook.vba_archive.read(ws.legacy_drawing)) vml = cs.write_shapes(vml) self._archive.writestr(ws.legacy_drawing, vml) self.vba_modified.add(ws.legacy_drawing) comment_rel = Relationship(Id="comments", type=cs._rel_type, Target=cs.path) ws._rels.append(comment_rel)
def _add_table_headers(ws): """ Check if tables have tableColumns and create them and autoFilter if necessary. Column headers will be taken from the first row of the table. """ tables = TablePartList() for table in ws._tables: if not table.tableColumns: table._initialise_columns() if table.headerRowCount: row = ws[table.ref][0] for cell, col in zip(row, table.tableColumns): if cell.data_type != "s": warn("File may not be readable: column headings must be strings.") col.name = unicode(cell.value) rel = Relationship(type=table._rel_type, Target="") ws._rels.append(rel) table._rel_id = rel.Id tables.append(Related(id=rel.Id)) return tables
def _write_worksheets(self): for idx, ws in enumerate(self.workbook.worksheets, 1): ws._id = idx xml = ws._write() rels_path = get_rels_path(ws.path)[1:] self._archive.writestr(ws.path[1:], xml) self.manifest.append(ws) if ws._drawing: self._write_drawing(ws._drawing) for r in ws._rels.Relationship: if "drawing" in r.Type: r.Target = ws._drawing.path if ws._comments: self._write_comment(ws) if ws.legacy_drawing is not None: shape_rel = Relationship(type="vmlDrawing", Id="anysvml", Target="/" + ws.legacy_drawing) ws._rels.append(shape_rel) for t in ws._tables: self._tables.append(t) t.id = len(self._tables) t._write(self._archive) self.manifest.append(t) ws._rels[t._rel_id].Target = t.path if ws._rels: tree = ws._rels.to_tree() self._archive.writestr(rels_path, tostring(tree))
def write_workbook_rels(workbook): """Write the workbook relationships xml.""" wb = workbook strings = Relationship(type='sharedStrings', Target='sharedStrings.xml') wb.rels.append(strings) styles = Relationship(type='styles', Target='styles.xml') wb.rels.append(styles) theme = Relationship(type='theme', Target='theme/theme1.xml') wb.rels.append(theme) if workbook.vba_archive: vba = Relationship(type='', Target='vbaProject.bin') vba.Type = 'http://schemas.microsoft.com/office/2006/relationships/vbaProject' wb.rels.append(vba) return tostring(wb.rels.to_tree())
def write_worksheet(worksheet): """Write a worksheet to an xml file.""" ws = worksheet ws._rels = RelationshipList() ws._hyperlinks = [] out = BytesIO() with xmlfile(out) as xf: with xf.element('worksheet', xmlns=SHEET_MAIN_NS): props = ws.sheet_properties.to_tree() xf.write(props) dim = SheetDimension(ref=ws.calculate_dimension()) xf.write(dim.to_tree()) xf.write(ws.views.to_tree()) cols = ws.column_dimensions.to_tree() ws.sheet_format.outlineLevelCol = ws.column_dimensions.max_outline xf.write(ws.sheet_format.to_tree()) if cols is not None: xf.write(cols) # write data write_rows(xf, ws) if ws.protection.sheet: xf.write(ws.protection.to_tree()) if ws.auto_filter: xf.write(ws.auto_filter.to_tree()) if ws.sort_state: xf.write(ws.sort_state.to_tree()) merge = write_mergecells(ws) if merge is not None: xf.write(merge) cfs = write_conditional_formatting(ws) for cf in cfs: xf.write(cf) if ws.data_validations: xf.write(ws.data_validations.to_tree()) hyper = write_hyperlinks(ws) if hyper: xf.write(hyper.to_tree()) options = ws.print_options if dict(options): new_element = options.to_tree() xf.write(new_element) margins = ws.page_margins.to_tree() xf.write(margins) setup = ws.page_setup if dict(setup): new_element = setup.to_tree() xf.write(new_element) if bool(ws.HeaderFooter): xf.write(ws.HeaderFooter.to_tree()) drawing = write_drawing(ws) if drawing is not None: xf.write(drawing) # if there is an existing vml file associated with this sheet or if there # are any comments we need to add a legacyDrawing relation to the vml file. if (ws.legacy_drawing is not None or ws._comments): legacyDrawing = Related(id="anysvml") xml = legacyDrawing.to_tree("legacyDrawing") xf.write(xml) if ws.page_breaks: xf.write(ws.page_breaks.to_tree()) tables = TablePartList() for table in ws._tables: row = ws[table.ref][0] for cell, col in zip(row, table.tableColumns): if cell.value: col.name = str(cell.value) rel = Relationship(type=table._rel_type, Target="") ws._rels.append(rel) table._rel_id = rel.Id tables.append(Related(id=rel.Id)) if tables: xf.write(tables.to_tree()) xml = out.getvalue() out.close() return xml
def write_workbook_rels(workbook): """Write the workbook relationships xml.""" root = Element('Relationships', xmlns=PKG_REL_NS) for i, _ in enumerate(workbook.worksheets, 1): rel = Relationship(type='worksheet', target='worksheets/sheet%s.xml' % i, id='rId%d' % i) root.append(rel.to_tree()) i += 1 strings = Relationship(type='sharedStrings', target='sharedStrings.xml', id='rId%d' % i) root.append(strings.to_tree()) i += 1 styles = Relationship(type='styles', target='styles.xml', id='rId%d' % i) root.append(styles.to_tree()) i += 1 styles = Relationship(type='theme', target='theme/theme1.xml', id='rId%d' % i) root.append(styles.to_tree()) if workbook.vba_archive: i += 1 vba = Relationship(type='vbaProject', target='vbaProject.bin', id='rId%d' % i) vba.type = 'http://schemas.microsoft.com/office/2006/relationships/vbaProject' root.append(vba.to_tree()) external_links = workbook._external_links if external_links: for idx, link in enumerate(external_links, 1): ext = Relationship(type='externalLink', target='externalLinks/externalLink%d.xml' % idx, id='rId%d' % (i + idx)) root.append(ext.to_tree()) return tostring(root)
def write_workbook(workbook): """Write the core workbook xml.""" wb = workbook wb.rels = RelationshipList() root = WorkbookPackage() props = WorkbookProperties( ) # needs a mapping to the workbook for preservation if wb.code_name is not None: props.codeName = wb.code_name if wb.excel_base_date == CALENDAR_MAC_1904: props.date1904 = True root.workbookPr = props # book views active = get_active_sheet(wb) view = BookView(activeTab=active) root.bookViews = [view] # worksheets for idx, sheet in enumerate(wb._sheets, 1): sheet_node = ChildSheet(name=sheet.title, sheetId=idx, id="rId{0}".format(idx)) rel = Relationship(type=sheet._rel_type, Target=sheet.path) wb.rels.append(rel) if not sheet.sheet_state == 'visible': if len(wb._sheets) == 1: raise ValueError( "The only worksheet of a workbook cannot be hidden") sheet_node.state = sheet.sheet_state root.sheets.append(sheet_node) # external references for link in wb._external_links: # need to match a counter with a workbook's relations rId = len(wb.rels) + 1 rel = Relationship(type=link._rel_type, Target=link.path) wb.rels.append(rel) ext = ExternalReference(id=rel.id) root.externalReferences.append(ext) # Defined names defined_names = copy( wb.defined_names) # don't add special defns to workbook itself. # Defined names -> autoFilter for idx, sheet in enumerate(wb.worksheets): auto_filter = sheet.auto_filter.ref if auto_filter: name = DefinedName(name='_FilterDatabase', localSheetId=idx, hidden=True) name.value = u"{0}!{1}".format(quote_sheetname(sheet.title), absolute_coordinate(auto_filter)) defined_names.append(name) # print titles if sheet.print_titles: name = DefinedName(name="Print_Titles", localSheetId=idx) name.value = ",".join([ u"{0}!{1}".format(quote_sheetname(sheet.title), r) for r in sheet.print_titles.split(",") ]) defined_names.append(name) # print areas if sheet.print_area: name = DefinedName(name="Print_Area", localSheetId=idx) name.value = ",".join([ u"{0}!{1}".format(quote_sheetname(sheet.title), r) for r in sheet.print_area ]) defined_names.append(name) root.definedNames = defined_names root.calcPr = CalcProperties(calcId=124519, fullCalcOnLoad=True) return tostring(root.to_tree())
def write_workbook_rels(workbook): """Write the workbook relationships xml.""" root = Element("Relationships", xmlns=PKG_REL_NS) for i, _ in enumerate(workbook.worksheets, 1): rel = Relationship(type="worksheet", target="worksheets/sheet%s.xml" % i, id="rId%d" % i) root.append(rel.to_tree()) i += 1 strings = Relationship(type="sharedStrings", target="sharedStrings.xml", id="rId%d" % i) root.append(strings.to_tree()) i += 1 styles = Relationship(type="styles", target="styles.xml", id="rId%d" % i) root.append(styles.to_tree()) i += 1 styles = Relationship(type="theme", target="theme/theme1.xml", id="rId%d" % i) root.append(styles.to_tree()) if workbook.vba_archive: i += 1 vba = Relationship(type="vbaProject", target="vbaProject.bin", id="rId%d" % i) vba.type = "http://schemas.microsoft.com/office/2006/relationships/vbaProject" root.append(vba.to_tree()) external_links = workbook._external_links if external_links: for idx, link in enumerate(external_links, 1): ext = Relationship( type="externalLink", target="externalLinks/externalLink%d.xml" % idx, id="rId%d" % (i + idx) ) root.append(ext.to_tree()) return tostring(root)
def write_root_rels(workbook): """Write the relationships xml.""" rels = RelationshipList() rel = Relationship(type="officeDocument", target=ARC_WORKBOOK, id="rId1") rels.append(rel) rel = Relationship("", target=ARC_CORE, id='rId2',) rel.type = "%s/metadata/core-properties" % PKG_REL_NS rels.append(rel) rel = Relationship("extended-properties", target=ARC_APP, id='rId3') rels.append(rel) if workbook.vba_archive is not None: relation_tag = '{%s}Relationship' % PKG_REL_NS # See if there was a customUI relation and reuse its id arc = fromstring(workbook.vba_archive.read(ARC_ROOT_RELS)) rel_tags = arc.findall(relation_tag) rId = None for rel in rel_tags: if rel.get('Target') == ARC_CUSTOM_UI: rId = rel.get('Id') break if rId is not None: vba = Relationship("", target=ARC_CUSTOM_UI, id=rId) vba.type = CUSTOMUI_NS rels.append(vba) return tostring(rels.to_tree())
def write_root_rels(workbook): """Write the relationships xml.""" root = Element("Relationships", xmlns=PKG_REL_NS) relation_tag = "{%s}Relationship" % PKG_REL_NS rel = Relationship(type="officeDocument", target=ARC_WORKBOOK, id="rId1") root.append(rel.to_tree()) rel = Relationship("", target=ARC_CORE, id="rId2") rel.type = "%s/metadata/core-properties" % PKG_REL_NS root.append(rel.to_tree()) rel = Relationship("extended-properties", target=ARC_APP, id="rId3") root.append(rel.to_tree()) 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: vba = Relationship("", target=ARC_CUSTOM_UI, id=rId) vba.type = CUSTOMUI_NS root.append(vba.to_tree()) return tostring(root)