mirror of
https://github.com/storytold/craft-libs.git
synced 2026-11-12 08:52:32 +00:00
* 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-xlsx: the part layer of XLSX and XLSB workbooks Package::open finds the workbook part through craft-opc and reads the workbook part, shared strings (runs and phonetic readings), the styles tables as indexed tables, and a worksheet's rows one at a time with the rest of the part as a tree. Binary workbooks give the same workbook, strings, rows and merged cells from their records. Every other part stays reachable through Package::opc. From GridCraft crates/xlsx (7e0d96d7): read.rs, sheet_read.rs, styles.rs, xml.rs (string items, xstring escapes), xlsb.rs and its tests, split from GridCraft's document model. * craft-xlsx: XLSB opens up to 4 million cells, records counted once over the workbook Binary workbooks over 1 million cells were refused, a quarter of what .xls allows, and an allowance of 5 million records per part refused ordinary files: Excel writes four records per non-empty row besides the cells, and one BrtCellBlank for every formatted empty cell. Cells are now 4 million over the workbook (also the most shared strings), text 256 MiB, and records 40 million for every part together, as in craft-xls. Ported from storytold/gridcraft#3807. --------- Co-authored-by: kiwi4boy <kiwi4boy@gmail.com>
42 lines
2.5 KiB
Markdown
42 lines
2.5 KiB
Markdown
# craft-xlsx
|
||
|
||
Excel workbooks: `.xlsx`, `.xlsm`, `.xltx`, `.xltm` (SpreadsheetML in an OPC package,
|
||
transitional and strict) and `.xlsb` (the same package with binary parts). Clean-room, from
|
||
ECMA-376 Part 1 (SpreadsheetML), [MS-XLSB] and observed files. No `unsafe`.
|
||
|
||
This is the part layer. `Package::open` opens the container through `craft-opc` and reads:
|
||
|
||
| Call | Gives |
|
||
|---|---|
|
||
| `workbook()` | `Workbook`: sheets in tab order (name, id, visibility, kind, part), the 1904 date flag, defined names, the active tab, and the whole part as a tree |
|
||
| `shared_strings()` | `StringItem`s: text, formatted runs, phonetic readings |
|
||
| `styles()` | `Styles`: number formats, fonts, fills, borders, cell and cell-style formats, named styles, differential formats, the indexed palette, as indexed tables |
|
||
| `sheet(entry, each)` | each `Row` of `Cell`s to a callback, then a `SheetPart`: the rest of the worksheet as a tree, its relationships, columns and merged cells |
|
||
| `opc()`, `read_xml()`, `optional_xml()`, `rels()` | any other part |
|
||
|
||
A cell keeps the file's terms: a shared-string index, a format index, the formula text as the
|
||
file spells it, value and cell metadata indexes. `CellValue::resolve` gives the value it shows.
|
||
Shared formulas are not expanded and formulas are not parsed: that needs a formula grammar.
|
||
|
||
A binary workbook gives the same `Workbook`, strings, rows and merged cells, with saved values
|
||
only: its formulas are token streams that are not decoded, and its styles are not read (each
|
||
cell keeps its format index).
|
||
|
||
## Hostile input
|
||
|
||
- `Limits.package`: ZIP entries, bytes per part and in all (`craft-opc`).
|
||
- `Limits.xml`: one XML part. Rows and shared strings are streamed, so this bounds one row, one
|
||
string and what is left of a part, not a sheet's length.
|
||
- `Limits.binary_records`, `binary_cells`, `binary_text`: a binary workbook, over all its parts
|
||
(40 million records, 4 million cells and as many shared strings, 256 MiB of text, as
|
||
`craft-xls` allows). Fixed caps: 1024 sheets, 100,000 merged ranges per sheet, 64 nested
|
||
extension blocks.
|
||
- Cells and rows outside the 1,048,576 × 16,384 grid are dropped and counted.
|
||
|
||
SpreadsheetML is read leniently: a damaged optional part is a warning, a damaged worksheet keeps
|
||
the rows before the damage. A binary part that does not parse fails the read, since skipping a
|
||
record would lose data without a trace.
|
||
|
||
Shared with `craft-xls` and `craft-ods` through `craft-sheet`: `CellRef`, `Range`, `Value`,
|
||
`CellError`, `Visibility`, sheet-name quoting, built-in number formats and the palette.
|