Skip to content

Cell Protection

Protection takes two switches, and both have to be right. Each cell carries a locked flag that lives in its cell style, and the sheet carries a flag saying whether those per-cell flags are enforced. Nothing is protected until Sheet.Protection().LockSheet(true) is called, and once it is, every cell that has not been explicitly unlocked becomes read-only. So the usual shape of the job is inverted from what you might expect: you mark the cells you want people to edit, then lock the sheet.

CallEffect
CellStyle.SetProtection(false, false)The cell stays editable after the sheet is locked.
CellStyle.SetProtection(true, false)The cell is read-only, its formula still visible in the formula bar.
CellStyle.SetProtection(true, true)Read-only and the formula is hidden.
Sheet.Protection().LockSheet(true)Enforces all of the above. Without it the flags are inert.
Workbook.Protection().LockStructure(true)Stops sheets being added, renamed or deleted. A separate control.
open := ss.StyleSheet.AddCellStyle()
open.SetProtection(false, false)

from, to, _ := reference.ParseRangeReference("A1:D10")
for rowIdx := from.RowIdx; rowIdx <= to.RowIdx; rowIdx++ {
    for colIdx := from.ColumnIdx; colIdx <= to.ColumnIdx; colIdx++ {
        sheet.Row(rowIdx).Cell(reference.IndexToColumn(colIdx)).SetStyle(open)
    }
}

sp := sheet.Protection()
sp.LockSheet(true)
sp.SetPassword("unioffice")

reference is github.com/unidoc/unioffice/v2/spreadsheet/reference. There is no range setter for styles, so unlocking a block means walking it cell by cell. Column.SetStyle covers a whole column in one call and the example uses it for column F, which is cheaper than looping when the whole column shares a style.

Writing to a cell through Sheet.Row(...).Cell(...) creates it if it is not there yet, so the loop leaves you with a materialized A1:D10 block whether or not those cells hold values. That is what you want here: an unlocked cell that does not exist in the file has no style to carry the flag.

Limitations

SetPassword runs the string through spreadsheet.PasswordHash, the legacy SpreadsheetML hash. It folds any password down to a 16-bit value written as four hex digits. It stops accidental edits and nothing more. Do not use it where confidentiality matters.

Cell.SetStyle replaces the cell’s whole style, not just the protection part. Applying an unlock style over cells that already had number formats, fonts or borders discards them. Set protection on the style you were going to use anyway, rather than applying a second, protection-only style on top.

Column.SetStyle sets the column default. A cell that already carries its own style keeps it, so unlocking a column does not unlock cells inside it that were styled individually.

Sheet protection is per sheet. Locking one sheet leaves the others open, and Workbook.Protection is a different thing again: it controls the workbook structure and window layout, not cell editing.

Run the example

The example unlocks A1:D10 and column F, widens column F, then locks the sheet behind the password unioffice. Everything outside those two regions is read-only when the file is opened.

git clone https://github.com/unidoc/unioffice-examples.git
cd unioffice-examples/spreadsheet/cell-protection
go run main.go

If this is your first time using UniOffice, follow the getting started guide to create an API key and set up your development environment.

View the full source
Last updated on