Add Background Images to Excel Shapes Programmatically
Introduction
Ever spent hours manually adding background images to shapes across multiple Excel spreadsheets? Or struggled to maintain consistent branding across dozens of worksheets? You’re not alone—and there’s a better way.
If you’re working with Excel documents that need professional formatting (think branded reports, educational materials, or marketing sheets), manually setting background images for shapes is tedious and error-prone. One wrong click, and you’re starting over. Multiply that across 50 shapes or 20 workbooks, and you’ve lost your afternoon.
This guide shows you how to automate the entire process using GroupDocs.Watermark for .NET. You’ll learn to programmatically apply background images to Excel shapes with full control over transparency, tiling, and targeting—all in a few lines of C# code. Whether you’re processing one file or a thousand, this approach saves time and ensures consistency.
What you’ll learn:
- How to identify and target specific shapes in Excel worksheets
- Setting background images with custom transparency and texture options
- Handling common issues like image sizing and file path problems
- Performance optimization for large-scale operations
- Real-world use cases and when to apply this technique
Let’s dive in—starting with why you’d want to automate this in the first place.
Why Automate Shape Background Images?
Before we jump into code, here’s why automation matters for this task:
The Manual Approach Problems:
- Time-consuming: Right-clicking each shape, navigating through format menus, selecting images—it adds up fast
- Inconsistency risk: Different team members might use different settings (transparency levels, image alignment)
- No version control: Hard to track what changes were made or roll back mistakes
- Scalability issues: Works fine for 5 shapes, becomes a nightmare for 500
The Automated Approach Benefits:
- Speed: Process hundreds of shapes across multiple workbooks in seconds
- Consistency: Same settings applied every time, no human error
- Maintainability: Change the image or settings once, re-run for all files
- Integration: Easily fits into existing document processing pipelines
- Batch processing: Handle entire directories of Excel files overnight
When to use this automation:
- You’re generating templated reports that need branded backgrounds
- Educational materials require consistent visual elements across multiple files
- Marketing teams need to update campaign imagery across existing spreadsheets
- You’re maintaining corporate templates with specific shape formatting standards
When manual might be better:
- One-off tasks with just a few shapes (overhead might not be worth it)
- You need pixel-perfect visual adjustment that’s easier to judge by eye
- The shapes and requirements change frequently and unpredictably
Now that you know why this matters, let’s get your environment set up.
Prerequisites
Before you start coding, make sure you’ve got these bases covered:
Required Libraries and Dependencies
1. GroupDocs.Watermark for .NET This is your main tool—it handles not just watermarks but also shape manipulation in Excel files. The library provides a clean API for accessing and modifying spreadsheet elements programmatically.
2. Visual Studio (or your preferred IDE) Any recent version works (2019, 2022, or VS Code with C# extensions). You just need something that supports .NET development and makes debugging easier.
Environment Setup Requirements
Operating System: Windows, macOS, or Linux (GroupDocs.Watermark is cross-platform)
.NET Version: You’ll need .NET Core 3.1+ or .NET Framework 4.6.1+. The library supports both, so use whichever fits your existing project setup.
Disk Space: Minimal—the library itself is lightweight, but make sure you have space for your Excel files and image assets.
Knowledge Prerequisites
Must-have:
- Basic C# syntax (variables, methods, using statements)
- Understanding of file paths and how to reference files in your project
Nice-to-have:
- Familiarity with Excel’s object model (worksheets, shapes, cells)
- Experience with NuGet package management
- Basic understanding of image formats and properties
Don’t worry if you’re missing some of these—we’ll explain everything as we go. The code examples are designed to be clear even if you’re relatively new to C# or Excel automation.
Setting Up GroupDocs.Watermark for .NET
Getting the library into your project is straightforward. Choose whichever method fits your workflow:
Installation Options
Option 1: .NET CLI (Fastest for command-line users)
dotnet add package GroupDocs.Watermark
Option 2: Package Manager Console (If you’re already in Visual Studio)
Install-Package GroupDocs.Watermark
Option 3: NuGet Package Manager UI (Most visual approach)
- Right-click your project in Solution Explorer
- Select “Manage NuGet Packages”
- Search for “GroupDocs.Watermark”
- Click Install on the latest stable version
License Acquisition
GroupDocs offers flexible licensing options depending on your needs:
1. Free Trial Perfect for evaluating the library and building proof-of-concepts. It has some limitations (like watermarking output files), but you can test all the functionality we’re covering today.
2. Temporary License Need more time or want to test in a production-like environment? Request a temporary license from GroupDocs—it gives you full access for a limited period (usually 30 days).
3. Full License For production use, you’ll want to purchase a license. GroupDocs offers different tiers based on deployment scope (single developer, site-wide, OEM, etc.).
Pro tip: Start with the free trial to make sure this fits your use case, then upgrade to a temporary license if you need extended testing time.
Basic Initialization
Here’s how you initialize GroupDocs.Watermark in your code. This pattern will be your starting point for every operation:
using System;
using GroupDocs.Watermark;
class Program
{
static void Main()
{
// Initialize the Watermarker with an Excel file path.
using (Watermarker watermarker = new Watermarker("path/to/your/excel.xlsx"))
{
// Your watermarking code goes here.
// The 'using' statement ensures proper cleanup when you're done.
}
}
}
What’s happening here:
- The
usingstatement creates a Watermarker object and automatically disposes of it when the block completes (important for memory management) - You pass in the path to your Excel file—can be absolute or relative to your project
- All your shape manipulation code will go inside this
usingblock
Common gotcha: Make sure the file path is correct and the file isn’t open in Excel when you run the code. Excel locks files when they’re open, which will cause an error.
Now that you’re set up, let’s get into the actual implementation.
Implementation Guide
Setting Background Images for Shapes in Excel
This is where things get interesting. We’re going to walk through the complete process of identifying shapes in your Excel worksheet and applying background images to them.
Overview: What We’re Actually Doing
Think of this process like a targeted search-and-replace operation:
- Open your Excel file programmatically
- Navigate to the worksheet containing your shapes
- Loop through all shapes, looking for ones that match your criteria
- For matching shapes, load an image and set it as the background
- Configure how that background appears (transparency, tiling, etc.)
- Save your modified file
The beauty of this approach is that you can be as specific or as broad as you want. Target one shape by exact text, multiple shapes by pattern matching, or all shapes in a worksheet—it’s up to you.
Step-by-Step Implementation
Let’s build this piece by piece, with explanations for each section.
1. Load Your Excel Document
First, you need to tell GroupDocs which Excel file you’re working with and how to interpret it:
string documentPath = "YOUR_DOCUMENT_DIRECTORY/YourExcelFile.xlsx";
var loadOptions = new SpreadsheetLoadOptions();
using (Watermarker watermarker = new Watermarker(documentPath, loadOptions))
{
// Proceed with getting content of the spreadsheet.
}
What’s happening:
documentPath: Replace this with your actual file path. Can be a network path, local path, or even a path constructed dynamically based on user inputSpreadsheetLoadOptions: This tells GroupDocs “Hey, I’m loading a spreadsheet file specifically.” It optimizes loading and ensures Excel-specific features are available- The
usingblock: Ensures your file handles are properly closed, even if an error occurs
Real-world scenario: Let’s say you’re processing uploaded files from users. You might construct documentPath from a temp directory: Path.Combine(tempDir, uploadedFile.FileName). Just make sure to validate the file extension first to avoid issues.
2. Accessing Worksheet Shapes
Now you need to navigate to the specific worksheet and get access to its shapes collection:
// Get content of the spreadsheet document.
SpreadsheetContent content = watermarker.GetContent<SpreadsheetContent>();
foreach (SpreadsheetShape shape in content.Worksheets[0].Shapes)
{
// Check if the shape meets specific conditions for background modification.
if (shape.Text == "© Aspose 2016")
{
// Code to set the background image will be placed here.
}
}
Breaking this down:
GetContent<SpreadsheetContent>(): This casts the generic document content to spreadsheet-specific content, giving you access to worksheets, cells, shapes, etc.content.Worksheets[0]: Accesses the first worksheet (index 0). If you need a different worksheet, adjust the index or use.Worksheets["SheetName"]to access by name.Shapes: A collection of all shape objects on that worksheet (text boxes, images, drawn shapes, etc.)shape.Text == "© Aspose 2016": This is your targeting logic—we’re looking for shapes with this specific text
Customizing the targeting logic: You might want to target shapes differently depending on your use case:
// Target by name instead of text:
if (shape.Name.Contains("Logo"))
// Target multiple shapes with text pattern:
if (shape.Text.StartsWith("©"))
// Target ALL shapes (no condition):
// Just remove the if statement and process every shape
// Target by position:
if (shape.X < 100 && shape.Y < 100) // Top-left corner shapes
Pro tip: If you’re not sure what properties your shapes have, add a debug line inside the loop: Console.WriteLine($"Shape: {shape.Name}, Text: {shape.Text}, Type: {shape.ShapeType}");. This helps you understand what you’re working with.
3. Setting the Background Image
This is the core operation—loading an image and applying it to your targeted shapes:
// Set a background image from a predefined file path.
shape.ImageFillFormat.BackgroundImage = new SpreadsheetWatermarkableImage(
File.ReadAllBytes("YOUR_DOCUMENT_DIRECTORY/TestPng.png"));
// Customize transparency and texture tiling options.
shape.ImageFillFormat.Transparency = 0.5;
shape.ImageFillFormat.TileAsTexture = true;
Let’s unpack this:
Loading the image:
File.ReadAllBytes(): Reads your image file into a byte array. This works for PNG, JPEG, and other common formatsSpreadsheetWatermarkableImage: Wraps your byte array in an object that GroupDocs can work with- Make sure your image path is correct—relative paths are relative to your executable’s location, not your source file
Transparency setting:
Transparencyranges from 0.0 (fully opaque) to 1.0 (fully transparent)0.5means 50% transparency—your background image will be visible but won’t completely obscure any text or data in the shape- Useful when you want the image to add visual interest without dominating
Texture tiling:
TileAsTexture = true: If your image is smaller than the shape, it will repeat (tile) to fill the spaceTileAsTexture = false: The image stretches to fit the shape (may cause distortion)- For logos or branded elements, tiling is usually what you want
Real-world example: Let’s say you’re adding a subtle company logo watermark to report headers. You might use:
shape.ImageFillFormat.Transparency = 0.7; // Very subtle
shape.ImageFillFormat.TileAsTexture = false; // Stretch to fit
But for a repeating pattern background (like a subtle texture), you’d use:
shape.ImageFillFormat.Transparency = 0.3; // More visible
shape.ImageFillFormat.TileAsTexture = true; // Repeat the pattern
4. Save the Modified Excel File
Finally, you need to write your changes back to a file:
string outputFileName = "YOUR_OUTPUT_DIRECTORY/ModifiedExcelFile.xlsx";
watermarker.Save(outputFileName);
Important considerations:
- Don’t overwrite the original: Notice we’re using a different filename. This is safer—you can always compare before/after
- Output directory must exist: Make sure
YOUR_OUTPUT_DIRECTORYexists, or create it programmatically:Directory.CreateDirectory(outputPath) - File permissions: Ensure your application has write permissions to the output location
For batch processing, you might generate output filenames dynamically:
string outputFileName = Path.Combine(
outputDir,
Path.GetFileNameWithoutExtension(documentPath) + "_modified.xlsx"
);
This appends “_modified” to the original filename, making it easy to identify processed files.
Common Pitfalls and Solutions
Here are issues developers frequently run into (so you don’t have to):
Problem 1: “Shape not found” or condition never matches
- Cause: Your targeting text or property doesn’t exactly match what’s in the file
- Solution: Add debug logging to see what’s actually in your shapes. Text comparisons are case-sensitive by default—use
.Equals(text, StringComparison.OrdinalIgnoreCase)for case-insensitive matching
Problem 2: Image appears distorted or pixelated
- Cause: Image resolution doesn’t match shape size, or you’re using
TileAsTexture = falsewith a small image on a large shape - Solution: Use images with appropriate resolution for your shapes (at least 2x the display size for crisp results). For small logos, use
TileAsTexture = trueto avoid stretching
Problem 3: “File not found” errors for image paths
- Cause: Relative paths can be tricky—they’re relative to where your executable runs, not where your source code is
- Solution: Use absolute paths during development:
Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Images", "logo.png"). Or embed images as resources in your project
Problem 4: Changes don’t appear in the saved file
- Cause: You might be opening the wrong file, or the shapes are on a different worksheet than you think
- Solution: Double-check your worksheet index. Remember Excel sheets are 0-indexed in code. Add console output to confirm which worksheet you’re processing
Problem 5: Performance issues with large files
- Cause: Processing thousands of shapes or using very large images
- Solution: See the Performance Considerations section below for optimization strategies
Practical Applications
Let’s look at real-world scenarios where this technique shines:
1. Branded Financial Reports Scenario: Your finance team generates quarterly reports with 50+ sheets. Each sheet has a company logo shape in the header that needs updating when branding changes.
Implementation:
// Target all shapes with "Header Logo" in the name
if (shape.Name.Contains("Header Logo"))
{
shape.ImageFillFormat.BackgroundImage = new SpreadsheetWatermarkableImage(
File.ReadAllBytes(currentBrandLogoPath));
shape.ImageFillFormat.Transparency = 0.2; // Subtle
shape.ImageFillFormat.TileAsTexture = false; // Stretch to fit
}
Benefit: Instead of manually updating 50+ logos, you run one script. Takes 10 seconds instead of 30 minutes.
2. Educational Materials with Visual Cues Scenario: A teacher creates worksheets with shapes highlighting important concepts. Different subjects need different color-coded background patterns.
Implementation:
// Math concepts get a blue pattern, science gets green
if (shape.Text.StartsWith("[MATH]"))
{
shape.ImageFillFormat.BackgroundImage = new SpreadsheetWatermarkableImage(
File.ReadAllBytes("math_pattern.png"));
}
else if (shape.Text.StartsWith("[SCIENCE]"))
{
shape.ImageFillFormat.BackgroundImage = new SpreadsheetWatermarkableImage(
File.ReadAllBytes("science_pattern.png"));
}
shape.ImageFillFormat.TileAsTexture = true;
shape.ImageFillFormat.Transparency = 0.8; // Very subtle
Benefit: Consistent visual coding across hundreds of worksheets, maintaining student recognition of concept types.
3. Marketing Campaign Updates Scenario: A marketing team has 20 product comparison spreadsheets. When a new campaign launches, all product images in specific shapes need updating.
Implementation:
// Update product showcase shapes
if (shape.Name.StartsWith("Product_"))
{
string productId = shape.Name.Split('_')[1];
string imagePath = $"campaign2025/{productId}_hero.jpg";
if (File.Exists(imagePath))
{
shape.ImageFillFormat.BackgroundImage = new SpreadsheetWatermarkableImage(
File.ReadAllBytes(imagePath));
shape.ImageFillFormat.Transparency = 0.1;
shape.ImageFillFormat.TileAsTexture = false;
}
}
Benefit: Batch update all campaign materials in minutes, ensuring brand consistency across all documents.
4. Automated Template Generation Scenario: A SaaS platform generates custom Excel reports for clients, each needing their logo on specific shapes.
Implementation:
// Dynamic logo insertion based on client ID
string clientLogoPath = $"client_logos/{clientId}.png";
if (File.Exists(clientLogoPath) && shape.Name == "ClientLogo")
{
shape.ImageFillFormat.BackgroundImage = new SpreadsheetWatermarkableImage(
File.ReadAllBytes(clientLogoPath));
shape.ImageFillFormat.Transparency = 0.0; // Fully opaque
shape.ImageFillFormat.TileAsTexture = false;
}
Benefit: Fully automated personalization, scalable to thousands of clients without manual intervention.
Performance Considerations
When you’re working with large Excel files or processing multiple documents, performance matters. Here’s how to keep things fast:
Image Optimization Strategies
Use appropriate image sizes: Don’t load a 5MB, 4000x4000px image when your shape is 200x200px. Resize images beforehand using any image processing library (like System.Drawing or ImageSharp):
// Pseudo-code for image resizing before loading
var resizedImage = ResizeImage(originalImage, 800, 600); // Max dimensions
byte[] imageBytes = ConvertToByteArray(resizedImage);
shape.ImageFillFormat.BackgroundImage = new SpreadsheetWatermarkableImage(imageBytes);
Typical targets:
- Header logos: 400x400px is usually plenty
- Background textures: 800x800px (will tile anyway)
- Full-sheet backgrounds: Match your typical screen resolution (1920x1080)
File format matters:
- PNG: Best for logos and graphics with transparency (but larger file size)
- JPEG: Better compression for photos (smaller files, no transparency)
- For repeated use across many shapes, JPEG can significantly reduce memory usage
Memory Management Best Practices
Reuse image byte arrays when possible:
byte[] logoBytes = File.ReadAllBytes("logo.png"); // Load once
foreach (var worksheet in content.Worksheets)
{
foreach (var shape in worksheet.Shapes)
{
if (shape.Name.Contains("Logo"))
{
// Reuse the same byte array instead of re-reading the file
shape.ImageFillFormat.BackgroundImage = new SpreadsheetWatermarkableImage(logoBytes);
}
}
}
This saves disk I/O and memory allocations, especially when processing multiple worksheets or files.
Dispose of resources properly:
The using statement handles Watermarker disposal automatically, but if you’re creating custom objects or streams, make sure to dispose of them:
using (var fileStream = File.OpenRead(imagePath))
{
byte[] imageBytes = new byte[fileStream.Length];
fileStream.Read(imageBytes, 0, (int)fileStream.Length);
// Use imageBytes...
}
// fileStream automatically disposed here
Batch Processing Tips
Process files in parallel (with caution):
If you’re handling multiple Excel files, you can use Parallel.ForEach to speed things up:
var files = Directory.GetFiles(inputDirectory, "*.xlsx");
Parallel.ForEach(files, new ParallelOptions { MaxDegreeOfParallelism = 4 }, file =>
{
ProcessExcelFile(file);
});
But be careful: Each parallel operation uses memory. With very large files, you might run out of memory. Test with your typical file sizes first.
Limit operations per document: If you have 1000 shapes in a worksheet but only need to modify 10, make sure your targeting condition is efficient. Avoid expensive operations (like file I/O) inside loops:
// Bad: Reading file inside the loop
foreach (var shape in worksheet.Shapes)
{
if (shape.Name == "Logo")
{
// Reading file every iteration (expensive!)
var bytes = File.ReadAllBytes("logo.png");
shape.ImageFillFormat.BackgroundImage = new SpreadsheetWatermarkableImage(bytes);
}
}
// Good: Reading file once before the loop
var logoBytes = File.ReadAllBytes("logo.png");
foreach (var shape in worksheet.Shapes)
{
if (shape.Name == "Logo")
{
shape.ImageFillFormat.BackgroundImage = new SpreadsheetWatermarkableImage(logoBytes);
}
}
Performance Benchmarks (Typical)
Here are rough benchmarks on a modern machine (i7 processor, 16GB RAM):
- Single shape modification: <100ms
- 10 shapes in one worksheet: ~200ms
- 100 shapes across 10 worksheets: ~2-3 seconds
- Batch processing 50 files (10 shapes each): ~2-3 minutes (sequential), ~45 seconds (parallel with 4 threads)
Your mileage will vary based on file size, image sizes, and hardware, but these give you a baseline expectation.
Image Selection Best Practices
Choosing the right images makes a huge difference in the final result. Here’s what to consider:
Resolution and DPI:
- Aim for at least 150 DPI at the final display size
- For a 300x300px shape, your image should be at least 300x300px (1:1) or ideally 600x600px (2:1) for retina displays
- Going much higher than 2x is overkill and wastes file size
File Formats:
- PNG: Use for logos, graphics, anything with transparency or sharp edges
- JPEG: Use for photos or complex images where small compression artifacts won’t be noticed
- Avoid: BMP (huge file sizes), GIF (limited colors)
Color Considerations:
- If your shape will contain dark text, use lighter background images (and vice versa)
- Test your transparency settings—too opaque and you can’t read text, too transparent and the image is pointless
- Consider color contrast accessibility standards (WCAG) if your documents are public-facing
Aspect Ratios:
- If
TileAsTexture = false, make sure your image aspect ratio roughly matches your shape’s aspect ratio to avoid distortion - For tiled backgrounds, square images (1:1 ratio) work best and tile cleanly
Transparency in Source Images:
- PNG files can have their own transparency (alpha channel)
- This stacks with the
Transparencysetting in your code - If your PNG is already 50% transparent, and you set
Transparency = 0.5, you’ll get 75% total transparency (they multiply)
Conclusion
You’ve now got the complete toolkit for programmatically setting background images on Excel shapes using GroupDocs.Watermark .NET. Let’s recap the key points:
What you’ve learned:
- How to load Excel files and navigate to specific worksheets and shapes
- Setting background images with fine control over transparency and tiling
- Targeting specific shapes based on text, name, position, or other properties
- Optimizing performance for large files and batch operations
- Troubleshooting common issues before they become roadblocks
Next steps to level up your skills:
- Experiment with different targeting criteria—try matching shapes by position, size, or type instead of just text
- Build a batch processor—create a console app that watches a folder and processes new Excel files automatically
- Explore other GroupDocs features—the library can also handle text watermarks, image overlays, and much more for various document types
- Integrate into existing workflows—if you’re already generating Excel reports programmatically, adding background images is a natural extension
The bottom line: Manual shape formatting is a time sink. With just a few dozen lines of C#, you can automate what used to take hours, maintain consistency across thousands of files, and free up your time for work that actually matters.
FAQ Section
1. Can I apply a background image to all shapes in a worksheet at once?
Yes, absolutely. Just remove the conditional targeting inside your loop so every shape gets processed:
foreach (SpreadsheetShape shape in content.Worksheets[0].Shapes)
{
// No if statement—applies to all shapes
shape.ImageFillFormat.BackgroundImage = new SpreadsheetWatermarkableImage(imageBytes);
shape.ImageFillFormat.Transparency = 0.5;
shape.ImageFillFormat.TileAsTexture = true;
}
Be careful with this approach—make sure it’s actually what you want, as it’ll modify every single shape on that worksheet.
2. What image file formats are supported for background images?
GroupDocs.Watermark supports all common image formats including PNG, JPEG, BMP, GIF, and TIFF. PNG and JPEG are your best bets for most use cases—PNG for graphics with transparency, JPEG for photos where file size matters.
3. Is it possible to set different images for different shapes in the same file?
Definitely. Just use different conditional logic to match different shapes to different images:
foreach (var shape in worksheet.Shapes)
{
if (shape.Name.Contains("Header"))
{
shape.ImageFillFormat.BackgroundImage = new SpreadsheetWatermarkableImage(headerImage);
}
else if (shape.Name.Contains("Footer"))
{
shape.ImageFillFormat.BackgroundImage = new SpreadsheetWatermarkableImage(footerImage);
}
else if (shape.Text.StartsWith("©"))
{
shape.ImageFillFormat.BackgroundImage = new SpreadsheetWatermarkableImage(copyrightImage);
}
}
You can get as granular as you need—different images based on shape name, text content, position, size, whatever.
4. How do I troubleshoot if the background image isn’t appearing in the saved file?
Here’s a systematic troubleshooting checklist:
- Verify the image path is correct and the file actually exists—add a check:
if (!File.Exists(imagePath)) throw new FileNotFoundException(); - Check your targeting logic—make sure your if condition is actually matching the shapes you think it is (add debug output)
- Look at transparency settings—if
Transparency = 1.0, your image is completely transparent (invisible) - Ensure you’re saving the file—sounds obvious, but make sure
watermarker.Save()is called - Check the correct worksheet—you might be looking at a different worksheet than where you applied changes
- Verify shape type—not all “shapes” support background images (some special types don’t)
If you’re still stuck, try simplifying—remove all conditions, target just one shape by index, use a very visible image with no transparency. This helps isolate the problem.
5. Can I use this with Excel files stored in cloud storage (like Azure Blob Storage or AWS S3)?
Yes, but you need to download the file locally first, process it, then upload it back. GroupDocs.Watermark works with local file paths, not cloud storage APIs directly. Here’s the pattern:
// 1. Download from cloud storage to a temp location
var tempPath = Path.GetTempFileName();
await cloudClient.DownloadToFileAsync(cloudFilePath, tempPath);
// 2. Process with GroupDocs
using (var watermarker = new Watermarker(tempPath, loadOptions))
{
// Your shape processing code here
watermarker.Save(tempPath); // Save over the temp file
}
// 3. Upload the modified file back to cloud storage
await cloudClient.UploadFromFileAsync(tempPath, cloudFilePath);
// 4. Clean up temp file
File.Delete(tempPath);
This adds some overhead for the download/upload, but it’s the standard approach for cloud-based document processing.
6. Will this work with Excel files that have macros (.xlsm files)?
Yes, GroupDocs.Watermark supports .xlsm files. Your macros will be preserved—the library only modifies the shape properties you explicitly change. Just make sure to save with the same file extension (.xlsm) to keep the macros intact:
string outputFileName = "modified_file.xlsm"; // Keep the .xlsm extension
watermarker.Save(outputFileName);
7. Can I remove or clear existing background images from shapes?
Yes, set the BackgroundImage property to null:
foreach (var shape in worksheet.Shapes)
{
shape.ImageFillFormat.BackgroundImage = null; // Clears the background image
}
This is useful if you need to “reset” shapes or remove outdated backgrounds before applying new ones.
Resources
Documentation:
- GroupDocs.Watermark for .NET Documentation - Complete guides and tutorials
- API Reference - Detailed class and method documentation
Downloads and Licensing:
- Download GroupDocs.Watermark - Latest releases and version history
- Get a Temporary License - Extended trial access for evaluation
Community and Support:
- Free Support Forum - Ask questions, share solutions, get help from the community