Recursive AI

Read an ODS spreadsheet in C#

OneDocument is a free, open-source Word, Excel and PowerPoint document library for .NET from Recursive AI. MIT or Apache-2.0, no native dependencies.

.ods is the spreadsheet format OpenOffice and LibreOffice Calc save. Read its typed cells and stored formula results without opening a desktop spreadsheet app.

Terminal
dotnet add package RecursiveAI.OneDocument.Spreadsheets

Requires .NET 10 (net10.0); .NET 9 and earlier aren’t supported.

C#
using RecursiveAI.OneDocument.Spreadsheets;
using var book = Workbook.Open("stock.ods");
Console.WriteLine(book.Sheets[0]["D1"].Text);

stock.ods is in the example. The snippet prints:

Text
99

99 is the value saved in the file; call Recalculate() to get 5.

Unzip the example, then dotnet run.

The full program

stock.ods is included in the example. Its Stock sheet has A1 = Pens, B1 = 2, C1 = 3, and D1 = SUM(B1:C1) with a deliberately stale cached value of 99.

The full program reads those four cells, lists import losses, then explicitly recalculates D1.

C#
using RecursiveAI.OneDocument.Spreadsheets;
 
using var book = Workbook.Open("stock.ods");
var sheet = book.Sheets[0];
foreach (string address in new[] { "A1", "B1", "C1", "D1" })
    Console.WriteLine($"{address}: {sheet[address].Value.Kind} {sheet[address].Text}");
var losses = book.ImportLoss?.Items ?? [];
Console.WriteLine($"Import losses: {losses.Count}");
foreach (var loss in losses)
    Console.WriteLine($"{loss.Code}: {loss.Message}");
Console.WriteLine($"Formula: {sheet["D1"].Formula}");
book.Recalculate();
Console.WriteLine($"After recalculation: {sheet["D1"].Text}");
Text
A1: Text Pens
B1: Number 2
C1: Number 3
D1: Number 99
Import losses: 0
Formula: SUM(B1:C1)
After recalculation: 5

Variations

Save the imported workbook as XLSX without recalculating. This writes stock.xlsx and keeps the stored result:

C#
using RecursiveAI.OneDocument.Spreadsheets;
using var book = Workbook.Open("stock.ods");
book.SaveAs("stock.xlsx");
Console.WriteLine(book.Sheets[0]["D1"].Text);
Text
99

Read Excel cells · Recalculate formulas

The short answer

To read an OpenOffice spreadsheet in C#, first check the format of the actual file. An ODS file is an OpenDocument spreadsheet, not an XLSX file with a different extension. OneDocument’s Workbook.Open detects ODS content and imports it into the same workbook model used for XLSX. Read cells through the worksheet’s address indexer, and inspect Value.Kind before treating their contents as numbers or text.

The example deliberately separates reading a formula from calculating it. D1 stores both a formula and the cached result 99. Opening the file reads that saved result. It does not silently replace it with 5. This is useful when you need to inspect what the producer actually saved, rather than change the document during import.

How do I read an OpenOffice Excel file in C#?

Use the snippet at the top for a single cell and the full program for typed values. The ODS documentation says that Workbook.Open sniffs the content: the extension does not decide the input format. ODS, spreadsheet templates in OTS, and flat FODS are supported by the OpenDocument spreadsheet layer.

The importer converts the source to an in-memory XLSX package wrapped by Workbook. That makes an address such as B1 usable through the ordinary worksheet API, but it is a conversion, not a promise that every ODF feature has an identical workbook counterpart. The sample has only text, numbers and a simple formula, so its import loss count is zero. For an unfamiliar workbook, enumerate ImportLoss.Items as the full program does before accepting the result.

Examples of documented import losses include shapes, pictures and charts, rich-text formatting inside cells, filter conditions and features without a workbook counterpart. The text of a rich-text cell is kept even when its internal formatting is reported as a loss. A zero count on this sample says nothing about a different input.

How do I read typed cell values?

Use Text when you want a textual representation of a stored cell value. Use Value.Kind and the typed value members when downstream code needs to distinguish strings from numbers. Do not infer the type from whether the displayed text looks numeric: an identifier may legitimately be text.

Formula cells need a second decision. Read the stored result when reproducing the source’s saved state. Call Recalculate when you want the calculation engine to compute results now. The full program demonstrates that decision with a visible change from 99 to 5. A formula that cannot be parsed, uses an unsupported dialect, or refers to another document can instead retain its cached value as a constant with a defect, as the ODS docs explain.

How do I convert OpenOffice to Excel?

The variation imports the supplied ODS and saves stock.xlsx. It does not call Recalculate, so the saved cached value remains 99. Recalculate before saving if fresh results are part of your conversion requirement.

Review the import loss report before treating a conversion as acceptable. Saving the imported model to XLSX cannot reconstruct a feature already dropped during ODS import. For a read-only inspection that needs no conversion output, leave out SaveAs entirely and dispose the workbook after reading.

All onedocument recipes