---
title: "Export an Excel chart to PNG in C#"
url: https://recursiveai.org/onedocument/cookbook/extract-excel-chart-as-png/
description: "Export an Excel chart to PNG in C# with OneDocument for .NET 10. Runnable code, sample input and a downloadable example with real output."
version: "1.0.0"
---

# Export an Excel chart to PNG in C#

**OneDocument** is a free, open-source Word, Excel and PowerPoint document library for .NET from Recursive AI. MIT or Apache-2.0, no native dependencies.

[NuGet](https://www.nuget.org/packages/RecursiveAI.OneDocument.Rendering) · [GitHub](https://github.com/recursive-ai-oss/onedocument-csharp) · [Docs](https://recursiveai.org/onedocument/docs/) · [Download example (.zip)](https://recursiveai.org/onedocument/cookbook/extract-excel-chart-as-png/extract-excel-chart-as-png.zip)

Export a chart without surrounding cells, using its stored data.

```shell
dotnet add package RecursiveAI.OneDocument.Rendering
```

Requires [.NET 10](https://dotnet.microsoft.com/download/dotnet/10.0) (net10.0); .NET 9 and earlier aren’t supported.

```csharp
using RecursiveAI.OneDocument.Charts;
using RecursiveAI.OneDocument.Packaging;
using var package =
    OpcPackage.Open("chart.xlsx");
var name = ChartHost.FindChartParts(package)[0];
var chart = ChartHost.LoadPart(package, name)!;
File.WriteAllBytes("chart.png",
    ChartHost.RenderPng(chart.Chart, 480, 300));
```

Writes chart.png (960 × 600 pixels) from chart.xlsx in the zip; prints nothing. The sample chart has Jan = 10, Feb = 20 and Mar = 15.

Unzip [the example](https://recursiveai.org/onedocument/cookbook/extract-excel-chart-as-png/extract-excel-chart-as-png.zip), then `dotnet run`.

## The full program

The full program locates the first chart frame in the sample’s drawing part, follows its relationship to the chart, and reports reader and layout notes. `/xl/drawings/drawing1.xml` is the sample’s drawing path, not a universal workbook path. Its chart is a clustered column chart named Sales chart with the three values shown above. The sample was generated for this recipe and may be redistributed.

```csharp
using RecursiveAI.OneDocument.Charts;
using RecursiveAI.OneDocument.Markup;
using RecursiveAI.OneDocument.Packaging;
using OneRender.Painting;

using OpcPackage package = OpcPackage.Open("chart.xlsx");
var drawing = package.FindPart("/xl/drawings/drawing1.xml")
    ?? throw new InvalidDataException("Drawing part not found.");
var frames = ChartFrames.Find(MarkupDocument.Parse(drawing.GetBytes()));
if (frames.Count == 0)
    throw new InvalidDataException("No chart frames in this drawing.");
var frame = frames[0];
var chart = ChartHost.Load(package, drawing.Name, frame.RelationshipId)
    ?? throw new InvalidDataException("Chart could not be loaded.");
var layout = ChartHost.Paint(new DisplayList(), chart.Chart, 0, 0, 640, 400);
File.WriteAllBytes("chart.png", ChartHost.RenderPng(chart.Chart, 480, 300));
Console.WriteLine($"Frame: {frame.Name}");
Console.WriteLine("Wrote chart.png (960 x 600)");
Console.WriteLine($"Reader notes: {chart.Chart.Notes.Count}");
foreach (var note in chart.Chart.Notes) Console.WriteLine(note);
Console.WriteLine($"Layout notes: {layout.Notes.Count}");
foreach (var note in layout.Notes) Console.WriteLine(note);
```

`dotnet run` prints:

```text
Frame: Sales chart
Wrote chart.png (960 x 600)
Reader notes: 0
Layout notes: 0
```

<img src="/assets/onedocument/extract-excel-chart-as-png/chart.png" alt="Rendered Sales column chart: Jan 10, Feb 20, Mar 15" width="960" height="600" loading="lazy">

The full program throws `InvalidDataException` if its drawing, frame or chart cannot be found; the short snippet assumes the supplied sample is present.

## Variations

**Change image size.** The dimensions passed to `RenderPng` are points, not output pixels.

```csharp
using RecursiveAI.OneDocument.Charts;
using RecursiveAI.OneDocument.Packaging;
using var package =
    OpcPackage.Open("chart.xlsx");
var name = ChartHost.FindChartParts(package)[0];
var chart = ChartHost.LoadPart(package, name)!;
File.WriteAllBytes("chart-small.png",
    ChartHost.RenderPng(chart.Chart, 240, 150));
Console.WriteLine("Wrote chart-small.png (480 x 300)");
```

```text
Wrote chart-small.png (480 x 300)
```

## Related recipes

- [Recalculate Excel formulas](https://recursiveai.org/onedocument/cookbook/recalculate-excel-formulas/)
- [Convert Excel to PDF](https://recursiveai.org/onedocument/cookbook/convert-excel-to-pdf/)

---

## The short answer

To export an Excel chart to PNG in C#, install OneDocument’s Rendering package, open the XLSX package, load a chart with `ChartHost`, and write the bytes returned by `RenderPng`. This exports a chart on its own: it is not a screenshot of the sheet, its surrounding cells, or other drawing objects.

The short snippet selects the first chart part in package order. That is enough for the supplied one-chart sample. The full program uses `ChartFrames.Find` on a spreadsheet drawing so that it can identify the chart by its frame and resolve the correct relationship. That is the more useful route when a workbook has several charts and placement or names matter.

## How to export Excel chart as png?

Open the XLSX package, load the chart with `ChartHost`, then write the bytes from `ChartHost.RenderPng`.

Load the drawing part containing the chart, parse its markup and inspect the frames. Each frame carries the chart relationship ID, name and description when present. `ChartHost.Load` resolves that relationship relative to the drawing part. It returns null if the relationship, part or readable chart XML is missing, so check before rendering.

Drawing paths and frame order vary by workbook. The full program uses the known path from the included input. In an application handling arbitrary workbooks, select the drawing linked from the worksheet you need instead of assuming every chart lives in drawing1.xml. The [chart documentation](https://recursiveai.org/onedocument/docs/charts/) describes the frame and host APIs.

`ChartHost.RenderPng` accepts width and height in points and renders at 144 dpi. A width of 480 points therefore gives 960 output pixels; 300 points gives 600. The variation halves those dimensions. Pick the output aspect ratio deliberately: this call lays the chart out in the box you request rather than cropping a preexisting worksheet image.

## How can I export a chart from Excel?

First decide whether you need the stored chart or updated data. Chart reading uses cached series and category data or literals. It recalculates nothing. If cells have changed but chart caches have not, an export can legitimately show earlier values. `ChartRefresh.Refresh` can replace the model’s caches from an `IChartDataSource`; `ChartHost.WorkbookSource` reads stored workbook cell values. Calculation and chart refresh are separate operations.

Inspect `ChartSpace.Notes` and `ChartLayoutInfo.Notes`, as the full program does. A PNG file can be produced even when a feature was approximated: 3-D charts are flattened, a region map can become a placeholder, and an unknown layout is reported. The documented notes include `chart.3d-flattened`, `chart.region-map`, `chart.layout-unknown` and `chart.font-missing`. A successful file write alone does not mean the image reproduces every Excel feature.

## How to convert Excel to png?

For a single chart, use this recipe. For a worksheet page with cells, use [Excel rendering](https://recursiveai.org/onedocument/docs/spreadsheet-rendering/) and [page image export](https://recursiveai.org/onedocument/docs/rendering-export/) instead. Those are different outputs: a chart image has its own requested box, while a worksheet page follows printing and page-layout rules.

The standalone chart renderer also exposes `WritePdf` for a chart-only PDF. Neither that call nor this PNG export edits the original chart part in the workbook. Model setters change the in-memory chart only; the pinned release has no chart model writer. Keep the original workbook if you need its editable chart, and distribute the PNG as a separate rendered artifact.
