Skip to content

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

GuideCovers
BordersBorder styles per cell, and boxing a whole range.
Cell CommentsNotes attached to a cell reference.
Cell ProtectionLocking a sheet while leaving chosen cells editable.
Conditional FormattingComparison rules, color scales, icon sets and data bars.
Merge CellsSpanning one value across a region.
Number and Date FormatsFormat codes, standard formats, and how dates are stored.
Print Empty CellsWalking a row including the cells that were never written.
Rich TextMixed formatting within one cell.
Rotate Cell TextAngled and vertically stacked text.
Wrap TextWrapping long values inside the column width.
Last updated on