{"id":27296155,"url":"https://github.com/shapecrawler/shapecrawler","last_synced_at":"2026-02-27T22:44:06.159Z","repository":{"id":38081830,"uuid":"196728321","full_name":"ShapeCrawler/ShapeCrawler","owner":"ShapeCrawler","description":"🍂 A .NET library for manipulating PowerPoint presentations","archived":false,"fork":false,"pushed_at":"2025-04-11T16:54:46.000Z","size":69605,"stargazers_count":344,"open_issues_count":63,"forks_count":69,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-04-11T17:13:42.541Z","etag":null,"topics":["csharp","dotnet","hacktoberfest","ooxml","openxml","powerpoint","powerpoint-presentations","pptx","presentation","shapecrawler","slide"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ShapeCrawler.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"adamshakhabov"}},"created_at":"2019-07-13T14:04:02.000Z","updated_at":"2025-04-11T16:51:47.000Z","dependencies_parsed_at":"2023-10-12T00:58:00.643Z","dependency_job_id":"76542989-fac7-4ff3-9cf0-92f521ce5cd8","html_url":"https://github.com/ShapeCrawler/ShapeCrawler","commit_stats":{"total_commits":591,"total_committers":9,"mean_commits":65.66666666666667,"dds":"0.045685279187817285","last_synced_commit":"c3977d6ecd18bfd3dd01c9677656f209f182d50b"},"previous_names":["adamshakhabov/slidedotnet"],"tags_count":88,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ShapeCrawler%2FShapeCrawler","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ShapeCrawler%2FShapeCrawler/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ShapeCrawler%2FShapeCrawler/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ShapeCrawler%2FShapeCrawler/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ShapeCrawler","download_url":"https://codeload.github.com/ShapeCrawler/ShapeCrawler/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248494669,"owners_count":21113476,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["csharp","dotnet","hacktoberfest","ooxml","openxml","powerpoint","powerpoint-presentations","pptx","presentation","shapecrawler","slide"],"created_at":"2025-04-11T23:30:35.304Z","updated_at":"2026-02-27T22:44:06.148Z","avatar_url":"https://github.com/ShapeCrawler.png","language":"C#","readme":"\u003ch3 align=\"center\"\u003e\r\n\r\n\u003cpicture\u003e\r\n  \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"./assets/logo-dark.png\"\u003e\r\n  \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"./assets/logo.png\"\u003e\r\n  \u003cimg alt=\"ShapeCrawler\" src=\"./assets/logo.png\"\u003e\r\n\u003c/picture\u003e\r\n\r\n\u003c/h3\u003e\r\n\r\n\u003ch3 align=\"center\"\u003e \r\n\r\n[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?color=orange)](https://makeapullrequest.com)\r\n![Nuget](https://img.shields.io/nuget/dt/ShapeCrawler?color=orange)\r\n[![GitHub Help Wanted issues](https://img.shields.io/github/issues/ShapeCrawler/ShapeCrawler/help%20wanted?style=flat\u0026logo=github\u0026logoColor=b545d1\u0026label=%22Help%20Wanted%22%20issues)](https://github.com/ShapeCrawler/ShapeCrawler/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22)\r\n\r\n\u003c/h3\u003e\r\n\r\n\u003cp align=\"center\"\u003e\r\n  \u003cstrong\u003ePowerPoint (PPTX) manipulation library for .NET / C# developers\u003c/strong\u003e\r\n\u003c/p\u003e\r\n\r\nShapeCrawler provides a clean, intuitive API on top of the Open XML SDK, making it easy to read, create, and modify `.pptx` files programmatically.\r\n\r\n---\r\n\r\n## 📦 Installation\r\n\r\n```bash\r\ndotnet add package ShapeCrawler\r\n```\r\n\r\n## 🚀 Getting Started\r\n\r\n```csharp\r\n// Load an existing presentation\r\nvar pres = new Presentation(\"presentation.pptx\");\r\n\r\n// Access shapes on a slide\r\nvar shapes = pres.Slide(1).Shapes;\r\nvar textBox = shapes.Shape(\"TextBox 1\");\r\n\r\n// Read text content\r\nvar text = textBox.TextBox.Text;\r\n\r\n// Modify and save\r\ntextBox.TextBox.SetText(\"Updated content\");\r\npres.Save();\r\n```\r\n\r\n## 🎯 Why ShapeCrawler?\r\n\r\n- **No Office Required** – Process presentations on any platform without Microsoft Office installation\r\n- **Clean API** – Intuitive object model that hides the complexity of Open XML\r\n- **Open Source** — Actively maintained\r\n\r\n## 💡 Common Use Cases\r\n\r\n### Create presentations\r\n\r\n```csharp\r\n// Create a new presentation with a slide\r\nvar pres = new Presentation(p =\u003e p.Slide());\r\n\r\n// Add a shape with text\r\nvar shapes = pres.Slide(1).Shapes;\r\nshapes.AddShape(x: 50, y: 60, width: 100, height: 70);\r\n\r\nvar addedShape = shapes.Last();\r\naddedShape.TextBox.SetText(\"Hello World!\");\r\n\r\npres.Save(\"output.pptx\");\r\n```\r\n\r\n### Update image\r\n\r\n```csharp\r\nvar pres = new Presentation(\"presentation.pptx\");\r\nvar picture = pres.Slide(1).Shape(\"Picture 1\").Picture;\r\n\r\n// Replace the image\r\nusing var newImage = File.OpenRead(\"new-image.png\");\r\npicture.Image.Update(newImage);\r\n\r\npres.Save();\r\n```\r\n\r\n### Tables\r\n\r\n#### Create table\r\n\r\n```csharp\r\nvar pres = new Presentation(\"presentation.pptx\");\r\nvar shapes = pres.Slide(1).Shapes;\r\n\r\n// Add a 3x2 table at position (50, 120)\r\nshapes.AddTable(x: 50, y: 120, columnsCount: 3, rowsCount: 2);\r\n\r\nvar table = shapes.Last().Table;\r\ntable[0, 0].TextBox.SetText(\"Hello table\");\r\n\r\npres.Save();\r\n```\r\n\r\n#### Update table\r\n\r\n```csharp\r\nvar pres = new Presentation(\"presentation.pptx\");\r\nvar table = pres.Slide(1).Shapes.Shape(\"Table 1\").Table;\r\n\r\n// Insert a row at index 1, using row 0 as a template\r\ntable.Rows.Add(1, 0);\r\n\r\n// Merge two header cells\r\ntable.MergeCells(table[0, 0], table[0, 1]);\r\n\r\npres.Save();\r\n```\r\n\r\n### Lines\r\n\r\n#### Adding a straight line\r\n\r\n```csharp\r\nvar pres = new Presentation(\"presentation.pptx\");\r\nvar shapes = pres.Slide(1).Shapes;\r\n\r\n// Add a line from (50, 60) to (100, 60)\r\nshapes.AddLine(startPointX: 50, startPointY: 60, endPointX: 100, endPointY: 60);\r\n```\r\n\r\n#### Accessing Start and End Points\r\n\r\n```csharp\r\nvar pres = new Presentation(\"presentation.pptx\");\r\nvar line = pres.Slide(1).Shapes.First(shape =\u003e shape.GeometryType == Geometry.Line).Line;\r\n\r\nvar start = line.StartPoint; // Point(x, y)\r\nvar end = line.EndPoint;     // Point(x, y)\r\nConsole.WriteLine($\"Line from {start.X},{start.Y} to {end.X},{end.Y}\");\r\n```\r\n\r\n### Charts\r\n\r\n#### Create Bar Chart\r\n\r\n```csharp\r\nvar pres = new Presentation(p =\u003e p.Slide());\r\nvar shapes = pres.Slide(1).Shapes;\r\n\r\nvar points = new Dictionary\u003cstring, double\u003e\r\n{\r\n    { \"Q1\", 50 },\r\n    { \"Q2\", 60 },\r\n    { \"Q3\", 40 }\r\n};\r\n\r\n// Add a bar chart\r\nshapes.AddBarChart(x: 100, y: 100, width: 500, height: 350, points, \"Sales\");\r\n\r\npres.Save(\"output.pptx\");\r\n```\r\n\r\n#### Update Chart Category\r\n\r\n```csharp\r\nvar pres = new Presentation(\"presentation.pptx\");\r\nvar chart = pres.Slide(1).Shapes.Shape(\"Bar Chart 1\").BarChart;\r\n\r\n// Update category name\r\nchart.Categories[0].Name = \"Renamed Category\";\r\n\r\npres.Save();\r\n```\r\n\r\n### More Examples\r\n\r\n**[See More Examples](https://github.com/ShapeCrawler/ShapeCrawler/tree/master/examples)**\r\n\r\n## ❓ Getting Help\r\n\r\nHave questions? We're here to help!\r\n\r\n- [Issues](https://github.com/ShapeCrawler/ShapeCrawler/issues) – Report bugs or request features\r\n- [Discussions Forum](https://github.com/ShapeCrawler/ShapeCrawler/discussions) – Ask questions and share ideas\r\n- Email – Reach out to theadamo86@gmail.com\r\n\r\n## 🤝 Contributing\r\n\r\nWe love contributions! Here's how you can help:\r\n\r\n- Give us a star ⭐ – If you find ShapeCrawler useful, show your support with a star!\r\n- Reporting Bugs – Found a bug? [Open an issue](https://github.com/ShapeCrawler/ShapeCrawler/issues) with a clear description of the problem\r\n- Contribute Code – Pull requests are welcome!\r\n- Need to share a confidential file? – Email it to theadamo86@gmail.com – only the maintainer will access it\r\n\r\n## 🔄 Pre-release Versions\r\n\r\nWant 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`\r\n\r\n## 📝 Changelog\r\n\r\n### Version 0.78.3 - 2026-02-27\r\n🐞Resolved potential security vulnerabilities\r\n\r\n[**View Full Changelog**](https://github.com/ShapeCrawler/ShapeCrawler/blob/master/CHANGELOG.md)\r\n","funding_links":["https://github.com/sponsors/adamshakhabov"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshapecrawler%2Fshapecrawler","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fshapecrawler%2Fshapecrawler","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshapecrawler%2Fshapecrawler/lists"}