Nano Banana Pro
Agent skill for nano-banana-pro
Comprehensive skill for manipulating Microsoft PowerPoint presentations using Aspose.Slides.NET library with modern C# patterns
Sign in to like and favorite skills
This skill enables Claude Code to effectively manipulate Microsoft PowerPoint presentations using the Aspose.Slides.NET library. It provides comprehensive guidance for working with presentations programmatically without requiring Microsoft PowerPoint installation.
Presentation (IPresentation) ├── Slides (ISlideCollection) │ ├── Slide (ISlide) │ │ ├── Shapes (IShapeCollection) │ │ │ ├── AutoShape (IAutoShape) │ │ │ ├── Table (ITable) │ │ │ ├── Chart (IChart) │ │ │ ├── PictureFrame (IPictureFrame) │ │ │ └── GroupShape (IGroupShape) │ │ ├── Background (IBackground) │ │ └── SlideShowTransition │ └── NotesSlide (INotesSlide) ├── Masters (IMasterSlideCollection) │ └── MasterSlide (IMasterSlide) ├── Layouts (ILayoutSlideCollection) │ └── LayoutSlide (ILayoutSlide) └── DocumentProperties (IDocumentProperties)
TextFrame (ITextFrame) ├── Paragraphs (IParagraphCollection) │ └── Paragraph (IParagraph) │ ├── Portions (IPortionCollection) │ │ └── Portion (IPortion) │ │ └── PortionFormat (IPortionFormat) │ └── ParagraphFormat (IParagraphFormat) └── TextFrameFormat (ITextFrameFormat)
Always use
using statements for proper disposal:
using Aspose.Slides; // Single presentation using var presentation = new Presentation("input.pptx"); // Work with presentation presentation.Save("output.pptx", SaveFormat.Pptx); // Multiple resources using var sourcePresentation = new Presentation("source.pptx"); using var targetPresentation = new Presentation(); // Combine presentations
Leverage LINQ and functional patterns:
// Find shapes by type var textShapes = slide.Shapes .OfType<IAutoShape>() .Where(s => s.TextFrame != null) .ToList(); // Process all text portions var allText = slide.Shapes .OfType<IAutoShape>() .Where(s => s.TextFrame != null) .SelectMany(s => s.TextFrame.Paragraphs) .SelectMany(p => p.Portions) .Select(p => p.Text); // Update text declaratively slide.Shapes .OfType<IAutoShape>() .Where(s => s.Name == "Title") .Select(s => s.TextFrame) .Where(tf => tf != null) .ToList() .ForEach(tf => tf.Text = "New Title");
Use modern C# features for shape handling:
foreach (var shape in slide.Shapes) { var result = shape switch { IAutoShape autoShape when autoShape.TextFrame != null => ProcessTextShape(autoShape), ITable table => ProcessTable(table), IChart chart => ProcessChart(chart), IPictureFrame picture => ProcessImage(picture), _ => null }; }
Create helper methods for declarative configuration:
IAutoShape AddConfiguredShape( ISlide slide, ShapeType shapeType, float x, float y, float width, float height, Action<IAutoShape> configure) { var shape = slide.Shapes.AddAutoShape(shapeType, x, y, width, height); configure(shape); return shape; } // Usage var titleShape = AddConfiguredShape( slide, ShapeType.Rectangle, 50, 50, 600, 100, shape => { shape.TextFrame.Text = "Title"; shape.FillFormat.FillType = FillType.Solid; shape.FillFormat.SolidFillColor.Color = Color.Blue; });
using var presentation = new Presentation("template.pptx"); // Populate placeholder text foreach (var slide in presentation.Slides) { foreach (var shape in slide.Shapes.OfType<IAutoShape>()) { if (shape.Placeholder != null) { var placeholderType = shape.Placeholder.Type; shape.TextFrame.Text = placeholderType switch { PlaceholderType.Title => "Dynamic Title", PlaceholderType.Body => "Dynamic Content", _ => shape.TextFrame.Text }; } } } presentation.Save("output.pptx", SaveFormat.Pptx);
// Define table dimensions var columnWidths = new[] { 100.0, 150.0, 200.0 }; var rowHeights = new[] { 50.0, 40.0, 40.0, 40.0 }; var table = slide.Shapes.AddTable( x: 50, y: 50, columnWidths, rowHeights); // Populate headers var headers = new[] { "Name", "Value", "Description" }; for (int col = 0; col < headers.Length; col++) { table[col, 0].TextFrame.Text = headers[col]; table[col, 0].CellFormat.FillFormat.FillType = FillType.Solid; table[col, 0].CellFormat.FillFormat.SolidFillColor.Color = Color.FromArgb(68, 114, 196); table[col, 0].TextFrame.Paragraphs[0].Portions[0].PortionFormat .FillFormat.SolidFillColor.Color = Color.White; } // Populate data rows var data = new[] { new[] { "Item 1", "100", "First item" }, new[] { "Item 2", "200", "Second item" }, new[] { "Item 3", "300", "Third item" } }; for (int row = 0; row < data.Length; row++) { for (int col = 0; col < data[row].Length; col++) { table[col, row + 1].TextFrame.Text = data[row][col]; } }
// Add chart to slide var chart = slide.Shapes.AddChart( ChartType.ClusteredColumn, x: 50, y: 50, width: 500, height: 400); // Clear default data chart.ChartData.Series.Clear(); chart.ChartData.Categories.Clear(); // Set categories var categories = new[] { "Q1", "Q2", "Q3", "Q4" }; foreach (var category in categories) { chart.ChartData.Categories.Add( chart.ChartData.ChartDataWorkbook.GetCell(0, 0, 0, category)); } // Add data series var series1 = chart.ChartData.Series.Add( chart.ChartData.ChartDataWorkbook.GetCell(0, 0, 1, "Sales"), chart.Type); var salesData = new[] { 120, 150, 180, 160 }; for (int i = 0; i < salesData.Length; i++) { series1.DataPoints.AddDataPointForBarSeries( chart.ChartData.ChartDataWorkbook.GetCell(0, i + 1, 1, salesData[i])); } // Style the chart series1.Format.Fill.FillType = FillType.Solid; series1.Format.Fill.SolidFillColor.Color = Color.FromArgb(68, 114, 196); chart.HasTitle = true; chart.ChartTitle.AddTextFrameForOverriding("Quarterly Sales");
void ReplaceTextPreservingFormat( IPresentation presentation, string searchText, string replacementText) { foreach (var slide in presentation.Slides) { foreach (var shape in slide.Shapes.OfType<IAutoShape>()) { if (shape.TextFrame == null) continue; foreach (var paragraph in shape.TextFrame.Paragraphs) { foreach (var portion in paragraph.Portions) { if (portion.Text.Contains(searchText)) { portion.Text = portion.Text.Replace( searchText, replacementText); } } } } } }
// Add image from file using var image = Image.FromFile("logo.png"); var ppImage = presentation.Images.AddImage(image); var pictureFrame = slide.Shapes.AddPictureFrame( ShapeType.Rectangle, x: 100, y: 100, width: 200, height: 150, ppImage); // Extract all images from presentation var imageIndex = 0; foreach (var slide in presentation.Slides) { foreach (var shape in slide.Shapes.OfType<IPictureFrame>()) { var image = shape.PictureFormat.Picture.Image.SystemImage; image.Save($"extracted_image_{imageIndex++}.png"); } }
For data-driven presentations, use a declarative approach:
public class SlideDataModel { public string Title { get; set; } public List<BulletPoint> BulletPoints { get; set; } public TableData TableData { get; set; } public ChartData ChartData { get; set; } } void PopulateSlideFromJson(ISlide slide, SlideDataModel data) { // Update title var titleShape = slide.Shapes .OfType<IAutoShape>() .FirstOrDefault(s => s.Placeholder?.Type == PlaceholderType.Title); if (titleShape != null && data.Title != null) { titleShape.TextFrame.Text = data.Title; } // Update bullet points var bodyShape = slide.Shapes .OfType<IAutoShape>() .FirstOrDefault(s => s.Placeholder?.Type == PlaceholderType.Body); if (bodyShape != null && data.BulletPoints != null) { bodyShape.TextFrame.Paragraphs.Clear(); foreach (var bullet in data.BulletPoints) { var paragraph = new Paragraph(); paragraph.Text = bullet.Text; paragraph.ParagraphFormat.Bullet.Type = BulletType.Symbol; bodyShape.TextFrame.Paragraphs.Add(paragraph); } } // Populate table if present if (data.TableData != null) { PopulateTable(slide, data.TableData); } // Populate chart if present if (data.ChartData != null) { PopulateChart(slide, data.ChartData); } }
// Use BlobManagementOptions for large presentations var blobOptions = new BlobManagementOptions { PresentationLockingBehavior = PresentationLockingBehavior.KeepLocked, IsTemporaryFilesAllowed = true, TempFilesRootPath = Path.GetTempPath() }; var loadOptions = new LoadOptions { BlobManagementOptions = blobOptions }; using var presentation = new Presentation("large.pptx", loadOptions);
async Task ProcessPresentationsAsync(IEnumerable<string> files) { var processingTasks = files.Select(async file => { using var presentation = new Presentation(file); // Process presentation await Task.Run(() => ProcessSlides(presentation)); var outputPath = Path.ChangeExtension(file, ".processed.pptx"); presentation.Save(outputPath, SaveFormat.Pptx); }); await Task.WhenAll(processingTasks); }
Result<Presentation> LoadPresentationSafely(string path) { try { var presentation = new Presentation(path); return Result<Presentation>.Success(presentation); } catch (Exception ex) when (ex is InvalidOperationException or IOException) { return Result<Presentation>.Failure($"Failed to load presentation: {ex.Message}"); } } // Usage with pattern matching var result = LoadPresentationSafely("presentation.pptx"); result switch { { IsSuccess: true } => ProcessPresentation(result.Value), { IsSuccess: false } => LogError(result.Error) };
var pdfOptions = new PdfOptions { Compliance = PdfCompliance.Pdf15, JpegQuality = 90, TextCompression = PdfTextCompression.Flate, EmbedFullFonts = true, DrawSlidesFrame = false }; // Include notes in PDF pdfOptions.NotesCommentsLayouting.NotesPosition = NotesPositions.BottomFull; presentation.Save("output.pdf", SaveFormat.Pdf, pdfOptions);
var htmlOptions = new HtmlOptions { EmbedImages = true, HtmlFormatter = HtmlFormatter.CreateDocumentFormatter(string.Empty, false) }; presentation.Save("output.html", SaveFormat.Html, htmlOptions);
foreach (var slide in presentation.Slides) { using var bitmap = slide.GetThumbnail(2.0f, 2.0f); // 2x scale bitmap.Save( $"slide_{slide.SlideNumber}.png", System.Drawing.Imaging.ImageFormat.Png); }
Solution: Use slide dimensions as reference
var slideWidth = presentation.SlideSize.Size.Width; var slideHeight = presentation.SlideSize.Size.Height; // Center shape var shape = slide.Shapes.AddAutoShape( ShapeType.Rectangle, x: (slideWidth - shapeWidth) / 2, y: (slideHeight - shapeHeight) / 2, width: shapeWidth, height: shapeHeight);
Solution: Enable auto-fit or adjust shape size
var textFrame = shape.TextFrame; textFrame.TextFrameFormat.AutofitType = TextAutofitType.Shape; // or textFrame.TextFrameFormat.AutofitType = TextAutofitType.Normal;
Solution: Embed fonts explicitly
var fontData = File.ReadAllBytes("customfont.ttf"); presentation.FontsManager.AddEmbeddedFont(fontData, EmbedFontCharacters.All);
Solution: Refresh chart data workbook
chart.ChartData.ChartDataWorkbook.Clear(0); // Re-populate data
When implementing Aspose.Slides functionality:
Start with the desired outcome and work backward:
// Goal: Create a data-driven presentation from JSON // 1. Define the data structure var slideData = JsonSerializer.Deserialize<PresentationData>(jsonContent); // 2. Load or create presentation using var presentation = LoadTemplate("template.pptx") ?? CreateNewPresentation(); // 3. Apply data to slides foreach (var (slide, data) in presentation.Slides.Zip(slideData.Slides)) { ApplyDataToSlide(slide, data); } // 4. Save with appropriate options SavePresentation(presentation, "output.pptx", slideData.ExportOptions);
This skill enables Claude Code to manipulate PowerPoint presentations using modern C# patterns with Aspose.Slides. Focus on:
using statementsWhen tackling a new task, understand the object hierarchy, leverage LINQ for collection operations, and prefer composition over complex imperative code.