PanoramicData.SheetMagic
3.0.124
dotnet add package PanoramicData.SheetMagic --version 3.0.124
NuGet\Install-Package PanoramicData.SheetMagic -Version 3.0.124
<PackageReference Include="PanoramicData.SheetMagic" Version="3.0.124" />
<PackageVersion Include="PanoramicData.SheetMagic" Version="3.0.124" />
<PackageReference Include="PanoramicData.SheetMagic" />
paket add PanoramicData.SheetMagic --version 3.0.124
#r "nuget: PanoramicData.SheetMagic, 3.0.124"
#:package PanoramicData.SheetMagic@3.0.124
#addin nuget:?package=PanoramicData.SheetMagic&version=3.0.124
#tool nuget:?package=PanoramicData.SheetMagic&version=3.0.124
PanoramicData.SheetMagic
Easily save/load data to/from Excel (XLSX) documents using strongly-typed C# classes.
Requirements
- .NET 9.0 - This library targets .NET 9.0 only
Installation
dotnet add package PanoramicData.SheetMagic
Features
- ? Strongly-typed - Work with your own C# classes
- ? Simple API - Easy to read and write XLSX files
- ? Multiple sheets - Add and read multiple worksheets
- ? Styling support - Apply table styles to your data
- ? Extended properties - Support for dynamic properties via
Extended<T> - ? Streams and files - Work with both
FileInfoandStreamobjects - ? Type safe - Full support for common .NET types including nullable types
Quick Start
Writing to a file
using PanoramicData.SheetMagic;
// Define your class
public class Thing
{
public string PropertyA { get; set; }
public int PropertyB { get; set; }
}
// Create some data
var things = new List<Thing>
{
new Thing { PropertyA = "Value 1", PropertyB = 1 },
new Thing { PropertyA = "Value 2", PropertyB = 2 },
};
// Write to Excel file
var fileInfo = new FileInfo($"Output {DateTime.UtcNow:yyyyMMddTHHmmss}Z.xlsx");
using var workbook = new MagicSpreadsheet(fileInfo);
workbook.AddSheet(things);
workbook.Save();
Reading from a file
using PanoramicData.SheetMagic;
// Read from Excel file
using var workbook = new MagicSpreadsheet(fileInfo);
workbook.Load();
// Read from default worksheet (first sheet)
var cars = workbook.GetList<Car>();
// Read from a specific worksheet by name
var animals = workbook.GetList<Animal>("Animals");
Advanced Features
Working with Streams
// Write to a stream
using var stream = new MemoryStream();
using (var workbook = new MagicSpreadsheet(stream))
{
workbook.AddSheet(data);
workbook.Save();
}
// Read from a stream
stream.Position = 0;
using var workbook = new MagicSpreadsheet(stream);
workbook.Load();
var items = workbook.GetList<MyClass>();
Multiple Sheets
using var workbook = new MagicSpreadsheet(fileInfo);
workbook.AddSheet(cars, "Cars");
workbook.AddSheet(animals, "Animals");
workbook.AddSheet(products, "Products");
workbook.Save();
Applying Table Styles
var options = new AddSheetOptions
{
TableOptions = new TableOptions
{
Name = "MyTable",
DisplayName = "MyTable1",
XlsxTableStyle = XlsxTableStyle.TableStyleMedium2,
ShowRowStripes = true,
ShowColumnStripes = false,
ShowFirstColumn = false,
ShowLastColumn = false
}
};
workbook.AddSheet(data, "StyledSheet", options);
Conditional Formatting
Conditional formatting is configured through AddSheetOptions.ConditionalFormats.
The object model is intentionally close to Excel's own configuration model:
ConditionalFormatselects one or more output columns, or all columns whenColumnNamesis omitted.ConditionalFormatRuledescribes one Excel rule such asCellIs,ContainsBlanks, orContainsErrors.ConditionalFormatStyledefines the differential format Excel applies when the rule matches.
ColumnNames must match the final header text written to Excel.
If PropertyHeaders is set, use those values.
Otherwise use the Description attribute value or the property name.
using System.Drawing;
using PanoramicData.SheetMagic;
var rows = new[]
{
new ReportRow { Name = null, Description = "Missing name", Score = null },
new ReportRow { Name = "Bravo", Description = "High score", Score = 9 },
new ReportRow { Name = "Charlie", Description = null, Score = 4 }
}.ToList();
var options = new AddSheetOptions
{
ConditionalFormats =
[
new ConditionalFormat
{
ColumnNames = ["Name", "Description"],
Rules =
[
new ConditionalFormatRule
{
RuleType = ConditionalFormatRuleType.ContainsBlanks,
Style = new ConditionalFormatStyle
{
BackgroundColor = Color.Red
}
}
]
},
new ConditionalFormat
{
ColumnNames = ["Score"],
Rules =
[
new ConditionalFormatRule
{
RuleType = ConditionalFormatRuleType.ContainsBlanks,
Style = new ConditionalFormatStyle
{
BackgroundColor = Color.Red
}
},
new ConditionalFormatRule
{
RuleType = ConditionalFormatRuleType.CellIs,
Operator = ConditionalFormatOperator.GreaterThan,
Formula = "5",
Style = new ConditionalFormatStyle
{
FontColor = Color.Green,
FontWeight = FontWeight.Bold
}
}
]
},
new ConditionalFormat
{
Rules =
[
new ConditionalFormatRule
{
RuleType = ConditionalFormatRuleType.ContainsErrors,
Style = new ConditionalFormatStyle
{
FontWeight = FontWeight.Bold
}
}
]
}
]
};
using var workbook = new MagicSpreadsheet(new FileInfo("ConditionalFormatting.xlsx"));
workbook.AddSheet(rows, "Report", options);
workbook.Save();
public sealed class ReportRow
{
public string? Name { get; set; }
public string? Description { get; set; }
public int? Score { get; set; }
}
Supported rule types currently include:
CellIsExpressionContainsBlanksNotContainsBlanksContainsErrorsNotContainsErrorsContainsTextNotContainsTextBeginsWithEndsWithDuplicateValuesUniqueValuesTop10AboveAverage
Custom Property Headers
Use the Description attribute to customize column headers:
using System.ComponentModel;
public class Employee
{
public int Id { get; set; }
[Description("Full Name")]
public string Name { get; set; }
[Description("Hire Date")]
public DateTime HireDate { get; set; }
}
Property Filtering
// Include only specific properties
var options = new AddSheetOptions
{
IncludeProperties = new[] { "Name", "Age", "City" }
};
workbook.AddSheet(people, "Filtered", options);
// Exclude specific properties
var options = new AddSheetOptions
{
ExcludeProperties = new[] { "InternalId", "Password" }
};
workbook.AddSheet(users, "Public", options);
Extended Properties (Dynamic Properties)
Work with objects that have both strongly-typed and dynamic properties:
var extendedData = new List<Extended<MyClass>>
{
new Extended<MyClass>(
new MyClass { Id = 1, Name = "Item 1" },
new Dictionary<string, object?>
{
{ "DynamicProp1", "Value1" },
{ "DynamicProp2", 42 }
}
)
};
workbook.AddSheet(extendedData);
workbook.Save();
// Reading extended properties
var loadedData = workbook.GetExtendedList<MyClass>();
foreach (var item in loadedData)
{
Console.WriteLine($"{item.Item.Name}");
foreach (var prop in item.Properties)
{
Console.WriteLine($" {prop.Key}: {prop.Value}");
}
}
Supported Types
- Primitives:
int,long,short,uint,ulong,ushort - Floating point:
float,double,decimal - Boolean:
bool - Dates:
DateTime,DateTimeOffset - Strings:
string - Enums (stored as text)
- Lists:
List<string>(with configurable delimiter) - All nullable versions of the above
Options
Configure behavior with the Options class:
var options = new Options
{
StopProcessingOnFirstEmptyRow = true,
IgnoreUnmappedProperties = true,
EmptyRowInterpretedAsNull = false,
LoadNullExtendedProperties = true,
ListSeparator = ";"
};
using var workbook = new MagicSpreadsheet(fileInfo, options);
Known Limitations
- JObject Support: Direct
JObjectserialization is not yet supported. UseExtended<object>instead. - Nested Complex Objects: Properties of type
List<ComplexType>cannot be loaded from Excel (though they can be saved as delimited strings). - Large Integer Precision: Excel stores all numbers as doubles, so very large
Int64/UInt64values (nearMaxValue) may lose precision. - Special Values:
double.NaNandnullnullable types are stored as empty strings in Excel.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
See the LICENSE file for details.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | 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. |
-
net10.0
- DocumentFormat.OpenXml (>= 2.20.0 && < 3.0.0)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on PanoramicData.SheetMagic:
| Package | Downloads |
|---|---|
|
PanoramicData.SheetMagic.Benchmarks
Package Description |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 3.0.124 | 97 | 4/13/2026 |
| 3.0.122 | 139 | 4/5/2026 |
| 3.0.118 | 470 | 12/21/2025 |
| 3.0.117 | 207 | 12/21/2025 |
| 3.0.114 | 372 | 11/23/2025 |
| 3.0.109 | 370 | 10/27/2025 |
| 3.0.106 | 492 | 9/2/2025 |
| 3.0.105 | 629 | 5/21/2025 |
| 3.0.104 | 264 | 5/8/2025 |
| 3.0.101 | 2,816 | 10/16/2023 |
| 3.0.98 | 266 | 10/9/2023 |
| 3.0.96 | 906 | 7/13/2023 |
| 3.0.94 | 276 | 7/12/2023 |
| 3.0.93 | 278 | 7/12/2023 |
| 3.0.91 | 322 | 7/11/2023 |
| 3.0.85 | 1,161 | 1/26/2023 |
| 3.0.81 | 472 | 1/17/2023 |
| 3.0.79 | 696 | 11/8/2022 |
| 3.0.65 | 506 | 11/5/2022 |
| 3.0.62 | 576 | 10/14/2022 |
Enhanced logic to handle missing text cells (this can happen with empty strings, if they have no formatting, and is a normal Excel optimization) in the Excel file's XML. These cell values are now returned as empty strings for consistency.