Anyone who has tried their hand at OpenXml programming would concur that its a bit daunting at start with. Anyone tried their hands at making charts in OpenXml would agree even more. There are, of course, several code snippets on the internet to help you out. However, I didn’t find any that would help me with simple charts in PowerPoint. And the one I found for Excel, for instance, was too complicated to be used and involved creating a chart from the scratch.
All I wanted was a simple way to put my data into in existing bar chart in a powerpoint slide. That way I can give the user the freedom to have any formatting options that he wishes for the chart and only the data will be filled in by my program.
You’ll see the code snippet below. Basically I delete the existing “BarChartSeries” and insert my own with my data. I don’t touch any other part of the Chart leaving the formatting intact.
It may not work for all your scenarios but its a simple thing to start with. Note that I’m using Microsoft’s OpenXml SDK.
private void button1_Click(object sender, EventArgs e)
{
Dictionary<string, int> values = new Dictionary<string, int>();
values.Add("hello", 20);
values.Add("world", 30);
values.Add("test", 40);
values.Add("data", 50);
PresentationDocument presentationDoc = PresentationDocument.Open("c:\\p2.pptx", true);
SlidePart slidePart = presentationDoc.PresentationPart.SlideParts.First();
ChartPart chartPart = slidePart.ChartParts.First();
ReplaceValuesInChartInSlide(chartPart, values, "my category");
presentationDoc.PresentationPart.Presentation.Save();
presentationDoc.Close();
}
public static void ReplaceValuesInChartInSlide(ChartPart chartPart, Dictionary<string, int> data, string categoryTitle)
{
ChartSpace chartSpace = chartPart.ChartSpace;
List<int> indexOfUsedItems = new List<int>();
BarChart barChart = chartSpace.Descendants<BarChart>().FirstOrDefault();
barChart.RemoveAllChildren<BarChartSeries>();
uint i = 0;
foreach (string key in data.Keys)
{
BarChartSeries barChartSeries = barChart.AppendChild<BarChartSeries>(new BarChartSeries(new Index() { Val = new UInt32Value(i) },
new Order() { Val = new UInt32Value(i) },
new SeriesText(new NumericValue() { Text = key })));
StringLiteral strLit = barChartSeries.AppendChild<CategoryAxisData>(new CategoryAxisData()).AppendChild<StringLiteral>(new StringLiteral());
strLit.Append(new PointCount() { Val = new UInt32Value(1U) });
strLit.AppendChild<StringPoint>(new StringPoint() { Index = new UInt32Value(0U) }).Append(new NumericValue(categoryTitle));
NumberLiteral numLit = barChartSeries.AppendChild<DocumentFormat.OpenXml.Drawing.Charts.Values>(
new DocumentFormat.OpenXml.Drawing.Charts.Values()).AppendChild<NumberLiteral>(new NumberLiteral());
numLit.Append(new FormatCode("General"));
numLit.Append(new PointCount() { Val = new UInt32Value(1U) });
numLit.AppendChild<NumericPoint>(new NumericPoint() { Index = new UInt32Value(0u) }).Append(new NumericValue(data[key].ToString()));
i++;
}
chartSpace.Save();
}
The p2.pptx in the code simply contained a slide with a barchart.
Note that a chart in powerpoint has its associated data in an embedded excel file. In this sample we haven’t touched that excel file and hence haven’t changed that data. Hence, although your chart will render new data correctly, it may not show the new data in that excel (it appears when click “Edit Data” for the chart in PowerPoint). Anyways, this simple code worked for us cos our primary aim was to render the graph.




