xiaohongshu
xiaohongshu
aspose-slides
Comprehensive skill for manipulating Microsoft PowerPoint presentations using Aspose.Slides.NET library with modern C# patterns
Full skill instructions
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.
xiaohongshu
technical spec
product ux expert
database patterns
Conduct multi-agent task orchestration and workflow coordination.
Initialize project with Conductor artifacts (product definition,
Expert in web animations, transitions, and motion design using Framer Motion and CSS
Creates Mermaid and ASCII diagrams for flowcharts, architecture, ERDs, state machines, mindmaps, and more. Use when user mentions diagram, flowchart, mermaid, ASCII diagram, text diagram, terminal diagram, visualize, C4, mindmap, architecture diagram, sequence diagram, ERD, or needs visual docume...
PostgreSQL bindings for H3 hexagonal grid system. Use when working with H3 cells in Postgres, including spatial indexing, geometry/geography integration, and raster analysis.
Context-Driven Development skill for projects using Conductor. Use this skill when you detect a `conductor/` directory in the project, when working on tasks defined in a `plan.md` file, or when the user asks about tracks, specs, or plans. Automatically applies TDD workflow, tracks task completion...
Display project status, active tracks, and next actions
Official Stakpak application containerization standard operating procedure, a step-by-step guidline to properly dockerize applications. This is a rule book curated by the Stakpak Team.
Generate, edit, and beat-sync AI video with leading models in one workspace.
The world's fastest calendar for remote work
Transform Your Design with AI Designer by ImgCreator.ai
Revolutionizing Video Production with AI-Powered Creativity
Extend an image past the frame and let AI fill the new aspect ratio.
Discover your celebrity doppelgänger with StarByFace!
ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.
Opus.ai: Revolutionize Your Web Experience