def _write_chartsheets(self, archive): from openpyxl.packaging.relationship import Relationship, RelationshipList from openpyxl.worksheet.drawing import Drawing for idx, sheet in enumerate(self.workbook.chartsheets, 1): if sheet._charts: drawing = SpreadsheetDrawing() drawing.charts = sheet._charts self.workbook._drawings.append(drawing) drawing_id = len(self.workbook._drawings) drawingpath = "{0}/drawing{1}.xml".format(PACKAGE_DRAWINGS, drawing_id) archive.writestr(drawingpath, tostring(drawing._write())) archive.writestr( "{0}/_rels/drawing{1}.xml.rels".format( PACKAGE_DRAWINGS, drawing_id), tostring(drawing._write_rels()) ) rel = Relationship(type="drawing", target="/" + drawingpath) rels = RelationshipList() rels.append(rel) tree = rels.to_tree() sheet.drawing.id = "rId{0}".format(len(rels)) archive.writestr(PACKAGE_CHARTSHEETS + '/_rels/sheet%d.xml.rels' % idx, tostring(tree) ) xml = tostring(sheet.to_tree()) archive.writestr(PACKAGE_CHARTSHEETS + '/sheet%d.xml' % idx, xml)
def _write_chartsheets(self, archive): from openpyxl.packaging.relationship import Relationship, RelationshipList from openpyxl.worksheet.drawing import Drawing for idx, sheet in enumerate(self.workbook.chartsheets, 1): if sheet._charts: drawing = SpreadsheetDrawing() drawing.charts = sheet._charts self.workbook._drawings.append(drawing) drawing_id = len(self.workbook._drawings) drawingpath = "{0}/drawing{1}.xml".format( PACKAGE_DRAWINGS, drawing_id) archive.writestr(drawingpath, tostring(drawing._write())) archive.writestr( "{0}/_rels/drawing{1}.xml.rels".format( PACKAGE_DRAWINGS, drawing_id), tostring(drawing._write_rels())) rel = Relationship(type="drawing", target="/" + drawingpath) rels = RelationshipList() rels.append(rel) tree = rels.to_tree() sheet.drawing.id = "rId{0}".format(len(rels)) archive.writestr( PACKAGE_CHARTSHEETS + '/_rels/sheet%d.xml.rels' % idx, tostring(tree)) xml = tostring(sheet.to_tree()) archive.writestr(PACKAGE_CHARTSHEETS + '/sheet%d.xml' % idx, xml)
def _write(self): from openpyxl.drawing.spreadsheet_drawing import SpreadsheetDrawing from openpyxl.writer.worksheet import write_worksheet self._drawing = SpreadsheetDrawing() self._drawing.charts = self._charts self._drawing.images = self._images return write_worksheet(self)
def _write_worksheets(self, archive): comments_id = 0 for idx, sheet in enumerate(self.workbook.worksheets, 1): xml = sheet._write(self.workbook.shared_strings) sheet._path = "sheet{0}.xml".format(idx) arc_path = "{0}/{1}".format(PACKAGE_WORKSHEETS, sheet._path) rels_path = get_rels_path(arc_path) archive.writestr(arc_path, xml) if sheet._charts or sheet._images: drawing = SpreadsheetDrawing() drawing.charts = sheet._charts drawing.images = sheet._images self.workbook._drawings.append(drawing) drawing_id = len(self.workbook._drawings) drawingpath = "{0}/drawing{1}.xml".format(PACKAGE_DRAWINGS, drawing_id) archive.writestr(drawingpath, tostring(drawing._write())) archive.writestr("{0}/_rels/drawing{1}.xml.rels".format(PACKAGE_DRAWINGS, drawing_id), tostring(drawing._write_rels())) for r in sheet._rels: if "drawing" in r.Type: r.Target = "/" + drawingpath if sheet._comments: comments_id += 1 cw = self.comment_writer(sheet) archive.writestr(PACKAGE_XL + '/comments%d.xml' % comments_id, cw.write_comments()) if sheet.legacy_drawing is not None: vmlroot = fromstring(self.workbook.vba_archive.read(sheet.legacy_drawing)) archive.writestr(sheet.legacy_drawing, cw.write_comments_vml(vmlroot)) # Record this file so we don't write it again when we dump out vba_archive self.vba_modified.add(sheet.legacy_drawing) else: vmlroot = Element("xml") archive.writestr(PACKAGE_XL + '/drawings/commentsDrawing%d.vml' % comments_id, cw.write_comments_vml(vmlroot)) if (sheet._rels or sheet._comments or sheet.legacy_drawing is not None): rels = write_rels(sheet, comments_id=comments_id) archive.writestr(rels_path, tostring(rels))
def to_tree(self): self._drawing = SpreadsheetDrawing() self._drawing.charts = self._charts tree = super(Chartsheet, self).to_tree() if not self.headerFooter: el = tree.find('headerFooter') tree.remove(el) tree.set("xmlns", SHEET_MAIN_NS) return tree
def _write(self): self._drawing = SpreadsheetDrawing() self._drawing.charts = self._charts self._drawing.images = self._images self.close() with open(self.filename) as src: out = src.read() self._cleanup() return out
def test_drawing(ExcelWriter, archive): wb = Workbook() ws = wb.active drawing = SpreadsheetDrawing() writer = ExcelWriter(wb, archive) writer._write_drawing(drawing) assert drawing.path == '/xl/drawings/drawing1.xml' assert drawing.path[1:] in archive.namelist() assert drawing.path in writer.manifest.filenames
def _write_worksheets(self, archive): comments_id = 0 vba_controls_id = 0 for i, sheet in enumerate(self.workbook.worksheets, 1): xml = sheet._write(self.workbook.shared_strings) archive.writestr(PACKAGE_WORKSHEETS + '/sheet%d.xml' % i , xml) if sheet._charts or sheet._images: drawing = SpreadsheetDrawing() drawing.charts = sheet._charts drawing.images = sheet._images self.workbook._drawings.append(drawing) drawing_id = len(self.workbook._drawings) drawingpath = "{0}/drawing{1}.xml".format(PACKAGE_DRAWINGS, drawing_id) archive.writestr(drawingpath, tostring(drawing._write())) archive.writestr("{0}/_rels/drawing{1}.xml.rels".format(PACKAGE_DRAWINGS, drawing_id), tostring(drawing._write_rels())) for r in sheet._rels: if "drawing" in r.type: r.target = "/" + drawingpath if sheet._comment_count > 0: comments_id += 1 cw = self.comment_writer(sheet) archive.writestr(PACKAGE_XL + '/comments%d.xml' % comments_id, cw.write_comments()) archive.writestr(PACKAGE_XL + '/drawings/commentsDrawing%d.vml' % comments_id, cw.write_comments_vml()) if sheet.vba_controls is not None: vba_controls_id += 1 if (sheet._rels or sheet._comment_count > 0 or sheet.vba_controls is not None): rels = write_rels(sheet, comments_id=comments_id, vba_controls_id=vba_controls_id) archive.writestr( PACKAGE_WORKSHEETS + '/_rels/sheet%d.xml.rels' % i, tostring(rels))
def find_images(archive, path): """ Given the path to a drawing file extract charts and images Ingore errors due to unsupported parts of DrawingML """ src = archive.read(path) tree = fromstring(src) try: drawing = SpreadsheetDrawing.from_tree(tree) except TypeError: warn( "DrawingML support is incomplete and limited to charts and images only. Shapes and drawings will be lost." ) return [], [] rels_path = get_rels_path(path) deps = [] if rels_path in archive.namelist(): deps = get_dependents(archive, rels_path) charts = [] for rel in drawing._chart_rels: cs = get_rel(archive, deps, rel.id, ChartSpace) chart = read_chart(cs) chart.anchor = rel.anchor charts.append(chart) images = [] if not PILImage: # Pillow not installed, drop images return charts, images for rel in drawing._blip_rels: dep = deps[rel.embed] if dep.Type == IMAGE_NS: try: image = Image(BytesIO(archive.read(dep.target))) except OSError: msg = "The image {0} will be removed because it cannot be read".format( dep.target) warn(msg) continue if image.format.upper() == "WMF": # cannot save msg = "{0} image format is not supported so the image is being dropped".format( image.format) warn(msg) continue image.anchor = rel.anchor images.append(image) return charts, images
def write_worksheet(self, ws): ws._drawing = SpreadsheetDrawing() ws._drawing.charts = ws._charts ws._drawing.images = ws._images if self.workbook.write_only: if not ws.closed: ws.close() writer = ws._writer else: writer = WorksheetWriter(ws) writer.write() ws._rels = writer._rels self._archive.write(writer.out, ws.path[1:]) self.manifest.append(ws) writer.cleanup()
def _write_worksheets(self, archive): comments_id = 0 for idx, sheet in enumerate(self.workbook.worksheets, 1): xml = sheet._write(self.workbook.shared_strings) sheet._path = "sheet{0}.xml".format(idx) arc_path = "{0}/{1}".format(PACKAGE_WORKSHEETS, sheet._path) rels_path = get_rels_path(arc_path) archive.writestr(arc_path, xml) if sheet._charts or sheet._images: drawing = SpreadsheetDrawing() drawing.charts = sheet._charts drawing.images = sheet._images self.workbook._drawings.append(drawing) drawing_id = len(self.workbook._drawings) drawingpath = "{0}/drawing{1}.xml".format( PACKAGE_DRAWINGS, drawing_id) archive.writestr(drawingpath, tostring(drawing._write())) archive.writestr( "{0}/_rels/drawing{1}.xml.rels".format( PACKAGE_DRAWINGS, drawing_id), tostring(drawing._write_rels())) for r in sheet._rels: if "drawing" in r.Type: r.Target = "/" + drawingpath if sheet._comments: comments_id += 1 cw = self.comment_writer(sheet) archive.writestr(PACKAGE_XL + '/comments%d.xml' % comments_id, cw.write_comments()) if sheet.legacy_drawing is not None: vmlroot = fromstring( self.workbook.vba_archive.read(sheet.legacy_drawing)) archive.writestr(sheet.legacy_drawing, cw.write_comments_vml(vmlroot)) # Record this file so we don't write it again when we dump out vba_archive self.vba_modified.add(sheet.legacy_drawing) else: vmlroot = Element("xml") archive.writestr( PACKAGE_XL + '/drawings/commentsDrawing%d.vml' % comments_id, cw.write_comments_vml(vmlroot)) if (sheet._rels or sheet._comments or sheet.legacy_drawing is not None): rels = write_rels(sheet, comments_id=comments_id) archive.writestr(rels_path, tostring(rels))
def find_images(archive, path): src = archive.read(path) tree = fromstring(src) drawing = SpreadsheetDrawing.from_tree(tree) rels_path = get_rels_path(path) deps = [] if rels_path in archive.namelist(): deps = get_dependents(archive, rels_path) images = [] for rel in drawing._image_rels: id = rel.embed path = deps[id].target image = Image(BytesIO(archive.read(path))) image.anchor = rel.anchor images.append(image) return images
def find_charts(archive, path): """ Given the path to a drawing file extract anchors with charts """ src = archive.read(path) tree = fromstring(src) drawing = SpreadsheetDrawing.from_tree(tree) rels_path = get_rels_path(path) deps = [] if rels_path in archive.namelist(): deps = get_dependents(archive, rels_path) charts = [] for rel in drawing._chart_rels: cs = get_rel(archive, deps, rel.id, ChartSpace) chart = read_chart(cs) chart.anchor = rel.anchor charts.append(chart) return charts
def find_images(archive, path): """ Given the path to a drawing file extract anchors with images """ src = archive.read(path) tree = fromstring(src) drawing = SpreadsheetDrawing.from_tree(tree) rels_path = get_rels_path(path) deps = [] if rels_path in archive.namelist(): deps = get_dependents(archive, rels_path) images = [] for rel in drawing._blip_rels: dep = deps[rel.embed] if dep.Type == IMAGE_NS: image = Image(BytesIO(archive.read(dep.target))) image.anchor = rel.anchor images.append(image) return images
def find_images(archive, path): """ Given the path to a drawing file extract charts and images Ingore errors due to unsupported parts of DrawingML """ src = archive.read(path) tree = fromstring(src) try: drawing = SpreadsheetDrawing.from_tree(tree) except TypeError: warn( "DrawingML support is incomplete and limited to charts and images only. Shapes and drawings will be lost." ) return [], [] rels_path = get_rels_path(path) deps = [] if rels_path in archive.namelist(): deps = get_dependents(archive, rels_path) charts = [] for rel in drawing._chart_rels: cs = get_rel(archive, deps, rel.id, ChartSpace) chart = read_chart(cs) chart.anchor = rel.anchor charts.append(chart) images = [] for rel in drawing._blip_rels: dep = deps[rel.embed] if dep.Type == IMAGE_NS: image = Image(BytesIO(archive.read(dep.target))) image.anchor = rel.anchor images.append(image) return charts, images
def to_tree(self): self._drawing = SpreadsheetDrawing() self._drawing.charts = self._charts tree = super(Chartsheet, self).to_tree() tree.set("xmlns", SHEET_MAIN_NS) return tree