to-spreadsheet
Version:
npm package to create spreadsheet in node environment and in browser
175 lines (174 loc) • 7.93 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.generateStyleXml = void 0;
const __1 = require("..");
const generateBorderXml = (border) => {
const getColorXml = (color) => color ? `<color rgb="${color.replace('#', 'FF')}" />` : '';
const getBorderSideXml = (side, color) => {
if (!side || side === __1.BorderStyle.none) {
return '<left />';
}
return `<left style="${side}">${getColorXml(color)}</left>`;
};
const leftXml = !border.left || border.left === __1.BorderStyle.none
? '<left />'
: `<left style="${border.left}">${getColorXml(border.color)}</left>`;
const rightXml = !border.right || border.right === __1.BorderStyle.none
? '<right />'
: `<right style="${border.right}">${getColorXml(border.color)}</right>`;
const topXml = !border.top || border.top === __1.BorderStyle.none
? '<top />'
: `<top style="${border.top}">${getColorXml(border.color)}</top>`;
const bottomXml = !border.bottom || border.bottom === __1.BorderStyle.none
? '<bottom />'
: `<bottom style="${border.bottom}">${getColorXml(border.color)}</bottom>`;
return `
<border>
${leftXml}
${rightXml}
${topXml}
${bottomXml}
<diagonal />
</border>`;
};
const generateFontXml = (color) => {
const colorXml = color
? `<color rgb="${color.replace('#', 'FF')}" />`
: '<color theme="1" />';
return `
<font>
<sz val="11" />
${colorXml}
<name val="Calibri" />
<family val="2" />
<scheme val="minor" />
</font>`;
};
const generateFillXml = (color) => {
if (!color) {
return `
<fill>
<patternFill patternType="none" />
</fill>`;
}
return `
<fill>
<patternFill patternType="solid">
<fgColor rgb="${color.replace('#', 'FF')}" />
<bgColor indexed="64" />
</patternFill>
</fill>`;
};
const generateAlignmentXml = (style) => {
const hasAlignment = style.horizontalAlignment || style.verticalAlignment;
if (!hasAlignment) {
return '';
}
let alignmentAttrs = '';
if (style.horizontalAlignment) {
alignmentAttrs += ` horizontal="${style.horizontalAlignment}"`;
}
if (style.verticalAlignment) {
alignmentAttrs += ` vertical="${style.verticalAlignment}"`;
}
return `<alignment${alignmentAttrs} />`;
};
const generateStyleXml = (styleMap, hasDateCells = false) => {
const styles = Array.from(styleMap.values());
const styleCount = styles.length;
const uniqueBorders = new Map();
const uniqueFonts = new Map();
const uniqueFills = new Map();
uniqueBorders.set("none", {});
uniqueFonts.set("default", "");
uniqueFills.set("none", "");
uniqueFills.set("gray125", "");
styles.forEach(style => {
if (style.border) {
uniqueBorders.set(JSON.stringify(style.border), style.border);
}
if (style.foregroundColor) {
uniqueFonts.set(style.foregroundColor, style.foregroundColor);
}
if (style.backgroundColor) {
uniqueFills.set(style.backgroundColor, style.backgroundColor);
}
});
const borderArray = Array.from(uniqueBorders.values());
const fontArray = Array.from(uniqueFonts.values());
const fillArray = Array.from(uniqueFills.values());
const bordersXml = borderArray.map(border => generateBorderXml(border)).join('');
const fontsXml = fontArray.map(color => generateFontXml(color || undefined)).join('');
const fillsXml = fillArray.map(color => generateFillXml(color || undefined)).join('');
const numFmtsXml = hasDateCells
? `<numFmts count="1">
<numFmt numFmtId="164" formatCode="mm/dd/yyyy" />
</numFmts>`
: '';
let cellXfsXml = '';
let cellXfsCount = styleCount;
if (hasDateCells) {
cellXfsXml += styles.map((style, index) => {
const borderIndex = Array.from(uniqueBorders.keys()).indexOf(JSON.stringify(style.border || {}));
const fontIndex = Array.from(uniqueFonts.keys()).indexOf(style.foregroundColor || "default");
const fillIndex = Array.from(uniqueFills.keys()).indexOf(style.backgroundColor || "none");
const alignmentXml = generateAlignmentXml(style);
const applyAlignment = style.horizontalAlignment || style.verticalAlignment ? ' applyAlignment="1"' : '';
return `<xf numFmtId="0" fontId="${fontIndex}" fillId="${fillIndex}" borderId="${borderIndex}" xfId="0"${applyAlignment}>${alignmentXml}</xf>`;
}).join('\n ');
cellXfsXml += '\n ';
cellXfsXml += styles.map((style, index) => {
const borderIndex = Array.from(uniqueBorders.keys()).indexOf(JSON.stringify(style.border || {}));
const fontIndex = Array.from(uniqueFonts.keys()).indexOf(style.foregroundColor || "default");
const fillIndex = Array.from(uniqueFills.keys()).indexOf(style.backgroundColor || "none");
const alignmentXml = generateAlignmentXml(style);
const applyAlignment = style.horizontalAlignment || style.verticalAlignment ? ' applyAlignment="1"' : '';
return `<xf numFmtId="164" fontId="${fontIndex}" fillId="${fillIndex}" borderId="${borderIndex}" xfId="0"${applyAlignment}>${alignmentXml}</xf>`;
}).join('\n ');
cellXfsCount = styleCount * 2;
}
else {
cellXfsXml = styles.map((style, index) => {
const borderIndex = Array.from(uniqueBorders.keys()).indexOf(JSON.stringify(style.border || {}));
const fontIndex = Array.from(uniqueFonts.keys()).indexOf(style.foregroundColor || "default");
const fillIndex = Array.from(uniqueFills.keys()).indexOf(style.backgroundColor || "none");
const alignmentXml = generateAlignmentXml(style);
const applyAlignment = style.horizontalAlignment || style.verticalAlignment ? ' applyAlignment="1"' : '';
return `<xf numFmtId="0" fontId="${fontIndex}" fillId="${fillIndex}" borderId="${borderIndex}" xfId="0"${applyAlignment}>${alignmentXml}</xf>`;
}).join('\n ');
}
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="x14ac x16r2 xr" xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac" xmlns:x16r2="http://schemas.microsoft.com/office/spreadsheetml/2015/02/main" xmlns:xr="http://schemas.microsoft.com/office/spreadsheetml/2014/revision">
${numFmtsXml}
<fonts count="${fontArray.length}" x14ac:knownFonts="1">
${fontsXml}
</fonts>
<fills count="${fillArray.length}">
${fillsXml}
</fills>
<borders count="${borderArray.length}">
${bordersXml}
</borders>
<cellStyleXfs count="1">
<xf numFmtId="0" fontId="0" fillId="0" borderId="0" />
</cellStyleXfs>
<cellXfs count="${cellXfsCount}">
${cellXfsXml}
</cellXfs>
<cellStyles count="1">
<cellStyle name="Normal" xfId="0" builtinId="0" />
</cellStyles>
<dxfs count="0" />
<tableStyles count="0" defaultTableStyle="TableStyleMedium2" defaultPivotStyle="PivotStyleLight16" />
<extLst>
<ext uri="{EB79DEF2-80B8-43e5-95BD-54CBDDF9020C}" xmlns:x14="http://schemas.microsoft.com/office/spreadsheetml/2009/9/main">
<slicerStyles defaultSlicerStyle="SlicerStyleLight1" />
</ext>
<ext uri="{9260A510-F301-46a8-8635-F512D64BE5F5}" xmlns:x15="http://schemas.microsoft.com/office/spreadsheetml/2010/11/main">
<timelineStyles defaultTimelineStyle="TimeSlicerStyleLight1" />
</ext>
</extLst>
</styleSheet>
`;
};
exports.generateStyleXml = generateStyleXml;