Conversation
Parse OOXML <cellStyles> elements and emit a flat namedStyles array on the workbook. Styles that inherit from a non-default named style get a parentStyle property with the style name (e.g. "Percent", "Heading 1").
… NamedStyle Only emit namedStyles when there are custom named styles beyond the default Normal — this keeps output backward compatible for workbooks with no custom named styles. Also rename CellStyle type to NamedStyle to match the updated @jsfkit/types.
borgar
left a comment
There was a problem hiding this comment.
Since a renderer may be looking up styles per-cell, per-render, performance can matter here. I think it would be better to use a record for the named styles:
st1 = { parentStyle: 'Normal', fontSize: 16 };
st2 = wb.namedStyles[st1.parentStyle];
This is a lot faster and easier than having to do:
st1 = { parentStyle: 'Normal', fontSize: 16 };
st2 = wb.namedStyles.find(item => item.name === st1.parentStyle);
A renderer could obviously maintain its own internal map/record but if this is a record already, the lookups can happen instantly and there is less implementation demand placed on the client.
Alternatively, we could use numerical indexes into the list:
st1 = { parentStyle: 0, fontSize: 16 };
st2 = wb.namedStyles[st1.parentStyle];
This is the same as how cells index into the style list so it is a familiar pattern, but its less nice for humans, and we do have the names here. The names map also has the advantage of ensuring that names are unique.
So, the changes I suggest:
- Rename the
parentStyleproperty toextends. - Use an object for
namedStyles, types asRecord<string, NamedStyle>.
What that would look like:
namedStyles: {
Normal: { name: 'Normal', presetId: 0, fontScheme: 'minor', fontSize: 12 },
Percent: { name: 'Percent', builtinId: 5, fontScheme: 'minor', fontSize: 12, numberFormat: '0%' },
},
styles: [
{ fontScheme: 'minor', fontSize: 12 },
{ fontScheme: 'minor', fontSize: 12, numberFormat: '0.00E+00' },
{ extends: 'Percent', fontScheme: 'minor', fontSize: 12, numberFormat: '0.0%' },
],I realize we're then triplicating the name (in Style, NamedStyle, and in the map, but it's important to include it because otherwise the two style types are hard to tell apart.
…e to extendsStyle - namedStyles is now Record<string, NamedStyle> instead of NamedStyle[] - Rename parentStyle to extendsStyle to avoid reserved keyword conflict - Rename CellStyleEntry to NamedStyleEntry for consistency
Summary
<cellStyles>elements and emit a flatnamedStylesarray on the workbookparentStyleproperty referencing the style by namestylewrapper)namedStylesis only emitted when there are custom named styles beyond the default "Normal"Example JSF output
{ "namedStyles": [ { "builtinId": 0, "name": "Normal", "fontScheme": "minor", "fontSize": 12 }, { "builtinId": 5, "name": "Percent", "fontScheme": "minor", "fontSize": 12, "numberFormat": "0%" } ], "styles": [ { "fontScheme": "minor", "fontSize": 12 }, { "fontScheme": "minor", "fontSize": 12, "numberFormat": "0.00E+00" }, { "parentStyle": "Percent", "fontScheme": "minor", "fontSize": 12, "numberFormat": "0.0%" } ] }namedStylescontains the named style definitions (flat: style properties are at the top level alongsidenameandbuiltinId)parentStyleon a style references a named style by name (omitted when inheriting from "Normal", the default)namedStyles(no fixture changes for existing tests)