PowerPoint Charts in C# and VB.NET

Chart elements are drawings used for graphical data representation. GemBox.Presentation provides a support for working with charts with a help of GemBox.Spreadsheet component.

  • With GemBox.Spreadsheet, GemBox.Presentation is able to create and update charts in PowerPoint presentations. It's also able to export presentations with charts to PDF, XPS or image format.
  • Without GemBox.Spreadsheet, GemBox.Presentation is only able to preserve charts in PowerPoint presentations.

Create chart

To enable GemBox.Presentation's chart support and work with Chart objects, you'll need to add a reference to GemBox.Spreadsheet library and call its SpreadsheetInfo.SetLicense method.

Note, if you don't have a GemBox.Spreadsheet license you can use its Free mode.

You can choose to create charts from the following types:

  • Area
  • Bar
  • Column
  • Combo
  • Line
  • Pie
  • Scatter

The following example shows how you can create a presentation with a chart element using C# and VB.NET.

PDF document with chart element
Screenshot of PDF document with chart
using GemBox.Presentation;
using GemBox.Spreadsheet;
using GemBox.Spreadsheet.Charts;

class Program
{
    static void Main()
    {
        // If using the Professional version, put your GemBox.Presentation serial key below.
        ComponentInfo.SetLicense("FREE-LIMITED-KEY");

        // If using the Professional version, put your GemBox.Spreadsheet serial key below.
        SpreadsheetInfo.SetLicense("FREE-LIMITED-KEY");

        var presentation = new PresentationDocument();

        // Add new PowerPoint presentation slide.
        var slide = presentation.Slides.AddNew(SlideLayoutType.Custom);

        // Add simple PowerPoint presentation title.
        var textBox = slide.Content.AddTextBox(ShapeGeometryType.Rectangle,
            116.8, 20, 105, 10, GemBox.Presentation.LengthUnit.Millimeter);

        textBox.AddParagraph().AddRun("New presentation with chart element.");

        // Create PowerPoint chart and add it to slide.
        var chart = slide.Content.AddChart(GemBox.Presentation.ChartType.Bar,
            49.3, 40, 240, 120, GemBox.Presentation.LengthUnit.Millimeter);

        // Get underlying Excel chart.
        ExcelChart excelChart = (ExcelChart)chart.ExcelChart;
        ExcelWorksheet worksheet = excelChart.Worksheet;

        // Add data for Excel chart.
        worksheet.Cells["A1"].Value = "Name";
        worksheet.Cells["A2"].Value = "John Doe";
        worksheet.Cells["A3"].Value = "Fred Nurk";
        worksheet.Cells["A4"].Value = "Hans Meier";
        worksheet.Cells["A5"].Value = "Ivan Horvat";

        worksheet.Cells["B1"].Value = "Salary";
        worksheet.Cells["B2"].Value = 3600;
        worksheet.Cells["B3"].Value = 2580;
        worksheet.Cells["B4"].Value = 3200;
        worksheet.Cells["B5"].Value = 4100;

        // Select data.
        excelChart.SelectData(worksheet.Cells.GetSubrange("A1:B5"), true);

        presentation.Save("Created Chart.%OutputFileType%");
    }
}
Imports GemBox.Presentation
Imports GemBox.Spreadsheet
Imports GemBox.Spreadsheet.Charts

Module Program

    Sub Main()

        ' If using the Professional version, put your GemBox.Presentation serial key below.
        ComponentInfo.SetLicense("FREE-LIMITED-KEY")

        ' If using the Professional version, put your GemBox.Spreadsheet serial key below.
        SpreadsheetInfo.SetLicense("FREE-LIMITED-KEY")

        Dim presentation As New PresentationDocument()

        ' Add new PowerPoint presentation slide.
        Dim slide = presentation.Slides.AddNew(SlideLayoutType.Custom)

        ' Add simple PowerPoint presentation title.
        Dim textBox = slide.Content.AddTextBox(ShapeGeometryType.Rectangle,
            116.8, 20, 105, 10, GemBox.Presentation.LengthUnit.Millimeter)

        textBox.AddParagraph().AddRun("New presentation with chart element.")

        ' Create PowerPoint chart and add it to slide.
        Dim chart = slide.Content.AddChart(GemBox.Presentation.ChartType.Bar,
            49.3, 40, 240, 120, GemBox.Presentation.LengthUnit.Millimeter)

        ' Get underlying Excel chart.
        Dim excelChart As ExcelChart = DirectCast(chart.ExcelChart, ExcelChart)
        Dim worksheet As ExcelWorksheet = excelChart.Worksheet

        ' Add data for Excel chart.
        worksheet.Cells("A1").Value = "Name"
        worksheet.Cells("A2").Value = "John Doe"
        worksheet.Cells("A3").Value = "Fred Nurk"
        worksheet.Cells("A4").Value = "Hans Meier"
        worksheet.Cells("A5").Value = "Ivan Horvat"

        worksheet.Cells("B1").Value = "Salary"
        worksheet.Cells("B2").Value = 3600
        worksheet.Cells("B3").Value = 2580
        worksheet.Cells("B4").Value = 3200
        worksheet.Cells("B5").Value = 4100

        ' Select data.
        excelChart.SelectData(worksheet.Cells.GetSubrange("A1:B5"), True)

        presentation.Save("Created Chart.%OutputFileType%")

    End Sub

End Module

For more information about charts, visit the Chart Components and Chart Formatting examples.

Note that to export a PowerPoint presentation with a chart to PDF or image format on a non-Windows platform (like on Linux or macOS), you'll need to add additional package references for native assets:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="GemBox.Presentation" Version="*" />
    <PackageReference Include="GemBox.Spreadsheet" Version="*" />

    <!-- Additional NuGet package references when running on Linux. -->
    <PackageReference Include="HarfBuzzSharp.NativeAssets.Linux" Version="*" />
    <PackageReference Include="SkiaSharp.NativeAssets.Linux" Version="*" />
  </ItemGroup>

</Project>

Update chart

The following example shows how you can update chart element's data in a PowerPoint presentation.

PowerPoint presentation with updated chart element
Screenshot of PowerPoint presentation with updated chart
using System.Linq;
using GemBox.Presentation;
using GemBox.Spreadsheet;
using GemBox.Spreadsheet.Charts;

class Program
{
    static void Main()
    {
        // If using the Professional version, put your GemBox.Presentation serial key below.
        ComponentInfo.SetLicense("FREE-LIMITED-KEY");

        // If using the Professional version, put your GemBox.Spreadsheet serial key below.
        SpreadsheetInfo.SetLicense("FREE-LIMITED-KEY");

        // Load input file and save it in selected output format
        var presentation = PresentationDocument.Load("%#Chart.pptx%");

        // Get PowerPoint chart.
        var chart = ((GraphicFrame)presentation.Slides[0].Content.Drawings[0]).Chart;

        // Get underlying Excel chart and cast it as LineChart.
        var lineChart = (LineChart)chart.ExcelChart;

        // Get underlying Excel sheet and add new cell values.
        var sheet = lineChart.Worksheet;
        sheet.Cells["D1"].Value = "Series 3";
        sheet.Cells["D2"].Value = 8.6;
        sheet.Cells["D3"].Value = 5;
        sheet.Cells["D4"].Value = 7;
        sheet.Cells["D5"].Value = 9;

        // Add new line series to the LineChart.
        lineChart.Series.Add(sheet.Cells["D1"].StringValue, "Sheet1!D2:D5");

        presentation.Save("Updated Chart.%OutputFileType%");
    }
}
Imports System.Linq
Imports GemBox.Presentation
Imports GemBox.Spreadsheet
Imports GemBox.Spreadsheet.Charts

Module Program

    Sub Main()

        ' If using the Professional version, put your GemBox.Presentation serial key below.
        ComponentInfo.SetLicense("FREE-LIMITED-KEY")

        ' If using the Professional version, put your GemBox.Spreadsheet serial key below.
        SpreadsheetInfo.SetLicense("FREE-LIMITED-KEY")

        ' Load input file and save it in selected output format
        Dim presentation = PresentationDocument.Load("%#Chart.pptx%")

        ' Get PowerPoint chart.
        Dim chart = DirectCast(presentation.Slides(0).Content.Drawings(0), GraphicFrame).Chart

        ' Get underlying Excel chart and cast it as LineChart.
        Dim lineChart = DirectCast(chart.ExcelChart, LineChart)

        ' Get underlying Excel sheet and add new cell values.
        Dim sheet = lineChart.Worksheet
        sheet.Cells("D1").Value = "Series 3"
        sheet.Cells("D2").Value = 8.6
        sheet.Cells("D3").Value = 5
        sheet.Cells("D4").Value = 7
        sheet.Cells("D5").Value = 9

        ' Add new line series to the LineChart.
        lineChart.Series.Add(sheet.Cells("D1").StringValue, "Sheet1!D2:D5")

        presentation.Save("Updated Chart.%OutputFileType%")

    End Sub

End Module

Some chart types are not supported through an API (like 3D charts) and won't be represented with Chart object.

You can find a list of supported chart types on GemBox.Spreadsheet's Charts help page.

Create chart from array data

Usually, the chart's data is provided as a reference to a worksheet's cell range or a named range. But you can also directly assign an array of numeric values that you want to plot.

Using array data may in some cases be an easier and more convenient way to work with charts, such charts are independent of their parent worksheet. However, note that you cannot add or modify such series with Microsoft PowerPoint.

The following example shows how to create chart series using array values directly.

PowerPoint presentation with chart that has values directly in its series
Screenshot of chart series with direct values
using GemBox.Presentation;
using GemBox.Spreadsheet.Charts;

class Program
{
    static void Main()
    {
        // If using the Professional version, put your GemBox.Presentation serial key below.
        ComponentInfo.SetLicense("FREE-LIMITED-KEY");

        // If using the Professional version, put your GemBox.Spreadsheet serial key below.
        SpreadsheetInfo.SetLicense("FREE-LIMITED-KEY");

        var presentation = new PresentationDocument();
        var slide = presentation.Slides.AddNew(SlideLayoutType.Custom);
        var chart = slide.Content.AddChart(GemBox.Presentation.ChartType.Column,
            5, 5, 15, 10, GemBox.Presentation.LengthUnit.Centimeter);

        // Get underlying Excel chart.
        var columnChart = (ColumnChart)chart.ExcelChart;

        // Set chart's category labels from array.
        columnChart.SetCategoryLabels(new string[] { "Columns 1", "Columns 2", "Columns 3" });

        // Add chart's series from arrays.
        columnChart.Series.Add("Values 1", new double[] { 3.4, 1.1, 3.7 });
        columnChart.Series.Add("Values 2", new double[] { 4.4, 3.9, 3.5 });
        columnChart.Series.Add("Values 3", new double[] { 2.9, 4.1, 1.9 });

        presentation.Save("Created Chart from Array.%OutputFileType%");
    }
}
Imports GemBox.Presentation
Imports GemBox.Spreadsheet.Charts

Module Program

    Sub Main()

        ' If using the Professional version, put your GemBox.Presentation serial key below.
        ComponentInfo.SetLicense("FREE-LIMITED-KEY")

        ' If using the Professional version, put your GemBox.Spreadsheet serial key below.
        SpreadsheetInfo.SetLicense("FREE-LIMITED-KEY")

        Dim presentation As New PresentationDocument()
        Dim slide = presentation.Slides.AddNew(SlideLayoutType.Custom)
        Dim chart = slide.Content.AddChart(GemBox.Presentation.ChartType.Column,
            5, 5, 15, 10, GemBox.Presentation.LengthUnit.Centimeter)

        ' Get underlying Excel chart.
        Dim columnChart = DirectCast(chart.ExcelChart, ColumnChart)

        ' Set chart's category labels from array.
        columnChart.SetCategoryLabels(New String() {"Columns 1", "Columns 2", "Columns 3"})

        ' Add chart's series from arrays.
        columnChart.Series.Add("Values 1", New Double() {3.4, 1.1, 3.7})
        columnChart.Series.Add("Values 2", New Double() {4.4, 3.9, 3.5})
        columnChart.Series.Add("Values 3", New Double() {2.9, 4.1, 1.9})

        presentation.Save("Created Chart from Array.%OutputFileType%")

    End Sub

End Module

Export chart

When saving a PowerPoint file with charts to PDF, the charts are rasterized to bitmaps and bitmaps are inserted in the PDF output. However, using GemBox.Pdf, you can save presentations with charts to PDF in a pure vectorized form. The code below demonstrates how to do that.

Upload your file (Drag file here)
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using GemBox.Presentation;
using GemBox.Pdf;
using GemBox.Pdf.Content;
using GemBox.Spreadsheet;
using GemBox.Spreadsheet.Charts;

class Program
{
    static void Main()
    {
        // If using the Professional versions, put your serial keys below.
        GemBox.Presentation.ComponentInfo.SetLicense("FREE-LIMITED-KEY");
        GemBox.Pdf.ComponentInfo.SetLicense("FREE-LIMITED-KEY");
        GemBox.Spreadsheet.SpreadsheetInfo.SetLicense("FREE-LIMITED-KEY");

        var presentation = PresentationDocument.Load("%InputFileName%");
        var placeholdersMapping = ReplaceChartsWithPlaceholders(presentation);
        presentation.Save("Chart.pdf");

        using (var pdf = PdfDocument.Load("Chart.pdf"))
        {
            ReplacePlaceholdersWithCharts(pdf, placeholdersMapping);
            pdf.Save();
        }
    }

    static readonly string PlaceholderNameFormat = "GemBox_Chart_Placeholder_{0}";
    static readonly Regex PlaceholderNameRegex = new Regex("GemBox_Chart_Placeholder_\\d+");
    static readonly MemoryStream PlaceholderImage = new MemoryStream(File.ReadAllBytes("%#placeholder.png%"));

    static Dictionary<string, MemoryStream> ReplaceChartsWithPlaceholders(PresentationDocument presentation)
    {
        var placeholdersMapping = new Dictionary<string, MemoryStream>();
        int counter = 0;

        foreach (var slide in presentation.Slides)
        {
            foreach (var frame in slide.Content.Drawings.All()
                .OfType<GraphicFrame>()
                .Where(f => f.Chart != null)
                .ToList())
            {
                var layout = frame.Layout;

                // Replace PowerPoint chart with placeholder image that has specific title.
                var placeholder = slide.Content.AddPicture(PictureContentType.Png, PlaceholderImage,
                    layout.Left, layout.Top, layout.Width, layout.Height);
                string placeholderName = string.Format(PlaceholderNameFormat, ++counter);
                placeholder.AlternativeText.Title = placeholderName;
                frame.Parent.Drawings.Remove(frame);

                // Retrieve Excel chart and export it as PDF.
                var excelChart = (ExcelChart)frame.Chart.ExcelChart;
                excelChart.Position.Width = layout.Width;
                excelChart.Position.Height = layout.Height;
                var chartAsPdfStream = new MemoryStream();
                excelChart.Format().Save(chartAsPdfStream, GemBox.Spreadsheet.SaveOptions.PdfDefault);

                // Map PDF that contains Excel chart to placeholder name.
                placeholdersMapping.Add(placeholderName, chartAsPdfStream);
            }
        }

        return placeholdersMapping;
    }

    static void ReplacePlaceholdersWithCharts(PdfDocument pdfDocument, Dictionary<string, MemoryStream> placeholdersMapping)
    {
        foreach (var page in pdfDocument.Pages)
        {
            // Find placeholders by searching for images with specific title.
            var placeholders = FindPlaceholders(page);

            foreach (var placeholder in placeholders)
            {
                if (!placeholdersMapping.TryGetValue(placeholder.Key, out MemoryStream chartAsPdfStream))
                    continue;

                PdfImageContent image = placeholder.Value.Item1;
                PdfQuad bounds = placeholder.Value.Item2;

                // Replace placeholder image with PDF that contains Excel chart.
                using (var excelDocument = PdfDocument.Load(chartAsPdfStream))
                {
                    var form = excelDocument.Pages[0].ConvertToForm(pdfDocument);
                    var formContentGroup = page.Content.Elements.AddGroup();
                    var formContent = formContentGroup.Elements.AddForm(form);
                    formContent.Transform = PdfMatrix.CreateTranslation(bounds.Left, bounds.Bottom);
                }

                image.Collection.Remove(image);
            }
        }
    }

    static Dictionary<string, Tuple<PdfImageContent, PdfQuad>> FindPlaceholders(PdfPage page)
    {
        var placeholders = new Dictionary<string, Tuple<PdfImageContent, PdfQuad>>();
        var enumerator = page.Content.Elements.All(page.Transform).GetEnumerator();
        while (enumerator.MoveNext())
        {
            var element = enumerator.Current;
            if (element.ElementType != PdfContentElementType.Image)
                continue;

            var imageElement = (PdfImageContent)element;
            var metadata = imageElement.Image.Metadata?.Value;
            if (metadata == null)
                continue;

            var match = PlaceholderNameRegex.Match(metadata);
            if (!match.Success)
                continue;

            var bounds = imageElement.Bounds;
            enumerator.Transform.Transform(ref bounds);
            placeholders.Add(match.Value, Tuple.Create(imageElement, bounds));
        }

        return placeholders;
    }
}
Imports System
Imports System.Collections.Generic
Imports System.IO
Imports System.Linq
Imports System.Text.RegularExpressions
Imports GemBox.Presentation
Imports GemBox.Pdf
Imports GemBox.Pdf.Content
Imports GemBox.Spreadsheet
Imports GemBox.Spreadsheet.Charts

Module Program

    Sub Main()

        ' If using the Professional versions, put your serial keys below.
        GemBox.Presentation.ComponentInfo.SetLicense("FREE-LIMITED-KEY")
        GemBox.Pdf.ComponentInfo.SetLicense("FREE-LIMITED-KEY")
        GemBox.Spreadsheet.SpreadsheetInfo.SetLicense("FREE-LIMITED-KEY")

        Dim presentation = PresentationDocument.Load("%InputFileName%")
        Dim placeholdersMapping = ReplaceChartsWithPlaceholders(presentation)
        presentation.Save("Chart.pdf")

        Using pdf = PdfDocument.Load("Chart.pdf")
            ReplacePlaceholdersWithCharts(pdf, placeholdersMapping)
            pdf.Save()
        End Using

    End Sub

    ReadOnly PlaceholderNameFormat As String = "GemBox_Chart_Placeholder_{0}"
    ReadOnly PlaceholderNameRegex As Regex = New Regex("GemBox_Chart_Placeholder_\d+")
    ReadOnly PlaceholderImage As MemoryStream = New MemoryStream(File.ReadAllBytes("%#placeholder.png%"))

    Function ReplaceChartsWithPlaceholders(presentation As PresentationDocument) As Dictionary(Of String, MemoryStream)
        Dim placeholdersMapping = New Dictionary(Of String, MemoryStream)()
        Dim counter As Integer = 0

        For Each slide In presentation.Slides
            For Each frame In slide.Content.Drawings.All() _
                .OfType(Of GraphicFrame)() _
                .Where(Function(f) f.Chart IsNot Nothing) _
                .ToList()
                Dim layout = frame.Layout

                ' Replace PowerPoint chart with placeholder image that has specific title.
                Dim placeholder = slide.Content.AddPicture(PictureContentType.Png, PlaceholderImage,
                    layout.Left, layout.Top, layout.Width, layout.Height)
                counter += 1
                Dim placeholderName As String = String.Format(PlaceholderNameFormat, counter)
                placeholder.AlternativeText.Title = placeholderName
                frame.Parent.Drawings.Remove(frame)

                ' Retrieve Excel chart and export it as PDF.
                Dim excelChart = CType(frame.Chart.ExcelChart, ExcelChart)
                excelChart.Position.Width = layout.Width
                excelChart.Position.Height = layout.Height
                Dim chartAsPdfStream = New MemoryStream()
                excelChart.Format().Save(chartAsPdfStream, GemBox.Spreadsheet.SaveOptions.PdfDefault)

                ' Map PDF that contains Excel chart to placeholder name.
                placeholdersMapping.Add(placeholderName, chartAsPdfStream)
            Next
        Next

        Return placeholdersMapping
    End Function

    Sub ReplacePlaceholdersWithCharts(pdfDocument As PdfDocument, placeholdersMapping As Dictionary(Of String, MemoryStream))
        Dim chartAsPdfStream As MemoryStream = Nothing

        For Each page In pdfDocument.Pages
            ' Find placeholders by searching for images with specific title.
            Dim placeholders = FindPlaceholders(page)

            For Each placeholder In placeholders
                If Not placeholdersMapping.TryGetValue(placeholder.Key, chartAsPdfStream) Then Continue For

                Dim image As PdfImageContent = placeholder.Value.Item1
                Dim bounds As PdfQuad = placeholder.Value.Item2

                ' Replace placeholder image with PDF that contains Excel chart.
                Using excelDocument = pdfDocument.Load(chartAsPdfStream)
                    Dim form = excelDocument.Pages(0).ConvertToForm(pdfDocument)
                    Dim formContentGroup = page.Content.Elements.AddGroup()
                    Dim formContent = formContentGroup.Elements.AddForm(form)
                    formContent.Transform = PdfMatrix.CreateTranslation(bounds.Left, bounds.Bottom)
                End Using

                image.Collection.Remove(image)
            Next
        Next
    End Sub

    Function FindPlaceholders(page As PdfPage) As Dictionary(Of String, Tuple(Of PdfImageContent, PdfQuad))
        Dim placeholders = New Dictionary(Of String, Tuple(Of PdfImageContent, PdfQuad))()
        Dim enumerator = page.Content.Elements.All(page.Transform).GetEnumerator()

        While enumerator.MoveNext()

            Dim element = enumerator.Current
            If element.ElementType <> PdfContentElementType.Image Then Continue While

            Dim imageElement = CType(element, PdfImageContent)
            Dim metadata = imageElement.Image.Metadata?.Value
            If metadata Is Nothing Then Continue While

            Dim match = PlaceholderNameRegex.Match(metadata)
            If Not match.Success Then Continue While

            Dim bounds = imageElement.Bounds
            enumerator.Transform.Transform(bounds)
            placeholders.Add(match.Value, Tuple.Create(imageElement, bounds))

        End While

        Return placeholders
    End Function

End Module

See also


Next steps

GemBox.Presentation is a .NET component that enables you to read, write, edit, convert, and print presentation files from your .NET applications using one simple API.

Download Buy