Skip to content

AutoFit measured like Excel's own AutoFit - #15

Merged
glenntosco merged 4 commits into
mainfrom
autofit
Oct 14, 2026
Merged

glenntosco merged 4 commits into
mainfrom
autofit

Conversation

@glenntosco

Copy link
Copy Markdown
Collaborator

Columns are measured with a Calibri 11 glyph table calibrated against Excel 16 through COM (every ASCII glyph, regular and bold), rendered as displayed (formatted numbers, dates, bold, font size), using Excel's column-width formula. New Worksheet.AutoFitColumns(Func<string, bool, double> measure, ...) and PackageOptions.TextMeasurer accept real font metrics. The number-format parser used for measuring never throws on malformed codes (28 hostile-input cases).

Widths vs Excel: ten digits 11.07 (11.0), "Description" bold 11.22 (11.14), default date column 10.77 (10.71).

🤖 Generated with Claude Code

glenntosco and others added 4 commits October 14, 2026 08:38
…t Excel instead of counting characters

AutoFitColumns sized columns by character count, so headers came out wider or
narrower than the EPPlus/Excel widths the import templates were built around.
Columns are now sized the way Excel's own AutoFit does:

- TextMeasure: hinted Calibri 11 advance widths in pixels for ASCII and Latin-1
  (accented letters as wide as their base letter), measured by auto-fitting every
  glyph in Excel 2016; digits are 7 px = one column unit, so "0000000000" is 10.
  Bold widens only the nine glyphs Calibri Bold actually widens on the pixel grid.
  Other scripts count one digit per character, two for CJK.
- Column width = Truncate((textPixels + 5) / 7 * 256) / 256 (ECMA-376 formula),
  with Excel's 3.6% layout factor; results match Excel to a few tenths of a unit
  ("Description" bold 11.2 vs Excel 11.14, ten digits 11.07 vs 11.0).
- Cells are measured as displayed: NumberDisplayFormat renders a number under its
  format ($1,234.50, 12.34%, 1.23457E+12, 2026-10-13, Tuesday, October 13, 2026,
  36:00:00), with month/day names and elapsed digits taken from the value; General
  follows Excel's 11-digit rule. Dates and durations follow the cell's style.
- Hooks for real font metrics: Worksheet.AutoFitColumns(Func<string,bool,double>)
  and PackageOptions.TextMeasurer, both returning widths in digit units.
- StyleSheet.FontTraits replaces WidthFactor (bold and size separately).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Format codes come from user styles and, in edit and template mode, from files
SheetStream did not write. An unterminated '[' at the end of a code made the
bracket Substring length negative; elapsed-time tokens could ask for a negative
or absurd digit count on NaN or huge serials. Unterminated quotes and brackets
now run to the end of the code, date-letter runs and elapsed digits are capped,
and anything the parser still cannot handle falls back to General instead of
failing the save over a width estimate.

Tests feed the parser unterminated quotes and brackets, lone escapes at the end,
only semicolons, nested brackets, 10,000-character runs and a 1 MB code, and
render each with NaN, infinities and 1e300.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@glenntosco
glenntosco merged commit 950f570 into main Oct 14, 2026
@glenntosco
glenntosco deleted the autofit branch October 14, 2026 13:47
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