Reading and writing XLSX (OOXML) is handled by unvell.ReoGrid.IO.Excel.
It depends on no external packages (neither the Open XML SDK nor EPPlus is used).
Everything is bundled with the One packages.
Reading and writing
using unvell.ReoGrid.Core;
using unvell.ReoGrid.IO.Excel;
Workbook loaded = XlsxReader.Read("book.xlsx");
XlsxWriter.Write(wb, "out.xlsx");
// a stream works too
using var stream = File.OpenRead("book.xlsx");
Workbook fromStream = XlsxReader.Read(stream);
XlsxWriter.Write has a stream overload as well.
Streaming reads
Reading is streamed through XmlReader directly into the sparse store.
Memory usage is proportional to the number of cells that actually exist
(not the sheet’s declared dimensions).
Lazy loading for huge files
// open a huge file with per-sheet lazy loading
using var virtualBook = XlsxReader.OpenVirtual("large.xlsx", SheetLoadMode.OnDemand);
| Mode | Behavior |
|---|---|
OnDemand | Builds each sheet the first time it is displayed |
Background | Builds the active sheet first, then prefetches the rest in the background |
VirtualWorkbook is IDisposable. It holds on to the underlying stream,
so dispose it when you are done.
How formulas are handled
Formulas are not re-evaluated on load. The cached values saved by Excel are used as-is.
var wb = XlsxReader.Read("book.xlsx");
// The cached values Excel saved are read as-is, so nothing is re-evaluated on load.
// Call this only when you want to compute them yourself.
foreach (var sheet in wb.Worksheets)
sheet.Recalculate();
There is a reason for this design: even for files containing functions that V5 does not
implement, the values Excel calculated are displayed as-is. Re-evaluating them would
turn them into #NAME?.
What is supported
| Feature | Read | Write |
|---|---|---|
| Values (numbers, strings, booleans, dates, errors) | Yes | Yes |
| Shared strings, inline strings, rich strings | Yes | Yes |
| Styles (font, color, alignment, wrapping) | Yes | Yes |
| Number formats | Yes | Yes |
| Borders | Yes | Yes |
| Merged cells | Yes | Yes |
| Row heights, column widths, hidden state | Yes | Yes |
| 1900 / 1904 date systems | Yes | Yes |
Conditional formatting (<conditionalFormatting> / <dxfs>) | Yes | Yes |
Defined names (<definedNames>) | Yes | Yes |
| Outlines (grouping) | Yes | Yes |
| Images (drawing) | Yes | Yes |
Page setup (<pageSetup>) | Yes | Yes |
Header/footer (<headerFooter>) and print titles | Yes | Yes |
| View state (frozen panes, zoom, gridlines), hidden sheets, tab colors | Yes | Yes |
Auto filter (<autoFilter>) | Yes | Yes |
Cell notes (comments{n}.xml plus VML) | Yes | Yes |
Data validation (<dataValidations>) | Yes | Yes |
Sheet protection (<sheetProtection>) | Yes | Yes |
| Formulas | Yes (cached values preserved) | Yes |
Not supported
| Feature | Notes |
|---|---|
| Shared formula expansion | |
| Charts and shapes | Images are supported |
| Cell types | XLSX has no corresponding concept, so they become plain cells |
| Threaded comments | Only the classic note is supported |
| Alternating row fills (banded rows) | Excel keeps them inside a table style |
Built-in names (_xlnm.*) | Only Print_Area and Print_Titles round-trip, as PrintSettings |
| Data bar negative colors, zero axis, and borders | Requires the OOXML x14 extensions |
| Split (unfrozen) panes | Frozen panes do round-trip |
cellStyleXfs (xfId) style inheritance | Not expanded on read |