ESShape 1.0.3
dotnet add package ESShape --version 1.0.3
NuGet\Install-Package ESShape -Version 1.0.3
<PackageReference Include="ESShape" Version="1.0.3" />
<PackageVersion Include="ESShape" Version="1.0.3" />
<PackageReference Include="ESShape" />
paket add ESShape --version 1.0.3
#r "nuget: ESShape, 1.0.3"
#:package ESShape@1.0.3
#addin nuget:?package=ESShape&version=1.0.3
#tool nuget:?package=ESShape&version=1.0.3
<h3 align="center">
<picture> <source media="(prefers-color-scheme: dark)" srcset="./assets/logo-dark.png"> <source media="(prefers-color-scheme: light)" srcset="./assets/logo.png"> <img alt="ShapeCrawler" src="./assets/logo.png"> </picture>
</h3>
<h3 align="center">
</h3>
<p align="center"> <strong>PowerPoint (PPTX) manipulation library for .NET / C# developers</strong> </p>
ShapeCrawler provides a clean, intuitive API on top of the Open XML SDK, making it easy to read, create, and modify .pptx files programmatically.
π¦ Installation
dotnet add package ShapeCrawler
π Getting Started
// Load an existing presentation
var pres = new Presentation("presentation.pptx");
// Access shapes on a slide
var shapes = pres.Slide(1).Shapes;
var textBox = shapes.Shape("TextBox 1");
// Read text content
var text = textBox.TextBox.Text;
// Modify and save
textBox.TextBox.SetText("Updated content");
pres.Save();
π― Why ShapeCrawler?
- No Office Required β Process presentations on any platform without Microsoft Office installation
- Clean API β Intuitive object model that hides the complexity of Open XML
- Open Source β Actively maintained
π‘ Common Use Cases
Create presentations
// Create a new presentation with a slide
var pres = new Presentation(p => p.Slide());
// Add a shape with text
var shapes = pres.Slide(1).Shapes;
shapes.AddShape(x: 50, y: 60, width: 100, height: 70);
var addedShape = shapes.Last();
addedShape.TextBox.SetText("Hello World!");
pres.Save("output.pptx");
Update image
var pres = new Presentation("presentation.pptx");
var picture = pres.Slide(1).Shape("Picture 1").Picture;
// Replace the image
using var newImage = File.OpenRead("new-image.png");
picture.Image.Update(newImage);
pres.Save();
Tables
Create table
var pres = new Presentation("presentation.pptx");
var shapes = pres.Slide(1).Shapes;
// Add a 3x2 table at position (50, 120)
shapes.AddTable(x: 50, y: 120, columnsCount: 3, rowsCount: 2);
var table = shapes.Last().Table;
table[0, 0].TextBox.SetText("Hello table");
pres.Save();
Update table
var pres = new Presentation("presentation.pptx");
var table = pres.Slide(1).Shapes.Shape("Table 1").Table;
// Insert a row at index 1, using row 0 as a template
table.Rows.Add(1, 0);
// Merge two header cells
table.MergeCells(table[0, 0], table[0, 1]);
pres.Save();
Lines
Adding a straight line
var pres = new Presentation("presentation.pptx");
var shapes = pres.Slide(1).Shapes;
// Add a line from (50, 60) to (100, 60)
shapes.AddLine(startPointX: 50, startPointY: 60, endPointX: 100, endPointY: 60);
Accessing Start and End Points
var pres = new Presentation("presentation.pptx");
var line = pres.Slide(1).Shapes.First(shape => shape.GeometryType == Geometry.Line).Line;
var start = line.StartPoint; // Point(x, y)
var end = line.EndPoint; // Point(x, y)
Console.WriteLine($"Line from {start.X},{start.Y} to {end.X},{end.Y}");
Charts
Create Bar Chart
var pres = new Presentation(p => p.Slide());
var shapes = pres.Slide(1).Shapes;
var points = new Dictionary<string, double>
{
{ "Q1", 50 },
{ "Q2", 60 },
{ "Q3", 40 }
};
// Add a bar chart
shapes.AddBarChart(x: 100, y: 100, width: 500, height: 350, points, "Sales");
pres.Save("output.pptx");
Update Chart Category
var pres = new Presentation("presentation.pptx");
var chart = pres.Slide(1).Shapes.Shape("Bar Chart 1").BarChart;
// Update category name
chart.Categories[0].Name = "Renamed Category";
pres.Save();
More Examples
β Getting Help
Have questions? We're here to help!
- Issues β Report bugs or request features
- Discussions Forum β Ask questions and share ideas
- Email β Reach out to theadamo86@gmail.com
π€ Contributing
We love contributions! Here's how you can help:
- Give us a star β β If you find ShapeCrawler useful, show your support with a star!
- Reporting Bugs β Found a bug? Open an issue with a clear description of the problem
- Contribute Code β Pull requests are welcome!
- Need to share a confidential file? β Email it to theadamo86@gmail.com β only the maintainer will access it
π Pre-release Versions
Want to try the latest features? Access pre-release builds from the master branch using the following NuGet: https://www.myget.org/F/shape/api/v3/index.json
π Changelog
Version 0.79.0 - 2026-03-31
πAdded Presentation.Properties.Company
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- DocumentFormat.OpenXml (>= 3.5.1)
- DocumentFormat.OpenXml.Linq (>= 3.5.1)
- Magick.NET-Q16-AnyCPU (>= 14.11.1)
- SkiaSharp (>= 3.119.2)
- SkiaSharp.NativeAssets.Linux (>= 3.119.2)
- System.Resources.Extensions (>= 10.0.3)
-
net10.0
- DocumentFormat.OpenXml (>= 3.5.1)
- DocumentFormat.OpenXml.Linq (>= 3.5.1)
- Magick.NET-Q16-AnyCPU (>= 14.11.1)
- SkiaSharp (>= 3.119.2)
- SkiaSharp.NativeAssets.Linux (>= 3.119.2)
- System.Resources.Extensions (>= 10.0.3)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Fixed table row insert/remove corrupting PPTX: no longer changes shape extent; cloned rows clear merge flags; MergeColumnRangeVertically clears stale merges; ApplyFixedTableHeight redistributes row heights inside a fixed table size.