Exceleration 2.0.1
dotnet add package Exceleration --version 2.0.1
NuGet\Install-Package Exceleration -Version 2.0.1
<PackageReference Include="Exceleration" Version="2.0.1" />
<PackageVersion Include="Exceleration" Version="2.0.1" />
<PackageReference Include="Exceleration" />
paket add Exceleration --version 2.0.1
#r "nuget: Exceleration, 2.0.1"
#:package Exceleration@2.0.1
#addin nuget:?package=Exceleration&version=2.0.1
#tool nuget:?package=Exceleration&version=2.0.1
Exceleration
Exceleration reads Excel workbooks into memory through ExcelDataReader and lets you address the cells the way Excel does: by sheet name, by A1 reference, or by row and column number counted from 1. It reads; it does not write workbooks.
dotnet add package Exceleration
Everything is in the Exceleration namespace. The package targets net8.0, net9.0 and net10.0 and depends on ExcelDataReader and ExcelDataReader.DataSet 3.9.0.
Read cells
The samples below read prices.xlsx, whose first sheet, Sheet1, holds:
| A | B | C | |
|---|---|---|---|
| 1 | Name | Qty | Price |
| 2 | Apple | 3 | 1.5 |
| 3 | Pear | 7 | 2.25 |
using Exceleration;
var wb = new Workbook("prices.xlsx");
var ws = wb["Sheet1"];
Console.WriteLine(ws["A2"].Value); // Apple
Console.WriteLine(ws.GetCell(3, 2).Address); // B3
Console.WriteLine(ws.GetCellValue("C3")); // 2.25
Console.WriteLine(ws.GetCellValue(1, 2)); // Qty
Console.WriteLine(ws["b2"].Offset(1, 1).Value); // 2.25
Console.WriteLine(ws.Cells.Count); // 9
Convert values
using Exceleration;
var ws = new Workbook("prices.xlsx")["Sheet1"];
int qty = ws["B2"].To<int>(); // 3
decimal price = ws["C2"].To<decimal>(); // 1.5
int bad = ws["A2"].To<int>(); // 0: "Apple" is not a number
int? none = ws["A2"].ToNullable<int>(); // null
bool ok = ws["B3"].IsParseable<int>(); // True
Console.WriteLine($"{qty} {price} {bad} {none is null} {ok}");
Rows and columns
using Exceleration;
var ws = new Workbook("prices.xlsx")["Sheet1"];
foreach (var row in ws.Rows)
{
Console.WriteLine(string.Join(", ", row.Select(c => c.Value)));
}
// Name, Qty, Price
// Apple, 3, 1.5
// Pear, 7, 2.25
var names = ws.GetColumn("A").Skip(1).Select(c => c.Value);
Console.WriteLine(string.Join(", ", names)); // Apple, Pear
var header = ws.GetRow(1);
Console.WriteLine(header.GetFirstCellByColumnLetter("C").Value); // Price
var expensive = ws.Rows
.Skip(1)
.Where(r => r.GetFirstCellByColumnLetter("C").To<double>() > 2)
.Select(r => r.GetFirstCellByColumnNumber(1).Value);
Console.WriteLine(string.Join(", ", expensive)); // Pear
ws.Rows and ws.Columns are properties that return a list of lists. GetRow, GetColumn and the CellListExtensions methods (GetFirstCellByRowNumber, GetFirstCellByColumnLetter, GetFirstCellByColumnNumber, and GetRow and GetColumn on a List<Cell>) pick cells out of them.
DataTable and added sheets
using System.Data;
using Exceleration;
var wb = new Workbook("prices.xlsx");
DataTable table = wb["Sheet1"].ToDataTable();
Console.WriteLine(table.Columns[0].ColumnName); // Column0
Console.WriteLine(table.Rows[1][0]); // Apple
wb.AddSheet(table, "Copy");
Console.WriteLine(wb["Copy"]["A3"].Value); // Pear
ToDataTable returns a copy of the sheet's data. Its columns are named Column0, Column1 and so on, and row 1 of the sheet is the table's first row.
How a workbook is read
new Workbook(filePath)reads every sheet of the file into memory and closes it before returning. Later changes to the file are not seen; construct a newWorkbookto read them.- It reads the formats ExcelDataReader's
ExcelReaderFactory.CreateReaderdetects from the file's content: .xlsx and .xlsm, .xlsb, and .xls. It does not read CSV. - A file it cannot read, a CSV file, any other file that is not a workbook, or a damaged workbook, throws
System.IO.InvalidDataExceptionnaming the file, with the exception ExcelDataReader or .NET raised as itsInnerException. A missing file throwsFileNotFoundException, and a file that cannot be openedIOException. - The file is opened for reading and shared with other readers and writers, so a workbook that Excel, another process or another thread has open can be read. It throws
IOExceptiononly when another process holds the file without sharing it. new Workbook(filePath, true)copies the file first, into the folderExceleration.dllwas loaded from, under the same file name, and reads the copy. It replaces a file of that name in that folder, leaves the copy there afterwards, andFilePaththen names the copy. A file that is already in that folder is read where it is.- Each constructor registers
CodePagesEncodingProvider.InstancewithEncoding.RegisterProvider, which ExcelDataReader needs for the code pages of older .xls files. The registration applies to the whole process. Nameis the file name of the path you passed, andSheetslists the sheets in workbook order.
Sheets, cells and values
wb["Sheet1"]finds a sheet by name, ignoring case. A name that is not there throwsArgumentException.- Row 1 of a sheet is row 1: no row is taken as a header. Empty rows and columns before the first value are kept, so a sheet whose only value is in B3 still has B3 at row 3, column 2.
- An A1 reference is column letters, in either case, then the row number, and nothing else: "B12" and "b12" are the same cell. Anything else, such as "$B$12", "B12:C13" or " B12", throws
ArgumentException, and a null reference throwsArgumentNullException. - Rows and columns are numbered from 1.
GetCell,GetCellValue,GetRow,GetColumnandOffsetthrowArgumentOutOfRangeExceptionfor a row or column outside the sheet's used range; itsParamNameisrowNumberorcolNumber, and its message gives the sheet's size. Offset(rows, columns)returns the cell that many rows down and columns to the right; negative numbers go up and left.Cellslists every cell of the used range, row by row.Valueis what ExcelDataReader read: astring, adoublefor every number, abool, aDateTimefor a cell with a date format, orDBNull.Valuefor an empty cell. A formula cell holds the value Excel last calculated and saved.DataTypeis the type ofValue,typeof(DBNull)for an empty cell.To<T>()converts withConvert.ChangeType, which uses the current culture and rounds a fractional number to the nearest even integer (1.5 and 2.5 both give 2). It returnsdefault(T)when the conversion fails, or throwsInvalidCastExceptionwithTo<T>(false).ToNullable<T>()returnsnullfor an empty cell, a cell that holds only spaces, or a value that does not convert.ToNullable<T>(false)returnsdefault(T), such as 0, for a value that does not convert, and stillnullfor an empty or blank cell.IsParseable<T>()returnsfalsefor an empty or blank cell and for a value that does not convert.ToString()returnsValue.ToString(), an empty string for an empty cell.wb.AddSheet(table, name)adds a sheet made from a copy of aDataTable, so the table you pass keeps its name and later changes to it do not reach the sheet.wb.AddSheet(sheet)adds a copy of aWorksheetfrom this or another workbook; the copy'sParentis this workbook, and the sheet you pass is not changed. Both throwArgumentExceptionwhen a sheet with the same name, ignoring case, is already there. Nothing is written back to the file. Adding toSheetsdirectly skips the name check.
Reading files you did not create
The whole workbook is held in memory, and a sheet takes room for every cell from A1 to its last used cell, empty or not. A 1.6 KB .xlsx whose only values are in A1 and CV100000 becomes a 100,000 by 100 table and took about 0.9 GB to read.
new Workbook(filePath)sets no limit. For a workbook from somewhere you do not control, pass one:var wb = new Workbook(path, false, maxCellsPerSheet: 1_000_000);A sheet whose used range, rows times columns, is larger than the limit throws
InvalidDataExceptionbefore any sheet is read, naming the sheet and its size.A file that is not a workbook, or is damaged, throws
InvalidDataException; theInnerExceptionsays what the parse hit, for exampleExcelDataReader.Exceptions.HeaderExceptionfor a file of another kind orSystem.Xml.XmlExceptionfor broken XML. An .xlsx part with a DTD is refused the same way, with anXmlExceptioninside, so external entities are not resolved.Pass
truefor the copy only when you control the file name, because the copy replaces any file of that name in the application's folder.
Attributions
Icon "Exceleration.png" designed by Stockes Design on Freepik.com.
License
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. 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
- ExcelDataReader (>= 3.9.0)
- ExcelDataReader.DataSet (>= 3.9.0)
-
net8.0
- ExcelDataReader (>= 3.9.0)
- ExcelDataReader.DataSet (>= 3.9.0)
-
net9.0
- ExcelDataReader (>= 3.9.0)
- ExcelDataReader.DataSet (>= 3.9.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.