Chart - Embedded Worksheet¶
The data for a chart in PowerPoint is stored in an embedded Excel spreadsheet.
Spike approach¶
- [ ] driver with one blank slide, builder column chart single series.
- [ ] Can edit Excel data in resulting file
- [ ] resulting file has an embedded Excel package of expected name
- [ ] XML uses worksheet references, not just cached data
Proposed protocol¶
>>> graphic_frame = prs.slides[0].shapes[0]
>>> chart = graphic_frame.chart
>>> chart_data = chart.chart_data
>>> chart_data
<pptx.chart.chart.ChartData instance at 0xdeadbeef1>
>>> chart_data.update_from_xlsx_stream(xlsx_stream)
MS API Protocol¶
>>> chart = prs.Slides(1).Shapes(1).Chart
>>> chart_data = chart.ChartData
>>> workbook = chart_data.Workbook
>>> worksheet = Workbook.Worksheets(1)
ChartData objects¶
- BreakLink
- Removes the link between the data for a chart and a Microsoft Excel workbook.
- IsLinked
- True if the data for the chart is linked to an external Microsoft Excel workbook. Read-only Boolean.
- Workbook
- Returns the workbook that contains the chart data associated with the chart. Read-only Object.
Code sketches¶
ChartPart.xlsx_blob = blob
:
@xlsx_blob.setter
def xlsx_blob(self, blob):
xlsx_part = self.xlsx_part
if xlsx_part:
xlsx_part.blob = blob
else:
xlsx_part = EmbeddedXlsxPart.new(blob, self.package)
rId = self.relate_to(xlsx_part, RT.PACKAGE)
externalData = self._element.get_or_add_externalData
externalData.rId = rId
@classmethod EmbeddedXlsxPart.new(cls, blob, package)
:
partname = cls.next_partname(package)
content_type = CT.SML_SHEET
xlsx_part = EmbeddedXlsxPart(partname, content_type, blob, package)
return xlsx_part
ChartPart.add_or_replace_xlsx(xlsx_stream)
:
xlsx_part = self.get_or_add_xlsx_part()
xlsx_stream.seek(0)
xlsx_bytes = xlsx_stream.read()
xlsx_part.blob = xlsx_bytes
ChartPart.xlsx_part
:
externalData = self._element.externalData
if externalData is None:
raise ValueError("chart has no embedded worksheet")
rId = externalData.rId
xlsx_part = self.related_parts[rId]
return xlsx_part
# later ...
xlsx_stream = BytesIO(xlsx_part.blob)
xlsx_package = OpcPackage.open(xlsx_stream)
workbook_part = xlsx_package.main_document
- Maybe can implement just a few Excel parts, enough to access and manipulate the data necessary. Like Workbook (start part I think) and Worksheet.
- What about linked rather than embedded Worksheet?
XML specimens¶
simple column chart:
<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<c:chartSpace
xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"
xmlns:c="http://schemas.openxmlformats.org/drawingml/2006/chart"
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
>
<c:date1904 val="0"/>
<c:lang val="en-US"/>
<c:roundedCorners val="0"/>
<mc:AlternateContent xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006">
<mc:Choice xmlns:c14="http://schemas.microsoft.com/office/drawing/2007/8/2/chart"
Requires="c14">
<c14:style val="102"/>
</mc:Choice>
<mc:Fallback>
<c:style val="2"/>
</mc:Fallback>
</mc:AlternateContent>
<c:chart>
<!-- 179 rows elided -->
</c:chart>
<c:txPr>
<a:bodyPr/>
<a:lstStyle/>
<a:p>
<a:pPr>
<a:defRPr sz="1800"/>
</a:pPr>
<a:endParaRPr lang="en-US"/>
</a:p>
</c:txPr>
<c:externalData r:id="rId1">
<c:autoUpdate val="0"/>
</c:externalData>
</c:chartSpace>