xlsx/modify-set-cell-value

Open cell-bold.xlsx (A1='Hello bold cell' with bold style s=1), assign ws['A1']='hello', save. Assert (a) A1's displayed value is 'hello' (via sharedStrings), (b) A1's @s='1' is preserved — the cell's bold formatting must not be clobbered by the value change, (c) the dimension ref and other structural attributes are unchanged.

Library verdicts: python-xlsx: — xlsxjs: —

Metadata

Feature idxlsx/modify-set-cell-value
Formatxlsx
Categorymodify-in-place
Spececma-376-5-part-1 § 18.3.1.4 c

XPath assertions

ID / partPredicateXPathpython-xlsxxlsxjs
a1-style-preserved
xl/worksheets/sheet1.xml
equal = 1
A1's @s index (pointing at the bold cellXf entry) must be preserved — the value change must not drop the style reference.
//s:sheetData/s:row/s:c[@r='A1']/@s
a1-is-string-typed
xl/worksheets/sheet1.xml
equal = s
A1 must remain a shared-string-typed cell.
//s:sheetData/s:row/s:c[@r='A1']/@t
a1-references-shared-string
xl/worksheets/sheet1.xml
exist
A1 must still carry a <v> child — some bugs drop the value element entirely.
//s:sheetData/s:row/s:c[@r='A1']/s:v
new-value-in-sharedstrings
xl/sharedStrings.xml
exist
The shared-strings table must now carry the new 'hello' entry referenced by A1.
//s:si/s:t[normalize-space()='hello']
a1-resolves-to-hello
xl/sharedStrings.xml
equal = hello
Because A1's <v>0</v> references sst[0], the first <si> must resolve to 'hello'.
/s:sst/s:si[1]/s:t
row-count-unchanged
xl/worksheets/sheet1.xml
match = ^1(\.0+)?$
Setting A1's value must not add phantom rows — exactly 1 row (the source had 1).
count(//s:sheetData/s:row)
dimension-unchanged
xl/worksheets/sheet1.xml
equal = A1:A1
dimension/@ref (adjacent attribute) must be preserved byte-for-byte.
//s:dimension/@ref

Render assertions

No render assertions declared.

Generator source

scripts/gen_modify_set_cell_value.py

#!/usr/bin/env python3
"""Generate ``fixtures/xlsx/cell-bold--set-cell-value.xlsx``.

Thin wrapper around ``scripts.mutations.xlsx_set_cell_value``. Opens
``fixtures/xlsx/cell-bold.xlsx``, sets ws['A1']='hello', saves.
Satisfies ``features/xlsx/modify-set-cell-value.json``.
"""

from __future__ import annotations

from pathlib import Path

from mutations import xlsx_set_cell_value

_REPO_ROOT = Path(__file__).resolve().parent.parent
_IN = _REPO_ROOT / "fixtures" / "xlsx" / "cell-bold.xlsx"
_OUT = _REPO_ROOT / "fixtures" / "xlsx" / "cell-bold--set-cell-value.xlsx"


def main() -> int:
    xlsx_set_cell_value(_IN, _OUT)
    print(_OUT)
    return 0


if __name__ == "__main__":
    raise SystemExit(main())

Manifest (expanded)

{
  "$schema": "../manifest.schema.json",
  "id": "xlsx/modify-set-cell-value",
  "title": "Modify: overwrite cell value on existing .xlsx",
  "format": "xlsx",
  "category": "modify-in-place",
  "summary": "Open cell-bold.xlsx (A1='Hello bold cell' with bold style s=1), assign ws['A1']='hello', save. Assert (a) A1's displayed value is 'hello' (via sharedStrings), (b) A1's @s='1' is preserved — the cell's bold formatting must not be clobbered by the value change, (c) the dimension ref and other structural attributes are unchanged.",
  "roles": [
    "authoring"
  ],
  "spec": {
    "source": "ecma-376-5-part-1",
    "clause": "18.3.1.4",
    "element": "c",
    "rnc_reference": "spec/ecma-376-5/part-1/rnc/SpreadsheetML.rnc",
    "xsd_reference": "spec/ecma-376-5/part-1/xsd/sml.xsd",
    "notes": "SpreadsheetML cells carry value and style independently: <c r=\"A1\" s=\"1\" t=\"s\"><v>0</v></c> — @s indexes styles.xml and must survive a value change. openpyxl/python-xlsx reuses the Cell object's style on reassignment."
  },
  "fixtures": {
    "machine": "xlsx/cell-bold--set-cell-value"
  },
  "modify": {
    "input_fixture": "fixtures/xlsx/cell-bold.xlsx",
    "mutation": "xlsx_set_cell_value",
    "output_fixture": "fixtures/xlsx/cell-bold--set-cell-value.xlsx"
  },
  "generator": {
    "python": "scripts/gen_modify_set_cell_value.py"
  },
  "assertions": [
    {
      "id": "a1-style-preserved",
      "part": "xl/worksheets/sheet1.xml",
      "namespaces": {
        "s": "http://schemas.openxmlformats.org/spreadsheetml/2006/main"
      },
      "xpath": "//s:sheetData/s:row/s:c[@r='A1']/@s",
      "must": "equal",
      "value": "1",
      "description": "A1's @s index (pointing at the bold cellXf entry) must be preserved — the value change must not drop the style reference."
    },
    {
      "id": "a1-is-string-typed",
      "part": "xl/worksheets/sheet1.xml",
      "namespaces": {
        "s": "http://schemas.openxmlformats.org/spreadsheetml/2006/main"
      },
      "xpath": "//s:sheetData/s:row/s:c[@r='A1']/@t",
      "must": "equal",
      "value": "s",
      "description": "A1 must remain a shared-string-typed cell."
    },
    {
      "id": "a1-references-shared-string",
      "part": "xl/worksheets/sheet1.xml",
      "namespaces": {
        "s": "http://schemas.openxmlformats.org/spreadsheetml/2006/main"
      },
      "xpath": "//s:sheetData/s:row/s:c[@r='A1']/s:v",
      "must": "exist",
      "description": "A1 must still carry a <v> child — some bugs drop the value element entirely."
    },
    {
      "id": "new-value-in-sharedstrings",
      "part": "xl/sharedStrings.xml",
      "namespaces": {
        "s": "http://schemas.openxmlformats.org/spreadsheetml/2006/main"
      },
      "xpath": "//s:si/s:t[normalize-space()='hello']",
      "must": "exist",
      "description": "The shared-strings table must now carry the new 'hello' entry referenced by A1."
    },
    {
      "id": "a1-resolves-to-hello",
      "part": "xl/sharedStrings.xml",
      "namespaces": {
        "s": "http://schemas.openxmlformats.org/spreadsheetml/2006/main"
      },
      "xpath": "/s:sst/s:si[1]/s:t",
      "must": "equal",
      "value": "hello",
      "description": "Because A1's <v>0</v> references sst[0], the first <si> must resolve to 'hello'."
    },
    {
      "id": "row-count-unchanged",
      "part": "xl/worksheets/sheet1.xml",
      "namespaces": {
        "s": "http://schemas.openxmlformats.org/spreadsheetml/2006/main"
      },
      "xpath": "count(//s:sheetData/s:row)",
      "must": "match",
      "value": "^1(\\.0+)?$",
      "description": "Setting A1's value must not add phantom rows — exactly 1 row (the source had 1)."
    },
    {
      "id": "dimension-unchanged",
      "part": "xl/worksheets/sheet1.xml",
      "namespaces": {
        "s": "http://schemas.openxmlformats.org/spreadsheetml/2006/main"
      },
      "xpath": "//s:dimension/@ref",
      "must": "equal",
      "value": "A1:A1",
      "description": "dimension/@ref (adjacent attribute) must be preserved byte-for-byte."
    }
  ]
}

Fixture

Download cell-bold--set-cell-value.xlsx (4.7 KB)

Reference preview

No rendered reference is available for this case.

Spec notes

SpreadsheetML cells carry value and style independently: <c r="A1" s="1" t="s"><v>0</v></c> — @s indexes styles.xml and must survive a value change. openpyxl/python-xlsx reuses the Cell object's style on reassignment.