Recursive AI

Coming from ClosedXML

All onedocument docs

ClosedXML edits workbooks through XLWorkbook, IXLWorksheet, IXLCell and IXLRange; ClosedXML.Report fills templates. OneDocument's equivalents are Workbook, Worksheet, Cell, Spreadsheet and Template. Read README.md first for what is true on every page.

Open, read, write, save

C#
// ClosedXML
using var wb = new XLWorkbook(path);
IXLWorksheet ws = wb.Worksheet("Sales");
ws.Cell("B2").Value = 1200;
ws.Cell("A2").Value = "North";
double d = ws.Cell("B2").GetDouble();
string s = ws.Cell("A2").GetString();
wb.Save();
C#
// OneDocument
using Workbook wb = Workbook.Open(path);
Worksheet ws = wb.Sheets["Sales"];
ws["B2"].Value = 1200;
ws["A2"].SetString("North");
double d = ws["B2"].Number;
string s = ws["A2"].Text;
wb.Save();

ws.Cell(row, column) is ws[row, column]. A new workbook is Workbook.Create(); ws.Cell(...).Value = "text" is SetString because a string cell holds a handle into the workbook's string table. SaveAs(path) chooses the format by extension (.xlsx, .xlsb, .xls, .csv, .pdf, ...).

Formulas

C#
// ClosedXML
ws.Cell("B5").FormulaA1 = "SUM(B2:B4)";
wb.RecalculateAllFormulas();
C#
// OneDocument
ws["B5"].Formula = "SUM(B2:B4)";
wb.RecalculateAll();     // or wb.Recalculate() for only what changed

Reading a formula cell returns its cached value; ClosedXML evaluates on demand, OneDocument never does until you call Recalculate. FormulaR1C1 has a counterpart in the public formula tree (docs/calc.md).

Styles

C#
// ClosedXML
ws.Range("A1:C1").Style.Font.Bold = true;
ws.Cell("B2").Style.NumberFormat.Format = "#,##0.00";
ws.Range("A1:C1").Merge();
C#
// OneDocument
ws.Range("A1:C1").UpdateStyle(s => s with { Font = (s.Font ?? new CellFont()) with { Bold = true } });
ws.Range("B2").NumberFormat = "#,##0.00";
ws.Range("A1:C1").Merge();

A SheetRange is a handle over the sheet, not a style object: styles are immutable records, and UpdateStyle applies the change to every cell of the range (once per distinct current style).

Tables and data

C#
// ClosedXML
ws.Cell("A1").InsertTable(orders);
ws.Range("A1:D10").CreateTable("Orders");
C#
// OneDocument
Spreadsheet.Write(path, orders);                      // [SpreadsheetRow] on the type; also .csv and .tsv
ws.Tables.Add("Orders", CellRange.Parse("A1:D10"));   // a table over cells already there

Spreadsheet.Read<T>(path) is the typed way back (docs/spreadsheets-poco.md). There is no call that inserts a collection at a cell of an open workbook.

Templates (ClosedXML.Report)

C#
// ClosedXML.Report
var template = new XLTemplate(path);
template.AddVariable(invoice);
template.Generate();
template.SaveAs(outPath);
C#
// OneDocument
Template.Render(path, invoice, outPath);              // the same call for .xlsx, .docx and .pptx

The tag syntax differs: OneDocument uses {{ expression }} and {% for item in items %} with Excel formulas as expressions (docs/templating.md, docs/templating-xlsx.md). Existing ClosedXML.Report templates must be rewritten.

PDF

ClosedXML does not render. Office.Convert("in.xlsx", "out.pdf") does, with the Rendering package.

Streaming

ClosedXML loads the whole workbook. For large sheets use XlsxStreamReader and XlsxStreamWriter (docs/spreadsheets-streaming.md).

Not supported or different

  • Ranges (ws.Range("A1:C10")) read and write values as a two-dimensional array and set styles, number formats, merges and Clear; there are no IXLRows / IXLColumns objects, and no copy or sort on a range.
  • No AdjustToContents, InsertRowsAbove style layout helpers; column width and row height are set through ColumnProperties and GetRow(row).Height.
  • ws.AddPicture(bytes, "E1", widthPixels, heightPixels, altText) adds a picture; there is no chart or shape creation call. Existing ones are kept and rendered.
  • Formulas are not evaluated on read; no ws.Evaluate("...") shortcut on the sheet.
  • Pivot tables: existing ones are kept and can be refreshed (docs/spreadsheets-pivots.md); there is no pivot builder.