Class WorkbookEditor
- Namespace
- DocToolkit
- Assembly
- DocToolkit.Xlsx.dll
Creates, reads and edits Excel (.xlsx) workbooks. Legacy .xls is not supported.
public static class WorkbookEditor
- Inheritance
-
WorkbookEditor
- Inherited Members
Methods
AddChart(byte[], string, string, ChartType, ChartData, string, int, int)
Adds a chart to sheetName, anchored at cellRef, and
returns the updated workbook.
public static byte[] AddChart(byte[] xlsx, string sheetName, string cellRef, ChartType type, ChartData data, string title = "", int widthPixels = 640, int heightPixels = 360)
Parameters
xlsxbyte[]The workbook to add the chart to. It is not modified.
sheetNamestringThe sheet to add the chart to.
cellRefstringAn A1-style cell reference for the chart's top-left corner, e.g.
"B2".typeChartTypeThe chart's shape.
dataChartDataThe chart's categories and value series.
titlestringThe chart's title. Empty for no title.
widthPixelsintThe chart's width, in pixels.
heightPixelsintThe chart's height, in pixels.
Returns
- byte[]
Exceptions
- ArgumentNullException
xlsx,dataor another required argument is null.- ArgumentException
xlsxis empty, orsheetName/cellRefis blank.- DocumentConversionException
The workbook could not be opened, the sheet does not exist, or the reference is not valid.
AddChartAsync(Stream, string, string, ChartType, ChartData, Stream, string, int, int, CancellationToken)
Reads a workbook from source, adds a chart, and writes the result to
destination — see AddChart(byte[], string, string, ChartType, ChartData, string, int, int) for the parameters.
source is read to its end and destination is
written; neither is disposed, closed or sought, and neither has to be seekable.
public static Task AddChartAsync(Stream source, string sheetName, string cellRef, ChartType type, ChartData data, Stream destination, string title = "", int widthPixels = 640, int heightPixels = 360, CancellationToken ct = default)
Parameters
sourceStreamThe stream the workbook is read from.
sheetNamestringThe sheet to add the chart to.
cellRefstringAn A1-style cell reference for the chart's top-left corner, e.g.
"B2".typeChartTypeThe chart's shape.
dataChartDataThe chart's categories and value series.
destinationStreamThe stream the updated workbook is written to.
titlestringThe chart's title. Empty for no title.
widthPixelsintThe chart's width, in pixels.
heightPixelsintThe chart's height, in pixels.
ctCancellationTokenCancels the read, the edit and the write.
Returns
Exceptions
- ArgumentNullException
source,destinationordatais null.- ArgumentException
sourceis not readable or held no bytes, a name is blank, ordestinationis not writable.- OperationCanceledException
ctwas cancelled.- DocumentConversionException
The workbook could not be opened, the sheet does not exist, or the reference is not valid.
AddChartAsync(string, string, string, string, ChartType, ChartData, string, int, int, CancellationToken)
Reads a workbook from inputPath, adds a chart, and writes the result to
outputPath — see AddChart(byte[], string, string, ChartType, ChartData, string, int, int) for the parameters. The two
paths may be the same file: the updated bytes are computed in full before
outputPath is opened.
public static Task AddChartAsync(string inputPath, string outputPath, string sheetName, string cellRef, ChartType type, ChartData data, string title = "", int widthPixels = 640, int heightPixels = 360, CancellationToken ct = default)
Parameters
inputPathstringThe workbook to read.
outputPathstringWhere to write the result. Overwritten if it exists.
sheetNamestringThe sheet to add the chart to.
cellRefstringAn A1-style cell reference for the chart's top-left corner, e.g.
"B2".typeChartTypeThe chart's shape.
dataChartDataThe chart's categories and value series.
titlestringThe chart's title. Empty for no title.
widthPixelsintThe chart's width, in pixels.
heightPixelsintThe chart's height, in pixels.
ctCancellationTokenCancels the read and the write.
Returns
Exceptions
- ArgumentNullException
A path, a name or
datais null.- ArgumentException
A path or a name is blank, or the file at
inputPathis empty.- FileNotFoundException
inputPathdoes not exist.- DirectoryNotFoundException
inputPath's oroutputPath's directory does not exist.- OperationCanceledException
ctwas cancelled.- DocumentConversionException
The workbook could not be opened, the sheet does not exist, or the reference is not valid.
AddDefinedName(byte[], string, string, string)
Adds a workbook-scoped defined name pointing at range on
sheetName, and returns the updated workbook.
public static byte[] AddDefinedName(byte[] xlsx, string name, string sheetName, string range)
Parameters
xlsxbyte[]The workbook to add the defined name to. It is not modified.
namestringThe defined name.
sheetNamestringThe sheet
rangeis on.rangestringThe cells the name refers to, such as
A1:B2.
Returns
- byte[]
Remarks
sheetName is always single-quoted in the reference this writes (e.g.
'Sales'!A1:B2), whether or not it needs to be. Measured directly: a sheet name
containing a space and left unquoted does not raise an error at write time — the defined
name simply is not present when the file is reopened, with nothing telling the caller why.
Quoting a name with no space is harmless, so this is not a conditional worth the risk of
getting the "needs quoting" rule wrong.
Exceptions
- ArgumentNullException
Any argument is null.
- ArgumentException
xlsxis empty, a name argument is blank, orrangenames a sheet.- DocumentConversionException
The workbook could not be opened, the sheet does not exist, or
nameis already in use.
AddDefinedNameAsync(Stream, string, string, string, Stream, CancellationToken)
Reads a workbook from source, adds a defined name, and writes the result
to destination — see AddDefinedName(byte[], string, string, string) for the parameters.
source is read to its end and destination is
written; neither is disposed, closed or sought, and neither has to be seekable.
public static Task AddDefinedNameAsync(Stream source, string name, string sheetName, string range, Stream destination, CancellationToken ct = default)
Parameters
sourceStreamThe stream the workbook is read from.
namestringThe defined name.
sheetNamestringThe sheet
rangeis on.rangestringThe cells the name refers to, such as
A1:B2.destinationStreamThe stream the updated workbook is written to.
ctCancellationTokenCancels the read, the edit and the write.
Returns
Exceptions
- ArgumentNullException
Any argument is null.
- ArgumentException
sourceis not readable or held no bytes, a name argument is blank,rangenames a sheet, ordestinationis not writable.- OperationCanceledException
ctwas cancelled.- DocumentConversionException
The workbook could not be opened, the sheet does not exist, or
nameis already in use.
AddDefinedNameAsync(string, string, string, string, string, CancellationToken)
Reads a workbook from inputPath, adds a defined name, and writes the
result to outputPath — see AddDefinedName(byte[], string, string, string) for the
parameters. The two paths may be the same file: the updated bytes are computed in full
before outputPath is opened.
public static Task AddDefinedNameAsync(string inputPath, string outputPath, string name, string sheetName, string range, CancellationToken ct = default)
Parameters
inputPathstringThe workbook to read.
outputPathstringWhere to write the result. Overwritten if it exists.
namestringThe defined name.
sheetNamestringThe sheet
rangeis on.rangestringThe cells the name refers to, such as
A1:B2.ctCancellationTokenCancels the read and the write.
Returns
Exceptions
- ArgumentNullException
A path or a name argument is null.
- ArgumentException
A path or a name argument is blank,
rangenames a sheet, or the file atinputPathis empty.- FileNotFoundException
inputPathdoes not exist.- DirectoryNotFoundException
inputPath's oroutputPath's directory does not exist.- OperationCanceledException
ctwas cancelled.- DocumentConversionException
The workbook could not be opened, the sheet does not exist, or
nameis already in use.
AddImage(byte[], string, string, byte[], int?, int?)
Inserts image into sheetName, anchored at
cellRef, and returns the updated workbook.
public static byte[] AddImage(byte[] xlsx, string sheetName, string cellRef, byte[] image, int? widthPixels = null, int? heightPixels = null)
Parameters
xlsxbyte[]The workbook to add the image to. It is not modified.
sheetNamestringThe sheet to add the image to.
cellRefstringAn A1-style cell reference for the image's top-left corner, e.g.
"B2".imagebyte[]The image bytes. PNG and JPEG only, decided by magic bytes.
widthPixelsint?The image's width, in pixels. null uses the image's own intrinsic width, scaled to match
heightPixelsif that is given.heightPixelsint?The image's height, in pixels. null uses the image's own intrinsic height, scaled to match
widthPixelsif that is given.
Returns
- byte[]
Exceptions
- ArgumentNullException
xlsx,imageor another required argument is null.- ArgumentException
xlsxorimageis empty, orsheetName/cellRefis blank.- ArgumentOutOfRangeException
A supplied size is zero or negative.
- DocumentConversionException
The workbook could not be opened, the sheet does not exist, the reference is not valid, or the image is neither PNG nor JPEG.
AddImageAsync(Stream, string, string, byte[], Stream, int?, int?, CancellationToken)
Reads a workbook from source, adds an image, and writes the result to
destination — see AddImage(byte[], string, string, byte[], int?, int?) for the parameters.
source is read to its end and destination is
written; neither is disposed, closed or sought, and neither has to be seekable.
public static Task AddImageAsync(Stream source, string sheetName, string cellRef, byte[] image, Stream destination, int? widthPixels = null, int? heightPixels = null, CancellationToken ct = default)
Parameters
sourceStreamThe stream the workbook is read from.
sheetNamestringThe sheet to add the image to.
cellRefstringAn A1-style cell reference for the image's top-left corner, e.g.
"B2".imagebyte[]The image bytes. PNG and JPEG only, decided by magic bytes.
destinationStreamThe stream the updated workbook is written to.
widthPixelsint?The image's width, in pixels. See AddImage(byte[], string, string, byte[], int?, int?).
heightPixelsint?The image's height, in pixels. See AddImage(byte[], string, string, byte[], int?, int?).
ctCancellationTokenCancels the read, the edit and the write.
Returns
Exceptions
- ArgumentNullException
source,destinationorimageis null.- ArgumentException
sourceis not readable or held no bytes,imageis empty, a name is blank, ordestinationis not writable.- ArgumentOutOfRangeException
A supplied size is zero or negative.
- OperationCanceledException
ctwas cancelled.- DocumentConversionException
The workbook could not be opened, the sheet does not exist, the reference is not valid, or the image is neither PNG nor JPEG.
AddImageAsync(string, string, string, string, byte[], int?, int?, CancellationToken)
Reads a workbook from inputPath, adds an image, and writes the result to
outputPath — see AddImage(byte[], string, string, byte[], int?, int?) for the parameters. The two paths
may be the same file: the updated bytes are computed in full before
outputPath is opened.
public static Task AddImageAsync(string inputPath, string outputPath, string sheetName, string cellRef, byte[] image, int? widthPixels = null, int? heightPixels = null, CancellationToken ct = default)
Parameters
inputPathstringThe workbook to read.
outputPathstringWhere to write the result. Overwritten if it exists.
sheetNamestringThe sheet to add the image to.
cellRefstringAn A1-style cell reference for the image's top-left corner, e.g.
"B2".imagebyte[]The image bytes. PNG and JPEG only, decided by magic bytes.
widthPixelsint?The image's width, in pixels. See AddImage(byte[], string, string, byte[], int?, int?).
heightPixelsint?The image's height, in pixels. See AddImage(byte[], string, string, byte[], int?, int?).
ctCancellationTokenCancels the read and the write.
Returns
Exceptions
- ArgumentNullException
A path, a name or
imageis null.- ArgumentException
A path or a name is blank,
imageis empty, or the file atinputPathis empty.- ArgumentOutOfRangeException
A supplied size is zero or negative.
- FileNotFoundException
inputPathdoes not exist.- DirectoryNotFoundException
inputPath's oroutputPath's directory does not exist.- OperationCanceledException
ctwas cancelled.- DocumentConversionException
The workbook could not be opened, the sheet does not exist, the reference is not valid, or the image is neither PNG nor JPEG.
AddPivotTable(byte[], string, string, string, string, IEnumerable<string>, IEnumerable<PivotDataField>, IEnumerable<string>?, IEnumerable<string>?, bool, bool)
Adds a pivot table to sheetName and returns the updated workbook.
public static byte[] AddPivotTable(byte[] xlsx, string sheetName, string sourceRange, string destinationCell, string name, IEnumerable<string> rowFields, IEnumerable<PivotDataField> dataFields, IEnumerable<string>? columnFields = null, IEnumerable<string>? pageFields = null, bool showRowGrandTotals = true, bool showColumnGrandTotals = true)
Parameters
xlsxbyte[]The workbook to add the pivot table to. It is not modified.
sheetNamestringThe sheet to add the pivot table to.
sourceRangestringAn A1-style range naming the source data, e.g.
"A1:C10".destinationCellstringAn A1-style cell reference for the pivot table's top-left corner, e.g.
"E1".namestringThe pivot table's name.
rowFieldsIEnumerable<string>Source column headers to group by, down the rows. At least one.
dataFieldsIEnumerable<PivotDataField>The aggregated value columns. At least one.
columnFieldsIEnumerable<string>Source column headers to group by, across the columns. Optional.
pageFieldsIEnumerable<string>Source column headers used as report filters. Optional.
showRowGrandTotalsboolWhether to show a grand total row.
showColumnGrandTotalsboolWhether to show a grand total column.
Returns
- byte[]
Remarks
The result grid is empty until Excel opens and recalculates it. A pivot
table's aggregated values are computed by whichever application opens the file — nothing
that WRITES it (this method included) populates the grid. This is a HARDER version of the
limitation this package already documents for XlsxFormula: a formula's value
is computed by ReadCell(byte[], string, string)/ReadSheet(byte[], string) on read, and, since
XlsxToPdfConverter started calling Calculate() before rendering, is now
computed there too — but there is no equivalent pivot-evaluation engine here, so reading
the pivot's own cells back with ReadCell(byte[], string, string) immediately after calling this
method returns empty strings, and XlsxToPdfConverter renders nothing where the
pivot's results would be. Open the result in Excel (or an equivalent) to see it populated.
Further edits to the workbook through this class's other methods (all ClosedXML-based) re-serialize the pivot table's XML — measured directly — but its field structure and aggregation choices survive that re-serialization correctly.
Exceptions
- ArgumentNullException
xlsx,rowFields,dataFieldsor another required argument is null.- ArgumentException
xlsxis empty, a name argument is blank, orrowFields/dataFieldsis empty.- DocumentConversionException
The workbook could not be opened, the sheet does not exist, or
destinationCellis not a valid cell reference.
AddPivotTableAsync(Stream, string, string, string, string, IEnumerable<string>, IEnumerable<PivotDataField>, Stream, IEnumerable<string>?, IEnumerable<string>?, bool, bool, CancellationToken)
Reads a workbook from source, adds a pivot table, and writes the
result to destination — see AddPivotTable(byte[], string, string, string, string, IEnumerable<string>, IEnumerable<PivotDataField>, IEnumerable<string>?, IEnumerable<string>?, bool, bool) for the
parameters.
source is read to its end and destination is
written; neither is disposed, closed or sought, and neither has to be seekable.
public static Task AddPivotTableAsync(Stream source, string sheetName, string sourceRange, string destinationCell, string name, IEnumerable<string> rowFields, IEnumerable<PivotDataField> dataFields, Stream destination, IEnumerable<string>? columnFields = null, IEnumerable<string>? pageFields = null, bool showRowGrandTotals = true, bool showColumnGrandTotals = true, CancellationToken ct = default)
Parameters
sourceStreamThe stream the workbook is read from.
sheetNamestringThe sheet to add the pivot table to.
sourceRangestringAn A1-style range naming the source data, e.g.
"A1:C10".destinationCellstringAn A1-style cell reference for the pivot table's top-left corner, e.g.
"E1".namestringThe pivot table's name.
rowFieldsIEnumerable<string>Source column headers to group by, down the rows. At least one.
dataFieldsIEnumerable<PivotDataField>The aggregated value columns. At least one.
destinationStreamThe stream the updated workbook is written to.
columnFieldsIEnumerable<string>Source column headers to group by, across the columns. Optional.
pageFieldsIEnumerable<string>Source column headers used as report filters. Optional.
showRowGrandTotalsboolWhether to show a grand total row.
showColumnGrandTotalsboolWhether to show a grand total column.
ctCancellationTokenCancels the read, the edit and the write.
Returns
Exceptions
- ArgumentNullException
source,destination,rowFieldsordataFieldsis null.- ArgumentException
sourceis not readable or held no bytes, a name is blank, orrowFields/dataFieldsis empty.- OperationCanceledException
ctwas cancelled.- DocumentConversionException
The workbook could not be opened, the sheet does not exist, or
destinationCellis not a valid cell reference.
AddPivotTableAsync(string, string, string, string, string, string, IEnumerable<string>, IEnumerable<PivotDataField>, IEnumerable<string>?, IEnumerable<string>?, bool, bool, CancellationToken)
Reads a workbook from inputPath, adds a pivot table, and writes the
result to outputPath — see AddPivotTable(byte[], string, string, string, string, IEnumerable<string>, IEnumerable<PivotDataField>, IEnumerable<string>?, IEnumerable<string>?, bool, bool) for the
parameters. The two paths may be the same file: the updated bytes are computed in full
before outputPath is opened.
public static Task AddPivotTableAsync(string inputPath, string outputPath, string sheetName, string sourceRange, string destinationCell, string name, IEnumerable<string> rowFields, IEnumerable<PivotDataField> dataFields, IEnumerable<string>? columnFields = null, IEnumerable<string>? pageFields = null, bool showRowGrandTotals = true, bool showColumnGrandTotals = true, CancellationToken ct = default)
Parameters
inputPathstringThe workbook to read.
outputPathstringWhere to write the result. Overwritten if it exists.
sheetNamestringThe sheet to add the pivot table to.
sourceRangestringAn A1-style range naming the source data, e.g.
"A1:C10".destinationCellstringAn A1-style cell reference for the pivot table's top-left corner, e.g.
"E1".namestringThe pivot table's name.
rowFieldsIEnumerable<string>Source column headers to group by, down the rows. At least one.
dataFieldsIEnumerable<PivotDataField>The aggregated value columns. At least one.
columnFieldsIEnumerable<string>Source column headers to group by, across the columns. Optional.
pageFieldsIEnumerable<string>Source column headers used as report filters. Optional.
showRowGrandTotalsboolWhether to show a grand total row.
showColumnGrandTotalsboolWhether to show a grand total column.
ctCancellationTokenCancels the read and the write.
Returns
Exceptions
- ArgumentNullException
A path, a name,
rowFieldsordataFieldsis null.- ArgumentException
A path or a name is blank, the file at
inputPathis empty, orrowFields/dataFieldsis empty.- FileNotFoundException
inputPathdoes not exist.- DirectoryNotFoundException
inputPath's oroutputPath's directory does not exist.- OperationCanceledException
ctwas cancelled.- DocumentConversionException
The workbook could not be opened, the sheet does not exist, or
destinationCellis not a valid cell reference.
AppendRows(byte[], string, IEnumerable<IEnumerable<object?>>)
Appends rows to sheetName, starting immediately after
its last used row, and returns the updated workbook. Every other sheet, and all existing
formatting, is left as it was.
"Last used row" comes from ClosedXML's LastRowUsed(), which — like
LastCellUsed() in ReadSheet(byte[], string) — ignores formatting but counts a cell
comment as used even with no value. A comment on an otherwise-blank row far below the real
data therefore pushes the append down to start after that row, leaving a gap rather than
continuing immediately after the last row a caller would see as holding data.
Cell typing and culture rules are identical to
Create(string, IEnumerable<IEnumerable<object?>>). A cell holding an
XlsxFormula is written as a formula. An empty rows is a
no-op that still returns a valid workbook.
public static byte[] AppendRows(byte[] xlsx, string sheetName, IEnumerable<IEnumerable<object?>> rows)
Parameters
xlsxbyte[]sheetNamestringrowsIEnumerable<IEnumerable<object>>
Returns
- byte[]
Exceptions
- ArgumentNullException
xlsxorrowsis null.- ArgumentException
xlsxis empty;sheetNameis blank, is longer than 31 characters, or contains one of: \ / ? * [ ]; or an element ofrowsis null.- DocumentConversionException
The sheet was not found, or the package could not be opened or edited.
AppendRowsAsync(Stream, string, IEnumerable<IEnumerable<object?>>, Stream, CancellationToken)
Reads a workbook from source, appends rows to
sheetName, and writes the result to destination. See
AppendRows(byte[], string, IEnumerable<IEnumerable<object?>>) for the
semantics, including exactly what "last used row" means.
source is read to its end and destination
is written; neither is disposed, closed or sought.
public static Task AppendRowsAsync(Stream source, string sheetName, IEnumerable<IEnumerable<object?>> rows, Stream destination, CancellationToken ct = default)
Parameters
sourceStreamThe stream the workbook is read from.
sheetNamestringThe sheet to append to.
rowsIEnumerable<IEnumerable<object>>The rows to append.
destinationStreamThe stream the updated workbook is written to.
ctCancellationTokenCancels the read, the edit and the write.
Returns
Exceptions
- ArgumentNullException
rowsis null.- ArgumentException
sourceis not readable or held no bytes;destinationis not writable;sheetNameis blank, is longer than 31 characters, or contains one of: \ / ? * [ ]; or an element ofrowsis null.- OperationCanceledException
ctwas cancelled.- DocumentConversionException
The sheet was not found, or the package could not be opened or edited.
AppendRowsAsync(string, string, string, IEnumerable<IEnumerable<object?>>, CancellationToken)
Reads a workbook from inputPath, appends rows to
sheetName, and writes the result to outputPath,
overwriting any existing file. See
AppendRows(byte[], string, IEnumerable<IEnumerable<object?>>) for the
semantics, including exactly what "last used row" means.
public static Task AppendRowsAsync(string inputPath, string outputPath, string sheetName, IEnumerable<IEnumerable<object?>> rows, CancellationToken ct = default)
Parameters
inputPathstringThe workbook to read.
outputPathstringWhere to write the result. Overwritten if it exists.
sheetNamestringThe sheet to append to.
rowsIEnumerable<IEnumerable<object>>The rows to append.
ctCancellationTokenCancels the read and the write.
Returns
Exceptions
- ArgumentNullException
rowsis null.- ArgumentException
inputPathoroutputPathis blank;sheetNameis blank, is longer than 31 characters, or contains one of: \ / ? * [ ]; or an element ofrowsis null.- FileNotFoundException
inputPathdoes not exist.- DirectoryNotFoundException
inputPath's oroutputPath's directory does not exist.- OperationCanceledException
ctwas cancelled.- DocumentConversionException
The sheet was not found, or the package could not be opened or edited.
Create(IEnumerable<XlsxSheet>)
Builds a workbook from sheets, one worksheet each, in sequence order.
Content comes from data rather than a template, so there is no source file to edit.
Cell typing and culture rules are identical to Create(string, IEnumerable<IEnumerable<object?>>). A cell holding an XlsxFormula is written as a formula — see that type for the one limit worth knowing about cached values.
public static byte[] Create(IEnumerable<XlsxSheet> sheets)
Parameters
sheetsIEnumerable<XlsxSheet>
Returns
- byte[]
Examples
byte[] xlsx = WorkbookEditor.Create(new[]
{
XlsxSheet.Named("Sales", new[]
{
new object?[] { "Region", "Q1" },
new object?[] { "North", 1200 },
new object?[] { "Total", XlsxFormula.From("=SUM(B2:B2)") },
}),
});
Exceptions
- ArgumentNullException
sheetsis null.- ArgumentException
sheetsis empty, contains a null element, or names the same sheet twice.- DocumentConversionException
The workbook could not be built.
Create(string, IEnumerable<IEnumerable<object?>>)
Creates a workbook with one sheet populated from rows.
Every built-in numeric type is written as a number so formulas such as SUM() pick it up; DateTime and DateOnly become dates, TimeOnly and TimeSpan become durations. Anything else is formatted with InvariantCulture, so the same code produces the same spreadsheet on every machine.
public static byte[] Create(string sheetName, IEnumerable<IEnumerable<object?>> rows)
Parameters
sheetNamestringrowsIEnumerable<IEnumerable<object>>
Returns
- byte[]
Exceptions
- ArgumentNullException
rowsis null.- ArgumentException
sheetNameis blank, is longer than 31 characters, or contains one of: \ / ? * [ ]; or a row is null.- DocumentConversionException
The workbook could not be built.
CreateAsync(IEnumerable<XlsxSheet>, Stream, CancellationToken)
Builds a workbook from sheets and writes it to
destination. See Create(IEnumerable<XlsxSheet>) for the
semantics — this overload applies identical logic.
destination is written, from its current position, and is
not disposed, closed or sought.
public static Task CreateAsync(IEnumerable<XlsxSheet> sheets, Stream destination, CancellationToken ct = default)
Parameters
sheetsIEnumerable<XlsxSheet>The sheets to build the workbook from, one worksheet each.
destinationStreamThe stream the workbook is written to.
ctCancellationTokenCancels the build and the write to
destination.
Returns
Exceptions
- ArgumentNullException
sheetsordestinationis null.- ArgumentException
sheetsis empty, contains a null element, or names the same sheet twice; ordestinationis not writable.- OperationCanceledException
ctwas cancelled.- DocumentConversionException
The workbook could not be built or written.
CreateAsync(string, IEnumerable<IEnumerable<object?>>, Stream, CancellationToken)
Builds a workbook with one sheet populated from rows and writes it to
destination. See Create(string, IEnumerable<IEnumerable<object?>>)
for the exact typing and culture rules applied to each cell — this overload applies the
identical logic, writing to destination instead of returning an array.
destination is written, from its current position, and is
not disposed, closed or sought — it belongs to the caller, and may be write-only and
forward-only, such as an HTTP response body.
public static Task CreateAsync(string sheetName, IEnumerable<IEnumerable<object?>> rows, Stream destination, CancellationToken ct = default)
Parameters
sheetNamestringThe name of the sheet to create.
rowsIEnumerable<IEnumerable<object>>The rows to populate it with.
destinationStreamThe stream the workbook is written to.
ctCancellationTokenCancels the build and the write to
destination.
Returns
Exceptions
- ArgumentNullException
rowsordestinationis null.- ArgumentException
sheetNameis blank, is longer than 31 characters, or contains one of: \ / ? * [ ]; a row is null; ordestinationis not writable.- OperationCanceledException
ctwas cancelled.- DocumentConversionException
The workbook could not be built or written.
CreateToFileAsync(IEnumerable<XlsxSheet>, string, CancellationToken)
Builds a workbook from sheets and writes it to
outputPath, overwriting any existing file. See
Create(IEnumerable<XlsxSheet>) for the semantics.
public static Task CreateToFileAsync(IEnumerable<XlsxSheet> sheets, string outputPath, CancellationToken ct = default)
Parameters
sheetsIEnumerable<XlsxSheet>The sheets to build the workbook from, one worksheet each.
outputPathstringWhere to write the workbook. Overwritten if it exists.
ctCancellationTokenCancels the write to
outputPath.
Returns
Exceptions
- ArgumentNullException
sheetsoroutputPathis null.- ArgumentException
sheetsis empty, contains a null element, or names the same sheet twice; oroutputPathis blank.- DirectoryNotFoundException
outputPath's directory does not exist.- OperationCanceledException
ctwas cancelled.- DocumentConversionException
The workbook could not be built or written.
CreateToFileAsync(string, IEnumerable<IEnumerable<object?>>, string, CancellationToken)
Builds a workbook with one sheet populated from rows and writes it to
outputPath. See Create(string, IEnumerable<IEnumerable<object?>>)
for the exact typing and culture rules applied to each cell — this overload applies the
identical logic, writing to outputPath instead of returning an array.
Named CreateToFileAsync rather than a third CreateAsync overload: sheetName and rows come first, same as
CreateAsync(string, IEnumerable<IEnumerable<object?>>, Stream, CancellationToken),
but the destination is a string path instead of a Stream — the distinct name
keeps which kind of destination a call writes to visible at the call site, rather than
resting on the argument type alone.
public static Task CreateToFileAsync(string sheetName, IEnumerable<IEnumerable<object?>> rows, string outputPath, CancellationToken ct = default)
Parameters
sheetNamestringThe name of the sheet to create.
rowsIEnumerable<IEnumerable<object>>The rows to populate it with.
outputPathstringWhere to write the workbook. Overwritten if it exists.
ctCancellationTokenCancels the write to
outputPath.
Returns
Exceptions
- ArgumentNullException
outputPath,sheetNameorrowsis null.- ArgumentException
outputPathis blank;sheetNameis blank, is longer than 31 characters, or contains one of: \ / ? * [ ]; or a row is null.- DirectoryNotFoundException
outputPath's directory does not exist.- OperationCanceledException
ctwas cancelled.- DocumentConversionException
The workbook could not be built.
EvaluateFormulas(byte[])
A copy of xlsx with every formula's computed value written into the
file, not just held in memory.
public static byte[] EvaluateFormulas(byte[] xlsx)
Parameters
xlsxbyte[]
Returns
- byte[]
Remarks
XlsxFormula's own remarks explain why this is needed at all: a formula this
package writes carries a formula and nothing else, so a reader that trusts a cached value
rather than recalculating — a third-party tool, or this package's own
XlsxToPdfConverter before it started calling this internally — sees the formula's
source text where a value belongs. Excel itself is unaffected, because it recalculates on
open by default; this exists for everything that is not Excel.
A formula XlsxFormulaInspection would report as unsupported is left exactly as it was — no plausible-looking value is invented for it. Call InspectFormulas(byte[]) first if that distinction matters to the caller.
Exceptions
- ArgumentNullException
xlsxis null.- ArgumentException
xlsxis empty.- DocumentConversionException
The workbook could not be read or written.
EvaluateFormulasAsync(Stream, Stream, CancellationToken)
A copy of xlsx with every formula's computed value written into the
file, not just held in memory.
public static Task EvaluateFormulasAsync(Stream source, Stream destination, CancellationToken ct = default)
Parameters
sourceStreamThe stream the workbook is read from.
destinationStreamThe stream the evaluated workbook is written to.
ctCancellationTokenCancels the read, the evaluation and the write.
Returns
Remarks
source is read to its end and destination is
written; neither is disposed, closed or sought, and neither has to be seekable.
Exceptions
- ArgumentNullException
sourceordestinationis null.- ArgumentException
sourceis not readable or held no bytes, ordestinationis not writable.- OperationCanceledException
ctwas cancelled.- DocumentConversionException
The workbook could not be read or written.
Format(byte[], string, XlsxFormat)
Applies format to sheetName and returns the workbook.
public static byte[] Format(byte[] xlsx, string sheetName, XlsxFormat format)
Parameters
xlsxbyte[]The workbook to format. It is not modified.
sheetNamestringThe sheet to format.
formatXlsxFormatThe formatting to apply.
Returns
- byte[]
Remarks
Formatting is applied to an existing workbook rather than being an argument to
Create, so it composes with every way a workbook can arrive here — built by
Create(string, IEnumerable<IEnumerable<object?>>), appended to, or handed in by
a caller who never used this library to make it.
See XlsxFormat for the boundary: a CLOSED vocabulary rather than a small one, and what is still deliberately outside it.
Exceptions
- ArgumentNullException
xlsxorformatis null.- ArgumentException
xlsxis empty, orsheetNameis blank.- DocumentConversionException
The workbook could not be opened, the sheet does not exist, or a rule or validation named a range the sheet rejects — a malformed one such as
"B2:B1", or a column letter beyond the sheet's width. Ranges are checked by the library beneath rather than here, deliberately: a second range parser would be a second source of truth about what a range is.
FormatAsync(Stream, string, XlsxFormat, Stream, CancellationToken)
Reads a workbook from source, applies format to
sheetName, and writes the result to destination.
Neither stream is disposed, closed or sought.
public static Task FormatAsync(Stream source, string sheetName, XlsxFormat format, Stream destination, CancellationToken ct = default)
Parameters
sourceStreamThe stream the workbook is read from.
sheetNamestringThe sheet to format.
formatXlsxFormatThe formatting to apply.
destinationStreamThe stream the workbook is written to.
ctCancellationTokenCancels the read and the write.
Returns
Exceptions
- ArgumentNullException
formatis null, or a stream is null.- ArgumentException
A stream is unusable,
sourceheld no bytes, orsheetNameis blank.- OperationCanceledException
ctwas cancelled.- DocumentConversionException
The workbook could not be opened, or the sheet does not exist.
InspectFormulas(byte[])
Every formula xlsx carries, and whether each one is understood well
enough to trust its value. See XlsxFormulaInspection for why this asks rather
than assumes.
public static XlsxFormulaInspection InspectFormulas(byte[] xlsx)
Parameters
xlsxbyte[]
Returns
Exceptions
- ArgumentNullException
xlsxis null.- ArgumentException
xlsxis empty.- DocumentConversionException
The workbook could not be read.
InspectFormulasAsync(Stream, CancellationToken)
Every formula xlsx carries, and whether each one is understood well
enough to trust its value. See XlsxFormulaInspection for why this asks rather
than assumes.
public static Task<XlsxFormulaInspection> InspectFormulasAsync(Stream source, CancellationToken ct = default)
Parameters
sourceStreamThe stream the workbook is read from.
ctCancellationTokenCancels the read.
Returns
Remarks
source is read to its end and is neither disposed, closed nor sought.
Exceptions
- ArgumentNullException
sourceis null.- ArgumentException
sourceis not readable or held no bytes.- OperationCanceledException
ctwas cancelled.- DocumentConversionException
The workbook could not be read.
InspectSignatures(byte[])
Inspects xlsx for digital signatures — whether it carries one, how
many, and who claims to have signed it. Does not validate anything cryptographically; see
ValidateSignatures(byte[], DocumentSignatureValidationOptions?).
public static DocumentSignatureInfo InspectSignatures(byte[] xlsx)
Parameters
xlsxbyte[]
Returns
Exceptions
- ArgumentNullException
xlsxis null.- ArgumentException
xlsxis empty.- DocumentConversionException
The workbook could not be inspected.
InspectSignaturesAsync(Stream, CancellationToken)
Reads an .xlsx from source and inspects it for digital signatures — see
InspectSignatures(byte[]). source is read to its end and is
neither disposed, closed nor sought.
public static Task<DocumentSignatureInfo> InspectSignaturesAsync(Stream source, CancellationToken ct = default)
Parameters
sourceStreamctCancellationToken
Returns
Exceptions
- ArgumentNullException
sourceis null.- ArgumentException
sourceis not readable or held no bytes.- OperationCanceledException
ctwas cancelled.- DocumentConversionException
The workbook could not be inspected.
IsProtected(byte[])
Whether xlsx is an ENCRYPTED Office document.
public static bool IsProtected(byte[] xlsx)
Parameters
xlsxbyte[]The bytes to inspect.
Returns
Remarks
This is not a validity check, and a false is not a promise that
anything else will succeed. It distinguishes an encrypted document from a plain one;
input that is neither — an image, a PDF, a text file, random bytes — is not encrypted, so
this answers false for it, while every other method on this class refuses
it. Measured over real files: a JPEG and a PDF both return false here and
both throw from ExtractText.
The summary used to say "that is, whether the other methods on this class will refuse it". That reads as a guard — test it, and if false, proceed — and takes the wrong branch for every input that is not a document at all. The behaviour was always right and only the sentence was wrong, which is why the fix is here and not in the code.
Reads the file signature; it does not try the password and does not need one. A plain XLSX is a ZIP package, an encrypted one is a compound file, and the two are distinguishable from their first eight bytes.
Exceptions
- ArgumentNullException
xlsxis null.
IsProtectedAsync(Stream, CancellationToken)
Whether xlsx is an ENCRYPTED Office document.
public static Task<bool> IsProtectedAsync(Stream source, CancellationToken ct = default)
Parameters
sourceStreamThe stream the workbook is read from.
ctCancellationTokenCancels the read.
Returns
Remarks
source is read to its end and is neither disposed, closed nor
sought. Unlike IsProtected(byte[]), which answers false for
an empty array, an empty source is rejected — every Stream overload
in this package treats a source that held no bytes as a caller error rather than as content.
Exceptions
- ArgumentNullException
sourceis null.- ArgumentException
sourceis not readable or held no bytes.- OperationCanceledException
ctwas cancelled.
Protect(byte[], string)
A copy of xlsx encrypted with password, so it cannot
be opened without one.
public static byte[] Protect(byte[] xlsx, string password)
Parameters
xlsxbyte[]The workbook to encrypt.
passwordstringThe password required to open the result. May not be empty.
Returns
- byte[]
Remarks
This is file encryption, not workbook protection. Office offers both under the same menu and they are not the same thing: this scrambles the whole file, so nothing can be read without the password. The other kind - a flag asking a reader not to edit - is a request rather than a lock, and is deliberately not exposed here.
The result is not a XLSX package any more. An encrypted Office document is a compound file with the package sealed inside it, so every other method on this class refuses it - call Unprotect(byte[], string) first. That refusal is the honest behaviour: those methods could not read the content even if they tried.
Exceptions
- ArgumentNullException
xlsxorpasswordis null.- ArgumentException
xlsxis empty, orpasswordis empty.- DocumentConversionException
The workbook could not be read or encrypted.
ProtectAsync(Stream, Stream, string, CancellationToken)
Reads a workbook from source and writes the encrypted copy to
destination.
Neither stream is disposed, closed or sought.
public static Task ProtectAsync(Stream source, Stream destination, string password, CancellationToken ct = default)
Parameters
sourceStreamThe stream the workbook is read from.
destinationStreamThe stream the encrypted workbook is written to.
passwordstringThe password required to open the result. May not be empty.
ctCancellationTokenCancels the read and the write.
Returns
Remarks
This is file encryption, not workbook protection. Office offers both under the same menu and they are not the same thing: this scrambles the whole file, so nothing can be read without the password. The other kind - a flag asking a reader not to edit - is a request rather than a lock, and is deliberately not exposed here.
The result is not a XLSX package any more. An encrypted Office document is a compound file with the package sealed inside it, so every other method on this class refuses it - call Unprotect(byte[], string) first. That refusal is the honest behaviour: those methods could not read the content even if they tried.
ReadCell(byte[], string, string)
Reads a cell as a string. cellRef is an A1-style reference. Text follows
the calling thread's CurrentCulture — see
ReadSheet(byte[], string) for the full rule.
public static string ReadCell(byte[] xlsx, string sheetName, string cellRef)
Parameters
Returns
Exceptions
- ArgumentNullException
Any argument is null.
- ArgumentException
xlsxis empty, or a name is blank.- DocumentConversionException
The workbook could not be opened, the sheet does not exist, or the reference is not valid.
ReadCellAsync(Stream, string, string, CancellationToken)
Reads a workbook from source and returns a cell as a string.
cellRef is an A1-style reference. source is
read to its end and is neither disposed, closed nor sought.
public static Task<string> ReadCellAsync(Stream source, string sheetName, string cellRef, CancellationToken ct = default)
Parameters
sourceStreamsheetNamestringcellRefstringctCancellationToken
Returns
Exceptions
- ArgumentNullException
sourceis null.- ArgumentException
sourceis not readable or held no bytes, or a name is blank.- OperationCanceledException
ctwas cancelled.- DocumentConversionException
The workbook could not be opened, the sheet does not exist, or the reference is not valid.
ReadCellAsync(string, string, string, CancellationToken)
Reads a workbook from path and returns a cell as a string.
cellRef is an A1-style reference. See ReadCell(byte[], string, string) for the
culture rule applied to the text.
public static Task<string> ReadCellAsync(string path, string sheetName, string cellRef, CancellationToken ct = default)
Parameters
pathstringThe workbook to read.
sheetNamestringThe sheet containing the cell.
cellRefstringAn A1-style cell reference, e.g.
"B2".ctCancellationTokenCancels the read.
Returns
Exceptions
- ArgumentNullException
A path or a name is null.
- ArgumentException
pathor a name is blank, or the file it names is empty.- FileNotFoundException
pathdoes not exist.- DirectoryNotFoundException
path's directory does not exist.- OperationCanceledException
ctwas cancelled.- DocumentConversionException
The workbook could not be opened, the sheet does not exist, or the reference is not valid.
ReadMetadata(byte[])
The document properties xlsx carries.
public static DocumentMetadata ReadMetadata(byte[] xlsx)
Parameters
xlsxbyte[]
Returns
Exceptions
- ArgumentNullException
xlsxis null.- ArgumentException
xlsxis empty.- DocumentConversionException
The workbook could not be read.
ReadMetadataAsync(Stream, CancellationToken)
The document properties xlsx carries.
public static Task<DocumentMetadata> ReadMetadataAsync(Stream source, CancellationToken ct = default)
Parameters
sourceStreamThe stream the workbook is read from.
ctCancellationTokenCancels the read.
Returns
Remarks
source is read to its end and is neither disposed, closed nor sought.
Exceptions
- ArgumentNullException
sourceis null.- ArgumentException
sourceis not readable or held no bytes.- OperationCanceledException
ctwas cancelled.- DocumentConversionException
The workbook could not be read.
ReadSheet(byte[], string)
Reads a whole sheet as strings, anchored at A1: if the data starts at C3, its first value
is at rows[2][2]. Every row is padded to the last used column, so all rows have the
same length; blank cells — and entirely blank rows inside the range — come back as empty
strings rather than being dropped, which keeps rows[r][c] positionally meaningful.
Values are produced exactly as ReadCell(byte[], string, string) produces them, so the two can never disagree about what a cell says. A formula cell reads back one of two ways, and which one depends on the file rather than on this library:
- If the file carries a cached value, as one Excel has saved does, that cached value is returned and the formula is not evaluated. It can therefore be stale — a workbook whose inputs were edited by something that did not recalculate reports the old result.
-
If it does not — which is what this library writes, see XlsxFormula —
ClosedXML evaluates the formula on read, so a cell holding
=A1+A2over 1 and 2 reads back as"3", and one that cannot be evaluated reads back as its Excel error string (#DIV/0!,#NAME?,#REF!) rather than throwing.
Text follows the calling thread's CurrentCulture
— the same rule ReadCell(byte[], string, string) uses, and asymmetric with
Create(string, IEnumerable<IEnumerable<object?>>), which
deliberately writes with InvariantCulture so
the same code produces the same file everywhere. A number such as 1234.5 reads back
as "1234.5" under an invariant or en-US culture but "1234,5" under de-DE;
callers who parse the returned text as a number should account for that, e.g. by parsing
with an explicit CultureInfo rather than the default.
public static IReadOnlyList<IReadOnlyList<string>> ReadSheet(byte[] xlsx, string sheetName)
Parameters
Returns
- IReadOnlyList<IReadOnlyList<string>>
The sheet's used range, anchored at A1 and padded rectangular. Empty only if the sheet holds no values and no cell comments: formatting alone never widens the range, but a comment on an otherwise-blank cell does, because ClosedXML's
LastCellUsed()counts it as used.
Examples
// No need to know the workbook's shape in advance.
foreach (string name in WorkbookEditor.SheetNames(xlsx))
{
IReadOnlyList<IReadOnlyList<string>> grid = WorkbookEditor.ReadSheet(xlsx, name);
Console.WriteLine($"{name}: {grid.Count} rows x {grid[0].Count} columns");
}
Remarks
The whole range is materialised into memory at once, so its cost is proportional to
rows × columns, not to how much of that rectangle actually holds data. To keep
one far-flung stray value from exhausting memory, ReadSheet(byte[], string) throws
DocumentConversionException rather than allocate when the used range exceeds
2,000,000 cells.
Exceptions
- ArgumentNullException
Any argument is null.
- ArgumentException
xlsxis empty, orsheetNameis blank.- DocumentConversionException
The workbook could not be opened, the sheet does not exist, or the sheet's used range exceeds the 2,000,000-cell limit ReadSheet(byte[], string) will materialise.
ReadSheetAsync(Stream, string, CancellationToken)
Reads a workbook from source and returns a whole sheet as strings. See
ReadSheet(byte[], string) for the anchoring, padding, culture and formula rules — this
overload applies the identical logic. source is read to its end
and is neither disposed, closed nor sought.
public static Task<IReadOnlyList<IReadOnlyList<string>>> ReadSheetAsync(Stream source, string sheetName, CancellationToken ct = default)
Parameters
sourceStreamThe stream the workbook is read from.
sheetNamestringThe sheet to read.
ctCancellationTokenCancels the read.
Returns
- Task<IReadOnlyList<IReadOnlyList<string>>>
The sheet's used range, anchored at A1 and padded rectangular. Empty only if the sheet holds no values and no cell comments — see ReadSheet(byte[], string).
Exceptions
- ArgumentNullException
sourceis null.- ArgumentException
sourceis not readable or held no bytes, orsheetNameis blank.- OperationCanceledException
ctwas cancelled.- DocumentConversionException
The workbook could not be opened, the sheet does not exist, or the sheet's used range exceeds the 2,000,000-cell limit ReadSheet(byte[], string) will materialise.
ReadSheetAsync(string, string, CancellationToken)
Reads a workbook from path and returns a whole sheet as strings. See
ReadSheet(byte[], string) for the anchoring, padding, culture and formula rules — this
overload applies the identical logic.
public static Task<IReadOnlyList<IReadOnlyList<string>>> ReadSheetAsync(string path, string sheetName, CancellationToken ct = default)
Parameters
pathstringThe workbook to read.
sheetNamestringThe sheet to read.
ctCancellationTokenCancels the read.
Returns
- Task<IReadOnlyList<IReadOnlyList<string>>>
The sheet's used range, anchored at A1 and padded rectangular. Empty only if the sheet holds no values and no cell comments — see ReadSheet(byte[], string).
Exceptions
- ArgumentNullException
A path or
sheetNameis null.- ArgumentException
pathorsheetNameis blank, or the file atpathis empty.- FileNotFoundException
pathdoes not exist.- DirectoryNotFoundException
path's directory does not exist.- OperationCanceledException
ctwas cancelled.- DocumentConversionException
The workbook could not be opened, the sheet does not exist, or the sheet's used range exceeds the 2,000,000-cell limit ReadSheet(byte[], string) will materialise.
SetCell(byte[], string, string, object?)
Sets a cell and returns the updated workbook bytes. A cell holding an XlsxFormula is written as a formula instead of a literal value — see that type for the one limit worth knowing about cached values.
public static byte[] SetCell(byte[] xlsx, string sheetName, string cellRef, object? value)
Parameters
Returns
- byte[]
Exceptions
- ArgumentNullException
Any argument other than
valueis null.- ArgumentException
xlsxis empty, or a name is blank.- DocumentConversionException
The workbook could not be opened, the sheet does not exist, or the reference is not valid.
SetCellAsync(Stream, string, string, object?, Stream, CancellationToken)
Reads a workbook from source, sets one cell, and writes the result to
destination. cellRef is an A1-style reference. A cell
holding an XlsxFormula is written as a formula instead of a literal value —
see that type for the one limit worth knowing about cached values.
source is read to its end and destination is
written; neither is disposed, closed or sought, and neither has to be seekable.
public static Task SetCellAsync(Stream source, string sheetName, string cellRef, object? value, Stream destination, CancellationToken ct = default)
Parameters
sourceStreamThe stream the workbook is read from.
sheetNamestringThe sheet containing the cell.
cellRefstringAn A1-style cell reference, e.g.
"B2".valueobjectThe value to write.
nullclears the cell; an XlsxFormula writes a formula.destinationStreamThe stream the updated workbook is written to.
ctCancellationTokenCancels the read, the edit and the write.
Returns
Exceptions
- ArgumentNullException
sourceordestinationis null.- ArgumentException
sourceis not readable or held no bytes, a name is blank, ordestinationis not writable.- OperationCanceledException
ctwas cancelled.- DocumentConversionException
The workbook could not be opened, the sheet does not exist, or the reference is not valid.
SetCellAsync(string, string, string, string, object?, CancellationToken)
Reads a workbook from inputPath, sets one cell, and writes the result to
outputPath. cellRef is an A1-style reference. A cell
holding an XlsxFormula is written as a formula instead of a literal value —
see that type for the one limit worth knowing about cached values. The two paths may be
the same file: the updated bytes are computed in full before
outputPath is opened, so a workbook that fails to process — cannot be
read, or cannot be edited — leaves outputPath untouched. That guarantee
does not extend to a failure during the write itself: a full disk, a cancellation, or the
process dying mid-write can still leave a partial file, so in-place editing of an
irreplaceable workbook is not crash-safe.
public static Task SetCellAsync(string inputPath, string outputPath, string sheetName, string cellRef, object? value, CancellationToken ct = default)
Parameters
inputPathstringThe workbook to read.
outputPathstringWhere to write the result. Overwritten if it exists.
sheetNamestringThe sheet containing the cell.
cellRefstringAn A1-style cell reference, e.g.
"B2".valueobjectThe value to write.
nullclears the cell; an XlsxFormula writes a formula.ctCancellationTokenCancels the read and the write.
Returns
Exceptions
- ArgumentNullException
A path or a name is null.
- ArgumentException
A path or a name is blank, or the file at
inputPathis empty.- FileNotFoundException
inputPathdoes not exist.- DirectoryNotFoundException
inputPath's oroutputPath's directory does not exist.- OperationCanceledException
ctwas cancelled.- DocumentConversionException
The workbook could not be opened, the sheet does not exist, or the reference is not valid.
SheetNames(byte[])
Lists every sheet in the workbook, in tab order, including hidden sheets — hiding a sheet is a presentation choice, not a privacy boundary, and a caller who cannot see a hidden sheet listed has no way to discover it exists.
public static IReadOnlyList<string> SheetNames(byte[] xlsx)
Parameters
xlsxbyte[]The workbook bytes.
Returns
- IReadOnlyList<string>
The sheet names, in tab order.
Exceptions
- ArgumentNullException
xlsxis null.- ArgumentException
xlsxis empty.- DocumentConversionException
The workbook could not be opened.
SheetNamesAsync(Stream, CancellationToken)
Reads a workbook from source and lists every sheet in tab order,
including hidden sheets. source is read to its end and is neither
disposed, closed nor sought.
public static Task<IReadOnlyList<string>> SheetNamesAsync(Stream source, CancellationToken ct = default)
Parameters
sourceStreamThe stream the workbook is read from.
ctCancellationTokenCancels the read.
Returns
- Task<IReadOnlyList<string>>
The sheet names, in tab order.
Exceptions
- ArgumentNullException
sourceis null.- ArgumentException
sourceis not readable or held no bytes.- OperationCanceledException
ctwas cancelled.- DocumentConversionException
The workbook could not be opened.
SheetNamesAsync(string, CancellationToken)
Reads a workbook from path and lists every sheet in tab order, including
hidden sheets. See SheetNames(byte[]) for the full rule.
public static Task<IReadOnlyList<string>> SheetNamesAsync(string path, CancellationToken ct = default)
Parameters
pathstringThe workbook to read.
ctCancellationTokenCancels the read.
Returns
- Task<IReadOnlyList<string>>
The sheet names, in tab order.
Exceptions
- ArgumentNullException
pathis null.- ArgumentException
pathis blank, or the file it names is empty.- FileNotFoundException
pathdoes not exist.- DirectoryNotFoundException
path's directory does not exist.- OperationCanceledException
ctwas cancelled.- DocumentConversionException
The workbook could not be opened.
Unprotect(byte[], string)
A copy of xlsx with its encryption removed, so the rest of this class
can work on it.
public static byte[] Unprotect(byte[] xlsx, string password)
Parameters
Returns
- byte[]
Remarks
The output is not protected in any way. That is what was asked for, but the bytes this returns are readable by anyone who obtains them.
A workbook that was never encrypted is reported as such rather than passed through, because silently returning the input would make a broken pipeline look like a working one.
Exceptions
- ArgumentNullException
xlsxorpasswordis null.- ArgumentException
xlsxis empty, orpasswordis empty.- DocumentConversionException
The password was wrong, the workbook was not encrypted, or it could not be read.
UnprotectAsync(Stream, Stream, string, CancellationToken)
Reads an encrypted workbook from source and writes the unprotected copy to
destination.
Neither stream is disposed, closed or sought.
public static Task UnprotectAsync(Stream source, Stream destination, string password, CancellationToken ct = default)
Parameters
sourceStreamThe stream the encrypted workbook is read from.
destinationStreamThe stream the unprotected workbook is written to.
passwordstringThe password the workbook was encrypted with.
ctCancellationTokenCancels the read and the write.
Returns
Remarks
The output is not protected in any way. That is what was asked for, but the bytes this returns are readable by anyone who obtains them.
A workbook that was never encrypted is reported as such rather than passed through, because silently returning the input would make a broken pipeline look like a working one.
ValidateSignatures(byte[], DocumentSignatureValidationOptions?)
Validates every digital signature xlsx carries, returning the
report-level tamper-detection verdict alongside each signature's own certificate chain
trust and revocation status. Read
DocumentSignatureValidationResult's own remarks before treating its
CryptographicStatus as tamper detection — it is not; the report-level
IsCryptographicallyValid is. Never
performs revocation checking or certificate downloads over the network, regardless of
options — see DocumentSignatureValidationOptions's own
remarks.
public static DocumentSignatureValidationReport ValidateSignatures(byte[] xlsx, DocumentSignatureValidationOptions? options = null)
Parameters
xlsxbyte[]optionsDocumentSignatureValidationOptions
Returns
Exceptions
- ArgumentNullException
xlsxis null.- ArgumentException
xlsxis empty.- DocumentConversionException
The workbook could not be validated.
ValidateSignaturesAsync(Stream, DocumentSignatureValidationOptions?, CancellationToken)
Reads an .xlsx from source and validates its digital signatures — see
ValidateSignatures(byte[], DocumentSignatureValidationOptions?). source is read to its end and is
neither disposed, closed nor sought.
public static Task<DocumentSignatureValidationReport> ValidateSignaturesAsync(Stream source, DocumentSignatureValidationOptions? options = null, CancellationToken ct = default)
Parameters
sourceStreamoptionsDocumentSignatureValidationOptionsctCancellationToken
Returns
Exceptions
- ArgumentNullException
sourceis null.- ArgumentException
sourceis not readable or held no bytes.- OperationCanceledException
ctwas cancelled.- DocumentConversionException
The workbook could not be validated.
WithMetadata(byte[], DocumentMetadata)
A copy of xlsx carrying metadata.
public static byte[] WithMetadata(byte[] xlsx, DocumentMetadata metadata)
Parameters
xlsxbyte[]metadataDocumentMetadata
Returns
- byte[]
Remarks
A null property leaves what the workbook already had in place, so stamping a title does not silently erase an author. Pass an empty string to clear one.
Exceptions
- ArgumentNullException
xlsxormetadatais null.- ArgumentException
xlsxis empty.- DocumentConversionException
The workbook could not be read or written.
WithMetadataAsync(Stream, DocumentMetadata, Stream, CancellationToken)
A copy of xlsx carrying metadata.
public static Task WithMetadataAsync(Stream source, DocumentMetadata metadata, Stream destination, CancellationToken ct = default)
Parameters
sourceStreamThe stream the workbook is read from.
metadataDocumentMetadataThe properties to stamp.
destinationStreamThe stream the updated workbook is written to.
ctCancellationTokenCancels the read, the edit and the write.
Returns
Remarks
source is read to its end and destination is
written; neither is disposed, closed or sought, and neither has to be seekable.
Exceptions
- ArgumentNullException
source,metadataordestinationis null.- ArgumentException
sourceis not readable or held no bytes, ordestinationis not writable.- OperationCanceledException
ctwas cancelled.- DocumentConversionException
The workbook could not be read or written.