Skip to content

fix(spreadsheet): single-row sheets, workbook titles, XLSB detection - #33

Merged
chaliy merged 11 commits into
mainfrom
claude/project-thread-foq2nw
Oct 27, 2026
Merged

chaliy merged 11 commits into
mainfrom
claude/project-thread-foq2nw

Conversation

@chaliy

@chaliy chaliy commented Oct 26, 2026

Copy link
Copy Markdown
Contributor

Requested by Михайло · project thread

What changed

First slice of the #11 follow-ups (format detection, correctness, panic profile):

  • Single-row sheets now render the row as data under its Excel column letters (| A | B |), and count in stats.rows. Before, the row became a header with no data rows.
  • Spreadsheet titles: Extraction.title is filled for XLSX (docProps/core.xml), ODS (meta.xml) and XLS (SummaryInformation, code-page aware). Best effort: a malformed property part gives None, never an error.
  • XLSB detection: application/vnd.ms-excel.sheet.binary.macroEnabled.12, .xlsb and xl/workbook.bin containers map to the new Format::Xlsb instead of Xlsx. XLSB is still rejected with UnsupportedFormat here; the reader comes in a follow-up PR.
  • Missing _rels/.rels: XLSX packages without it get the standard officeDocument relationship before calamine opens them, so they parse.
  • panic = "unwind" in the release profile, so the catch_unwind guard actually works in the CLI and the Python/Node bindings. Before, a parser panic aborted the process.
  • Trailing newline: kept, now documented as intended (non-empty output ends with exactly one \n).

Why

These gaps showed up while making markkit fetchkit's Office backend (#11).

Before / After

single.xlsx (openpyxl, one row, title "FY26 Summary"):

Before (main):

## Totals

| Q1 | 100 | Q2 | 120 |
| --- | --- | --- | --- |

title: null

After:

## Totals

| A | B | C | D |
| --- | --- | --- | --- |
| Q1 | 100 | Q2 | 120 |

title: "FY26 Summary"

just fmt lint test check-okf test-scripts examples pass locally. cargo deny is not installed locally and runs in CI.

Risk

  • Low
  • Output change for single-row sheets (intended). Format gains a variant (#[non_exhaustive], so not breaking). Slightly larger release binaries with unwind tables.

Checklist

  • Tests added or updated (single row, titles for all three formats, malformed property sets, missing _rels, XLSB content type; new fuzz fixtures)
  • Backward compatibility considered

Part of #11


Generated by Claude Code

- Single-row sheets render the row as data under Excel column letters
- Extraction.title from XLSX core.xml, ODS meta.xml, XLS SummaryInformation
- XLSB content type / extension / container detected as Format::Xlsb, not Xlsx
- XLSX without _rels/.rels gets the standard package relationship
- Release profile uses panic = "unwind" so catch_unwind guards work
- Document the trailing newline as intended

Part of #11
- Single-row sheets render the row as data under Excel column letters
- Extraction.title from XLSX core.xml, ODS meta.xml, XLS SummaryInformation
- XLSB content type / extension / container detected as Format::Xlsb, not Xlsx
- XLSX without _rels/.rels gets the standard package relationship
- Release profile uses panic = "unwind" so catch_unwind guards work
- Document the trailing newline as intended

Part of #11
@chaliy chaliy self-assigned this Oct 26, 2026
@chaliy
chaliy merged commit 42414ce into main Oct 27, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant