Cells
Almost nothing about a cell’s appearance is stored on the cell. Formatting lives in a cell style held by the workbook stylesheet, and the cell keeps only an index into the list of styles. You build a style, set its properties, and assign it:
style := ss.StyleSheet.AddCellStyle()
style.SetNumberFormat("#,##0.00")
cell.SetStyle(style)That indirection is what makes large workbooks possible. Fifty thousand
formatted cells hold fifty thousand indices pointing at a handful of styles,
not fifty thousand copies of the formatting. SetStyle also deduplicates: two
styles you built separately with identical properties collapse into one entry
when they are assigned.
Finish a style before assigning it
AddCellStyle returns a style that is not yet part of the workbook. It joins
the stylesheet when Cell.SetStyle or Column.SetStyle puts it there, and two
things follow from that.
CellStyle.Index() returns 0 until the style has been assigned to something.
Reading the index straight after creating the style gives you 0, which is the
default style, and SetStyleIndex(0) then leaves the cell unformatted with no
error reported. Assign the style to one cell first, and take Index() after
that if you want to apply it to the rest by index.
Changing a style after it has been assigned is unreliable in both directions. If
the style was newly registered, the cells holding its index see the change,
because they all point at the same object. If it was deduplicated into a style
that already existed, the handle you are holding was left behind and the change
goes nowhere. Set everything you want on a style before the first SetStyle
call and neither case can bite you.
Value and presentation are separate
SetNumber stores a number. Whether it reads as 1234.5, currency, a percentage
or a date is decided by the number format on the style. Dates in particular have
no type of their own: a date is a count of days since 1899-12-30, so a cell
holding one with no date format displays a five-digit integer. That is the
single most common surprise in generated spreadsheets, and
Number and Date Formats covers it in full.
Merging is a sheet property
Merging is the exception to all of the above. It describes a rectangular region
rather than a single cell, so it lives on the worksheet: Sheet.AddMergedCells
appends to the sheet’s merge list and Sheet.MergedCells reads it back. Nothing
is written into the cells, and merging applies no formatting, so centering the
visible value is a separate style.
Comments are similar. They are held in a per-sheet comments part keyed by cell
reference, not on the cell, and their text is a RichText rather than a string.
Where to look
| Guide | Covers |
|---|---|
| Borders | Border styles per cell, and boxing a whole range. |
| Cell Comments | Notes attached to a cell reference. |
| Cell Protection | Locking a sheet while leaving chosen cells editable. |
| Conditional Formatting | Comparison rules, color scales, icon sets and data bars. |
| Merge Cells | Spanning one value across a region. |
| Number and Date Formats | Format codes, standard formats, and how dates are stored. |
| Print Empty Cells | Walking a row including the cells that were never written. |
| Rich Text | Mixed formatting within one cell. |
| Rotate Cell Text | Angled and vertically stacked text. |
| Wrap Text | Wrapping long values inside the column width. |