styles-v1.xml, styles-v2.xml) so you can step back to any point.
How Excel's Style Indexing System Works
This concept underlies almost all styles.xml corruption, so it's worth understanding first.
styles.xml contains four indexed arrays, each a numbered list starting at 0:
fonts → [ font0, font1, font2, ... ]
fills → [ fill0, fill1, fill2, ... ]
borders → [ border0, border1, ... ]
cellXfs → [ format0, format1, format2, ... ]
Each entry in cellXfs (a cell format) points to a font, fill, and border by their index numbers:
<cellXfs>
<xf fontId="0" fillId="0" borderId="0"/> <!-- format index 0: default -->
<xf fontId="1" fillId="0" borderId="0"/> <!-- format index 1: bold text -->
<xf fontId="0" fillId="2" borderId="0"/> <!-- format index 2: yellow background -->
</cellXfs>
When a cell in sheet1.xml says s="2", it means: use format index 2 from cellXfs.
cell s="2" → cellXfs[2] → fontId="0", fillId="2", borderId="0"
↓ ↓ ↓
fonts[0] fills[2] borders[0]
One bad index number anywhere in this chain corrupts formatting for every cell that references it.
What a Healthy styles.xml Looks Like
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
<fonts count="2">
<font><sz val="11"/><name val="Calibri"/></font> <!-- index 0 -->
<font><b/><sz val="11"/><name val="Calibri"/></font> <!-- index 1: bold -->
</fonts>
<fills count="2">
<fill><patternFill patternType="none"/></fill> <!-- index 0: REQUIRED -->
<fill><patternFill patternType="gray125"/></fill> <!-- index 1: REQUIRED -->
</fills>
<borders count="1">
<border><left/><right/><top/><bottom/><diagonal/></border> <!-- index 0 -->
</borders>
<cellXfs count="2">
<xf numFmtId="0" fontId="0" fillId="0" borderId="0" xfId="0"/> <!-- index 0 -->
<xf numFmtId="0" fontId="1" fillId="0" borderId="0" xfId="0"
applyFont="1"/> <!-- index 1 -->
</cellXfs>
</styleSheet>
Out-of-Range Style Index in a Cell
A cell references a style index that does not exist in cellXfs.
Repaired Records: Cell information from /xl/worksheets/sheet1.xml part
<!-- styles.xml: cellXfs has count="2", so valid indexes are 0 and 1 -->
<cellXfs count="2">
<xf .../> <!-- index 0 -->
<xf .../> <!-- index 1 -->
</cellXfs>
<!-- sheet1.xml: cell uses s="9" which does not exist -->
<c r="B2" s="9"><v>12500</v></c> <!-- ← CORRUPT: index 9 does not exist -->
Fix: Change s="9" to a valid index. s="0" always works as it is the default style.
<!-- Fixed -->
<c r="B2" s="0"><v>12500</v></c>
count Attribute Mismatch
Each section (<fonts>, <fills>, <borders>, <cellXfs>) has a count attribute. If the count doesn't match the actual number of child elements, Excel will error or silently repair.
<!-- CORRUPT: count says 5 but only 2 font entries exist -->
<fonts count="5"> <!-- ← wrong count -->
<font>...</font> <!-- index 0 -->
<font>...</font> <!-- index 1 -->
<!-- Excel expects 3 more entries that aren't here -->
</fonts>
Fix: Count the actual child elements and update the count attribute to match.
<!-- Fixed -->
<fonts count="2">
<font>...</font>
<font>...</font>
</fonts>
Missing Reserved Fill Entries
The spec requires index 0 to be a none fill and index 1 to be gray125. Many programmatic XLSX writers skip these and start with their own fills at index 0. This shifts all fill indexes by 2, so every cell with a background color displays the wrong one — or errors entirely.
<!-- CORRUPT: missing the two required reserved fills -->
<fills count="1">
<fill>
<patternFill patternType="solid">
<fgColor rgb="FFFFFF00"/> <!-- yellow — but it's at index 0, not 2 -->
</patternFill>
</fill>
</fills>
<!-- Fixed: reserved entries first, then custom fills -->
<fills count="3">
<fill><patternFill patternType="none"/></fill> <!-- index 0: REQUIRED -->
<fill><patternFill patternType="gray125"/></fill> <!-- index 1: REQUIRED -->
<fill>
<patternFill patternType="solid">
<fgColor rgb="FFFFFF00"/>
</patternFill>
</fill> <!-- index 2: yellow -->
</fills>
fillId references in cellXfs must be incremented by 2 to point to the right fill entries.
Bloated styles.xml
Less of a hard corruption and more of a progressive problem. Workbooks used heavily over months or years — especially ones where many users paste data from other sources — accumulate thousands of duplicate style entries. A styles.xml that should be 20KB becomes 2MB.
What you will see:
- Extremely slow saves
- "Too many different cell formats" error
- Occasional "Excel found unreadable content" on open
xl/
styles.xml 2,847 KB ← should be under 100KB for most workbooks
Fix: Copy all data to a new workbook using Paste Special > Values. This strips all direct formatting and resets styles.xml to a minimal clean state. You will need to reapply any intentional formatting afterward.
Checklist: How to Check styles.xml in Your File
- Rename your XLSX to .zip, navigate to the
xlfolder, copystyles.xmlto your Desktop - Open in VS Code (with the Red Hat XML extension) and press Shift+Alt+F to format
- Check that each section's
countattribute matches the number of child elements inside it - Confirm the first two
<fill>entries arepatternType="none"andpatternType="gray125" - Note the highest valid
cellXfsindex (countminus 1) - Open
sheet1.xmland confirm no cell has ansattribute higher than that number - Check the file size in Windows Explorer — anything over 500KB is worth investigating