Files
craft-libs/crates/ods/README.md
Dylan M. Taylor 0d68632c9b Add craft-ods: OpenDocument spreadsheet tables on craft-odf (#990)
* Add craft-sheet: the cell positions, values and tables the spreadsheet formats share

craft-xls carried its own CellRef, Range, Value, CellError, Visibility, sheet-name
quoting, built-in number format table and indexed palette. craft-xlsx and craft-ods
need the same ones, so they move to a crate with no dependencies and craft-xls
re-exports them: an application gets one Value and one CellRef whichever file it read.

Added on the way: A1 parsing (CellRef::parse, Range::parse), Range::count and a1,
CellError::parse and the newer error values SpreadsheetML stores as text,
builtin_format_id for writers.

* Add craft-ods: OpenDocument spreadsheet tables on craft-odf

read() checks the spreadsheet mimetype, refuses an encrypted package, and reads the
tables of content.xml into sheets of cells that keep the file's terms: value type,
the raw value, displayed text, formula text, style name, covered cells, with
repeats expanded and merged ranges. Cell::value() gives the shown value, dates and
durations as serial numbers.

From GridCraft crates/xlsx/src/ods.rs and its tests (7e0d96d7), split from
GridCraft's document model and moved onto craft-odf and craft-xml's pull reader.
Options::only_sheet covers WordCraft's reader of one chosen sheet.
2026-11-11 20:16:51 -05:00

38 lines
2.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# craft-ods
OpenDocument spreadsheets (`.ods`, `.ots`): the tables of `content.xml` (ODF 1.3 Part 3,
section 9), on `craft-odf` for the package. Clean-room. No `unsafe`.
`read(bytes, &Options)` gives a `Workbook` of `Sheet`s in document order. Each sheet has its
`table:name` as written, its non-blank `Cell`s by position (repeated rows and columns expanded)
and its merged ranges. A cell keeps the file's terms:
| Field | From |
|---|---|
| `value_type` | `office:value-type`, or `calcext:value-type="error"` |
| `raw`, `currency` | the value attribute for the type, `office:currency` |
| `text`, `paragraphs` | the displayed paragraphs, white space collapsed as ODF says, annotations left out |
| `formula` | `table:formula` as written (`of:=…`), not translated |
| `style` | `table:style-name` |
| `covered` | a `table:covered-table-cell` |
`Cell::value()` gives the shown value: numbers, booleans, strings, dates as serial numbers in
the 1900 date system (`date_serial`) and durations in days (`duration_days`). It is `None` when
the type's value is missing or unreadable, or for a formula without a cached result, so the
caller chooses what to show.
`read_content` reads a `content.xml` on its own (a flat `.fods` goes through
`craft_odf::flat::to_package` first). An encrypted package is `Error::Encrypted`; decrypt it with
`craft_odf::crypt::decrypt` and read the result.
## Hostile input
`Options` bounds the package (`craft-odf`), cells (1,000,000), merged ranges (100,000), text
(64 MiB, repeats counted) and one cell's text or attribute (1 MiB), all over the whole
workbook. Repeats and spans are checked against the 1,048,576 × 16,384 grid before anything is
expanded; blank padding past the grid's edge is clipped, data past it is an error. The XML is read strictly
(unbalanced markup, a document type declaration or an undefined entity fails the read), with
`craft-xml`'s depth and attribute limits. At most 1024 tables.
`Options::only_sheet` keeps one sheet's cells and lists the others by name.