Read borders and alignments

This commit is contained in:
Pieter Sheth-Voss 2015-04-15 15:07:45 -04:00
parent 114f257ce4
commit 5f9576a6d2
12 changed files with 804 additions and 314 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

2
.gitignore vendored

@ -6,3 +6,5 @@ tmp
*.xlsx
*.xlsm
*.xlsb
lab/
.idea/

@ -1,83 +1,122 @@
/* 18.8.21 fills CT_Fills */
function parse_fills(t, opts) {
styles.Fills = [];
var fill = {};
t[0].match(tagregex).forEach(function(x) {
var y = parsexmltag(x);
switch(y[0]) {
case '<fills': case '<fills>': case '</fills>': break;
styles.Fills = [];
var fill = {};
t[0].match(tagregex).forEach(function (x) {
var y = parsexmltag(x);
switch (y[0]) {
case '<fills':
case '<fills>':
case '</fills>':
break;
/* 18.8.20 fill CT_Fill */
case '<fill>': break;
case '</fill>': styles.Fills.push(fill); fill = {}; break;
/* 18.8.20 fill CT_Fill */
case '<fill>':
break;
case '</fill>':
styles.Fills.push(fill);
fill = {};
break;
/* 18.8.32 patternFill CT_PatternFill */
case '<patternFill':
if(y.patternType) fill.patternType = y.patternType;
break;
case '<patternFill/>': case '</patternFill>': break;
/* 18.8.32 patternFill CT_PatternFill */
case '<patternFill':
if (y.patternType) fill.patternType = y.patternType;
break;
case '<patternFill/>':
case '</patternFill>':
break;
/* 18.8.3 bgColor CT_Color */
case '<bgColor':
if(!fill.bgColor) fill.bgColor = {};
if(y.indexed) fill.bgColor.indexed = parseInt(y.indexed, 10);
if(y.theme) fill.bgColor.theme = parseInt(y.theme, 10);
if(y.tint) fill.bgColor.tint = parseFloat(y.tint);
/* 18.8.3 bgColor CT_Color */
case '<bgColor':
if (!fill.bgColor) fill.bgColor = {};
if (y.indexed) fill.bgColor.indexed = parseInt(y.indexed, 10);
if (y.theme) fill.bgColor.theme = parseInt(y.theme, 10);
if (y.tint) fill.bgColor.tint = parseFloat(y.tint);
/* Excel uses ARGB strings */
if(y.rgb) fill.bgColor.rgb = y.rgb;//.substring(y.rgb.length - 6);
break;
case '<bgColor/>': case '</bgColor>': break;
if (y.rgb) fill.bgColor.rgb = y.rgb;//.substring(y.rgb.length - 6);
break;
case '<bgColor/>':
case '</bgColor>':
break;
/* 18.8.19 fgColor CT_Color */
case '<fgColor':
if(!fill.fgColor) fill.fgColor = {};
if(y.theme) fill.fgColor.theme = parseInt(y.theme, 10);
if(y.tint) fill.fgColor.tint = parseFloat(y.tint);
/* Excel uses ARGB strings */
if(y.rgb) fill.fgColor.rgb = y.rgb;//.substring(y.rgb.length - 6);
break;
case '<fgColor/>': case '</fgColor>': break;
/* 18.8.19 fgColor CT_Color */
case '<fgColor':
if (!fill.fgColor) fill.fgColor = {};
if (y.theme) fill.fgColor.theme = parseInt(y.theme, 10);
if (y.tint) fill.fgColor.tint = parseFloat(y.tint);
/* Excel uses ARGB strings */
if (y.rgb) fill.fgColor.rgb = y.rgb;//.substring(y.rgb.length - 6);
break;
case '<fgColor/>':
case '</fgColor>':
break;
default: if(opts.WTF) throw 'unrecognized ' + y[0] + ' in fills';
}
});
default:
if (opts.WTF) throw 'unrecognized ' + y[0] + ' in fills';
}
});
}
function parse_fonts(t, opts) {
styles.Fonts = [];
var font = {};
t[0].match(tagregex).forEach(function(x) {
t[0].match(tagregex).forEach(function (x) {
var y = parsexmltag(x);
switch(y[0]) {
switch (y[0]) {
case '<fonts': case '<fonts>': case '</fonts>': break;
case '<fonts':
case '<fonts>':
case '</fonts>':
break;
case '<font':
break;
case '</font>': styles.Fonts.push(font); ;font = {}; break;
case '</font>':
styles.Fonts.push(font);
;
font = {};
break;
case '<name':
if(y.val) font.name = y.val;
if (y.val) font.name = y.val;
break;
case '<name/>':
case '</name>':
break;
case '<name/>': case '</name>': break;
case '<b/>': font.bold = true;break;
case '<u/>': font.underline = true;break;
case '<i/>': font.italic = true;break;
case '<strike/>': font.strike = true;break;
case '<outline/>': font.outline = true;break;
case '<shadow/>': font.shadow = true;break;
case '<b/>':
font.bold = true;
break;
case '<u/>':
font.underline = true;
break;
case '<i/>':
font.italic = true;
break;
case '<strike/>':
font.strike = true;
break;
case '<outline/>':
font.outline = true;
break;
case '<shadow/>':
font.shadow = true;
break;
case '<sz':
if(y.val) font.sz = y.val;
if (y.val) font.sz = y.val;
break;
case '<sz/>':
case '</sz>':
break;
case '<sz/>': case '</sz>': break;
case '<vertAlign':
if(y.val) font.vertAlign = y.val;
if (y.val) font.vertAlign = y.val;
break;
case '<vertAlign/>':
case '</vertAlign>':
break;
case '<vertAlign/>': case '</vertAlign>': break;
case '<color':
@ -86,32 +125,77 @@ function parse_fonts(t, opts) {
if (y.tint) font.color.tint = y.tint;
if (y.rgb) font.color.rgb = y.rgb;
break;
case '<color/>':case '</color>': break;
case '<color/>':
case '</color>':
break;
}
});
}
function parse_borders(t, opts) {
styles.Borders = [];
var border = {};
t[0].match(tagregex).forEach(function(x) {
var border = {}, sub_border = {};
t[0].match(tagregex).forEach(function (x) {
var y = parsexmltag(x);
switch(y[0]) {
case '<borders': case '<borders>': case '</borders>': break;
case '<border>': break;
switch (y[0]) {
case '<borders':
case '<borders>':
case '</borders>':
break;
case '<border':
case '<border>':
border = {};
if (y.diagonalUp) { border.diagonalUp = y.diagonalUp; }
if (y.diagonalDown) { border.diagonalDown = y.diagonalDown; }
styles.Borders.push(border);
break;
break;
case '</border>':
styles.Fonts.push(border);
border = {}; break;
break;
case '<left':
sub_border = border.left = {};
if (y.style) {
sub_border.style = y.style;
}
break;
case '<right':
sub_border = border.right = {};
if (y.style) {
sub_border.style = y.style;
}
break;
case '<top':
sub_border = border.top = {};
if (y.style) {
sub_border.style = y.style;
}
break;
case '<bottom':
sub_border = border.bottom = {};
if (y.style) {
sub_border.style = y.style;
}
break;
case '<diagonal':
sub_border = border.diagonal = {};
if (y.style) {
sub_border.style = y.style;
}
break;
case '<color':
if(y.style) border.style = y.style;
sub_border.color = {};
if (y.theme) sub_border.color.theme = y.theme;
if (y.tint) sub_border.color.tint = y.tint;
if (y.rgb) sub_border.color.rgb = y.rgb;
break;
case '<name/>': case '</name>': break;
case '<sz':
if(y.val) font.sz = y.val;
case '<name/>':
case '</name>':
break;
default:
break;
case '<sz/>': case '</sz>': break;
}
});
@ -119,111 +203,153 @@ function parse_borders(t, opts) {
/* 18.8.31 numFmts CT_NumFmts */
function parse_numFmts(t, opts) {
styles.NumberFmt = [];
var k = keys(SSF._table);
for(var i=0; i < k.length; ++i) styles.NumberFmt[k[i]] = SSF._table[k[i]];
var m = t[0].match(tagregex);
for(i=0; i < m.length; ++i) {
var y = parsexmltag(m[i]);
switch(y[0]) {
case '<numFmts': case '</numFmts>': case '<numFmts/>': case '<numFmts>': break;
case '<numFmt': {
var f=unescapexml(utf8read(y.formatCode)), j=parseInt(y.numFmtId,10);
styles.NumberFmt[j] = f; if(j>0) SSF.load(f,j);
} break;
default: if(opts.WTF) throw 'unrecognized ' + y[0] + ' in numFmts';
}
}
styles.NumberFmt = [];
var k = keys(SSF._table);
for (var i = 0; i < k.length; ++i) styles.NumberFmt[k[i]] = SSF._table[k[i]];
var m = t[0].match(tagregex);
for (i = 0; i < m.length; ++i) {
var y = parsexmltag(m[i]);
switch (y[0]) {
case '<numFmts':
case '</numFmts>':
case '<numFmts/>':
case '<numFmts>':
break;
case '<numFmt':
{
var f = unescapexml(utf8read(y.formatCode)), j = parseInt(y.numFmtId, 10);
styles.NumberFmt[j] = f;
if (j > 0) SSF.load(f, j);
}
break;
default:
if (opts.WTF) throw 'unrecognized ' + y[0] + ' in numFmts';
}
}
}
function write_numFmts(NF, opts) {
var o = ["<numFmts>"];
[[5,8],[23,26],[41,44],[63,66],[164,392]].forEach(function(r) {
for(var i = r[0]; i <= r[1]; ++i) if(NF[i] !== undefined) o[o.length] = (writextag('numFmt',null,{numFmtId:i,formatCode:escapexml(NF[i])}));
});
if(o.length === 1) return "";
o[o.length] = ("</numFmts>");
o[0] = writextag('numFmts', null, { count:o.length-2 }).replace("/>", ">");
return o.join("");
var o = ["<numFmts>"];
[
[5, 8],
[23, 26],
[41, 44],
[63, 66],
[164, 392]
].forEach(function (r) {
for (var i = r[0]; i <= r[1]; ++i) if (NF[i] !== undefined) o[o.length] = (writextag('numFmt', null, {numFmtId: i, formatCode: escapexml(NF[i])}));
});
if (o.length === 1) return "";
o[o.length] = ("</numFmts>");
o[0] = writextag('numFmts', null, { count: o.length - 2 }).replace("/>", ">");
return o.join("");
}
/* 18.8.10 cellXfs CT_CellXfs */
function parse_cellXfs(t, opts) {
styles.CellXf = [];
t[0].match(tagregex).forEach(function(x) {
var y = parsexmltag(x);
switch(y[0]) {
case '<cellXfs': case '<cellXfs>': case '<cellXfs/>': case '</cellXfs>': break;
styles.CellXf = [];
var xf;
t[0].match(tagregex).forEach(function (x) {
var y = parsexmltag(x);
switch (y[0]) {
case '<cellXfs':
case '<cellXfs>':
case '<cellXfs/>':
case '</cellXfs>':
break;
/* 18.8.45 xf CT_Xf */
case '<xf': delete y[0];
if(y.numFmtId) y.numFmtId = parseInt(y.numFmtId, 10);
if(y.fillId) y.fillId = parseInt(y.fillId, 10);
styles.CellXf.push(y); break;
case '</xf>': break;
/* 18.8.45 xf CT_Xf */
case '<xf':
xf = y;
delete xf[0];
delete y[0];
if (xf.numFmtId) xf.numFmtId = parseInt(xf.numFmtId, 10);
if (xf.fillId) xf.fillId = parseInt(xf.fillId, 10);
styles.CellXf.push(xf);
break;
case '</xf>':
break;
/* 18.8.1 alignment CT_CellAlignment */
case '<alignment': case '<alignment/>': break;
/* 18.8.1 alignment CT_CellAlignment */
case '<alignment':
case '<alignment/>':
var alignment = {}
if (y.vertical) { alignment.vertical = y.vertical;}
if (y.horizontal) { alignment.horizontal = y.horizontal;}
if (y.indent) { alignment.indent = y.indent; }
if (y.wrapText) { alignment.wrapText = y.wrapText; }
xf.alignment = alignment;
/* 18.8.33 protection CT_CellProtection */
case '<protection': case '</protection>': case '<protection/>': break;
break;
case '<extLst': case '</extLst>': break;
case '<ext': break;
default: if(opts.WTF) throw 'unrecognized ' + y[0] + ' in cellXfs';
}
});
/* 18.8.33 protection CT_CellProtection */
case '<protection':
case '</protection>':
case '<protection/>':
break;
case '<extLst':
case '</extLst>':
break;
case '<ext':
break;
default:
if (opts.WTF) throw 'unrecognized ' + y[0] + ' in cellXfs';
}
});
}
function write_cellXfs(cellXfs) {
var o = [];
o[o.length] = (writextag('cellXfs',null));
cellXfs.forEach(function(c) { o[o.length] = (writextag('xf', null, c)); });
o[o.length] = ("</cellXfs>");
if(o.length === 2) return "";
o[0] = writextag('cellXfs',null, {count:o.length-2}).replace("/>",">");
return o.join("");
var o = [];
o[o.length] = (writextag('cellXfs', null));
cellXfs.forEach(function (c) {
o[o.length] = (writextag('xf', null, c));
});
o[o.length] = ("</cellXfs>");
if (o.length === 2) return "";
o[0] = writextag('cellXfs', null, {count: o.length - 2}).replace("/>", ">");
return o.join("");
}
/* 18.8 Styles CT_Stylesheet*/
var parse_sty_xml= (function make_pstyx() {
var numFmtRegex = /<numFmts([^>]*)>.*<\/numFmts>/;
var cellXfRegex = /<cellXfs([^>]*)>.*<\/cellXfs>/;
var fillsRegex = /<fills([^>]*)>.*<\/fills>/;
var bordersRegex = /<borders([^>]*)>.*<\/borders>/;
var parse_sty_xml = (function make_pstyx() {
var numFmtRegex = /<numFmts([^>]*)>.*<\/numFmts>/;
var cellXfRegex = /<cellXfs([^>]*)>.*<\/cellXfs>/;
var fillsRegex = /<fills([^>]*)>.*<\/fills>/;
var bordersRegex = /<borders([^>]*)>.*<\/borders>/;
return function parse_sty_xml(data, opts) {
/* 18.8.39 styleSheet CT_Stylesheet */
var t;
return function parse_sty_xml(data, opts) {
/* 18.8.39 styleSheet CT_Stylesheet */
var t;
/* numFmts CT_NumFmts ? */
if((t=data.match(numFmtRegex))) parse_numFmts(t, opts);
/* numFmts CT_NumFmts ? */
if ((t = data.match(numFmtRegex))) parse_numFmts(t, opts);
/* fonts CT_Fonts ? */
if((t=data.match(/<fonts([^>]*)>.*<\/fonts>/))) parse_fonts(t, opts)
/* fonts CT_Fonts ? */
if ((t = data.match(/<fonts([^>]*)>.*<\/fonts>/))) parse_fonts(t, opts)
/* fills CT_Fills */
if((t=data.match(fillsRegex))) parse_fills(t, opts);
/* fills CT_Fills */
if ((t = data.match(fillsRegex))) parse_fills(t, opts);
/* borders CT_Borders ? */
// if ((t=data.match(bordersRegex))) parse_borders(t, opts);
/* cellStyleXfs CT_CellStyleXfs ? */
/* borders CT_Borders ? */
if ((t = data.match(bordersRegex))) parse_borders(t, opts);
/* cellStyleXfs CT_CellStyleXfs ? */
/* cellXfs CT_CellXfs ? */
if((t=data.match(cellXfRegex))) parse_cellXfs(t, opts);
/* cellXfs CT_CellXfs ? */
if ((t = data.match(cellXfRegex))) parse_cellXfs(t, opts);
/* dxfs CT_Dxfs ? */
/* tableStyles CT_TableStyles ? */
/* colors CT_Colors ? */
/* extLst CT_ExtensionList ? */
/* dxfs CT_Dxfs ? */
/* tableStyles CT_TableStyles ? */
/* colors CT_Colors ? */
/* extLst CT_ExtensionList ? */
return styles;
};
return styles;
};
})();
var STYLES_XML_ROOT = writextag('styleSheet', null, {
'xmlns': XMLNS.main[0],
'xmlns:vt': XMLNS.vt
'xmlns': XMLNS.main[0],
'xmlns:vt': XMLNS.vt
});
RELS.STY = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles";
@ -234,17 +360,20 @@ function write_sty_xml(wb, opts) {
return style_builder.toXml();
}
var o = [XML_HEADER, STYLES_XML_ROOT], w;
if((w = write_numFmts(wb.SSF)) != null) o[o.length] = w;
o[o.length] = ('<fonts count="1"><font><sz val="12"/><color theme="1"/><name val="Calibri"/><family val="2"/><scheme val="minor"/></font></fonts>');
o[o.length] = ('<fills count="2"><fill><patternFill patternType="none"/></fill><fill><patternFill patternType="gray125"/></fill></fills>');
o[o.length] = ('<borders count="1"><border><left/><right/><top/><bottom/><diagonal/></border></borders>');
o[o.length] = ('<cellStyleXfs count="1"><xf numFmtId="0" fontId="0" fillId="0" borderId="0"/></cellStyleXfs>');
if((w = write_cellXfs(opts.cellXfs))) o[o.length] = (w);
o[o.length] = ('<cellStyles count="1"><cellStyle name="Normal" xfId="0" builtinId="0"/></cellStyles>');
o[o.length] = ('<dxfs count="0"/>');
o[o.length] = ('<tableStyles count="0" defaultTableStyle="TableStyleMedium9" defaultPivotStyle="PivotStyleMedium4"/>');
var o = [XML_HEADER, STYLES_XML_ROOT], w;
if ((w = write_numFmts(wb.SSF)) != null) o[o.length] = w;
o[o.length] = ('<fonts count="1"><font><sz val="12"/><color theme="1"/><name val="Calibri"/><family val="2"/><scheme val="minor"/></font></fonts>');
o[o.length] = ('<fills count="2"><fill><patternFill patternType="none"/></fill><fill><patternFill patternType="gray125"/></fill></fills>');
o[o.length] = ('<borders count="1"><border><left/><right/><top/><bottom/><diagonal/></border></borders>');
o[o.length] = ('<cellStyleXfs count="1"><xf numFmtId="0" fontId="0" fillId="0" borderId="0"/></cellStyleXfs>');
if ((w = write_cellXfs(opts.cellXfs))) o[o.length] = (w);
o[o.length] = ('<cellStyles count="1"><cellStyle name="Normal" xfId="0" builtinId="0"/></cellStyles>');
o[o.length] = ('<dxfs count="0"/>');
o[o.length] = ('<tableStyles count="0" defaultTableStyle="TableStyleMedium9" defaultPivotStyle="PivotStyleMedium4"/>');
if(o.length>2){ o[o.length] = ('</styleSheet>'); o[1]=o[1].replace("/>",">"); }
return o.join("");
if (o.length > 2) {
o[o.length] = ('</styleSheet>');
o[1] = o[1].replace("/>", ">");
}
return o.join("");
}

@ -34,6 +34,7 @@ function get_cell_style(styles, cell, opts) {
function get_cell_style_csf(cellXf) {
if (cellXf) {
var s = {}
if (typeof cellXf.numFmtId != undefined) {
@ -48,8 +49,12 @@ function get_cell_style_csf(cellXf) {
s.font = styles.Fonts[cellXf.fontId];
}
if (cellXf.borderId) {
// s.border = styles.Borders[cellXf.borderId];
s.border = styles.Borders[cellXf.borderId];
}
if (cellXf.applyAlignment==1) {
s.alignment = cellXf.alignment;
}
return s;
}

150
example.js Normal file

@ -0,0 +1,150 @@
var XLSX = require('./');
var Workbook = require('../workbook');
///http://daveaddey.com/?p=40
function JSDateToExcelDate(inDate) {
return 25569.0 + ((inDate.getTime() - (inDate.getTimezoneOffset() * 60 * 1000)) / (1000 * 60 * 60 * 24));
}
var workbook = new Workbook(XLSX)
.addRowsToSheet("Main", [
[
{
v: "This is a submerged cell",
s:{
border: {
left: {style: 'thick', color: {auto: 1}},
top: {style: 'thick', color: {auto: 1}},
bottom: {style: 'thick', color: {auto: 1}}
}
}
},
{
v: "Pirate ship",
s:{
border: {
top: {style: 'thick', color: {auto: 1}},
bottom: {style: 'thick', color: {auto: 1}}
}
}
},
{
v: "Sunken treasure",
s:{
border: {
right: {style: 'thick', color: {auto: 1}},
top: {style: 'thick', color: {auto: 1}},
bottom: {style: 'thick', color: {auto: 1}}
}
}
}],
[
{"v": "Blank"},
{"v": "Red", "s": {fill: { fgColor: { rgb: "FFFF0000"}}}},
{"v": "Green", "s": {fill: { fgColor: { rgb: "FF00FF00"}}}},
{"v": "Blue", "s": {fill: { fgColor: { rgb: "FF0000FF"}}}}
],
[
{"v": "Default"},
{"v": "Arial", "s": {font: {name: "Arial", sz: 24, color: {theme: "5"}}}},
{"v": "Times New Roman", "s": {font: {name: "Times New Roman", sz: 16, color: {rgb: "FF2222FF"}}}},
{"v": "Courier New", "s": {font: {name: "Courier New", sz: 14}}}
],
[
0.618033989,
{"v": 0.618033989},
{"v": 0.618033989, "t": "n"},
{"v": 0.618033989, "t": "n", "s": { "numFmt": "0.00%"}},
{"v": 0.618033989, "t": "n", "s": { "numFmt": "0.00%"}, fill: { fgColor: { rgb: "FFFFCC00"}}}
],
[
{"v": 0.618033989, "t": "n", "s": { "numFmt": "0%"}},
{"v": 0.618033989, "t": "n", "s": { "numFmt": "0.0%"}},
{"v": 0.618033989, "t": "n", "s": { "numFmt": "0.00%"}},
{"v": 0.618033989, "t": "n", "s": { "numFmt": "0.000%"}},
{"v": 0.618033989, "t": "n", "s": { "numFmt": "0.0000%"}},
{"v": 0, "t": "n", "s": { numFmt: "0.00%;\\(0.00%\\);\\-;@"}, fill: { fgColor: { rgb: "FFFFCC00"}}}
],
[
{v: (new Date()).toLocaleString()},
{v: JSDateToExcelDate(new Date()), t: 'd'},
{v: JSDateToExcelDate(new Date()), s: {numFmt: 'd-mmm-yy'}}
]
,
[
{v: "left", "s": { alignment: {horizontal: "left"}}},
{v: "left", "s": { alignment: {horizontal: "center"}}},
{v: "left", "s": { alignment: {horizontal: "right"}}}
],[
{v: "vertical", "s": { alignment: {vertical: "top"}}},
{v: "vertical", "s": { alignment: {vertical: "center"}}},
{v: "vertical", "s": { alignment: {vertical: "bottom"}}}
],[
{v: "indent", "s": { alignment: {indent: "1"}}},
{v: "indent", "s": { alignment: {indent: "2"}}},
{v: "indent", "s": { alignment: {indent: "3"}}}
],
[{
v: "In publishing and graphic design, lorem ipsum is a filler text commonly used to demonstrate the graphic elements of a document or visual presentation. ",
s: { alignment: { wrapText: 1, alignment: 'right', vertical: 'center', indent: 1}}
}
],
[
{v: 41684.35264774306, s: {numFmt: 'm/d/yy'}},
{v: 41684.35264774306, s: {numFmt: 'd-mmm-yy'}},
{v: 41684.35264774306, s: {numFmt: 'h:mm:ss AM/PM'}},
{v: JSDateToExcelDate(new Date()), s: {numFmt: 'm/d/yy'}},
{v: 42065.02247239584, s: {numFmt: 'm/d/yy'}},
{v: JSDateToExcelDate(new Date()), s: {numFmt: 'm/d/yy h:mm:ss AM/PM'}}
],
[
{v: "Apple", s: {border: {top: { style: "thin"}, left: { style: "thin"}, right: { style: "thin"}, bottom: { style: "thin"}}}},
{},
{
v: "Apple",
s: {
border: {
diagonalUp: 1, diagonalDown: 1,
top: { style: "dashed", color: {auto: 1}},
right: { style: "medium", color: {theme: "5"}},
bottom: { style: "hair", color: {theme: 5, tint: "-0.3"}},
left: { style: "thin", color: {rgb: "FFFFAA00"}},
diagonal: {style: "dotted", color: {auto: 1}}
}
}
},
{},
{
v: "Pear",
s: {
border: {
diagonalUp: 1, diagonalDown: 1,
top: { style: "dashed", color: {auto: 1}},
right: { style: "dotted", color: {theme: "5"}},
bottom: { style: "mediumDashed", color: {theme: 5, tint: "-0.3"}},
left: { style: "double", color: {rgb: "FFFFAA00"}},
diagonal: {style: "hair", color: {auto: 1}}
}
}
}
],
[
{v: "Up 90", s: {alignment: {textRotation: 90}}},
{v: "Up 45", s: {alignment: {textRotation: 45}}},
{v: "Horizontal", s: {alignment: {textRotation: 0}}},
{v: "Down 45", s: {alignment: {textRotation: 135}}},
{v: "Down 90", s: {alignment: {textRotation: 180}}},
{v: "Vertical", s: {alignment: {textRotation: 255}}}
],
[
{v: "Font color test", s: { font: {fgColor: {rgb: "FFC6EFCE"}}}}
]
]).mergeCells("Main", {
"s": {"c": 0, "r": 0 },
"e": {"c": 2, "r": 0 }
}).finalize();
var OUTFILE = '/tmp/wb.xlsx';
XLSX.writeFile(workbook, OUTFILE, {defaultCellStyle: { font: { name: "Verdana", sz: 11, color: "FF00FF88"}, fill: {fgColor: {rgb: "FFFFAA00"}}}});
console.log("Results written to " + OUTFILE)

BIN
out.txt Normal file

Binary file not shown.

20
test-acid.js Normal file

@ -0,0 +1,20 @@
var X = require('./');
var opts = { cellNF: true,
type: 'file',
cellHTML: true,
cellFormula: true,
cellStyles: false,
cellDates: false,
sheetStubs: false,
sheetRows: 0,
bookDeps: false,
bookSheets: false,
bookProps: false,
bookFiles: false,
bookVBA: false,
WTF: false }
;
var FILENAME = './test_files/number_format_entities-2.xlsx';
wb = X.read(X.write(X.readFile(FILENAME,opts), {type:"buffer", bookType:'xlsx'}), {WTF:true, cellNF: true})
X.writeFile(wb,'/tmp/wb3.xlsx');

@ -0,0 +1,43 @@
var argv = require('minimist')(process.argv.slice(2));
var XLSX = require('./');
var fs = require('fs')
var INFILE = './test_files/pivot_table_test.xlsm';
var TESTFILE = './test_files/pivot_table_test.xlsm.';
//var INFILE = './test_files/formula_stress_test.xlsb';
//var TESTFILE = './test_files/formula_stress_test.xls.';
var INFILE ='./test_files/apachepoi_Tables.xlsx';
var TESTFILE='./test_files/apachepoi_Tables.xlsx.';
var INFILE = './test_files/apachepoi_45540_classic_Footer.xlsx';
var TESTFILE = './test_files/apachepoi_45540_classic_Footer.xlsx.';
var SHEET=argv.p || 0;
function stripbom(x) { return x.replace(/^\ufeff/,""); }
function fixcsv(x) { return stripbom(x).replace(/\t/g,",").replace(/#{255}/g,"").replace(/"/g,"").replace(/[\n\r]+/g,"\n").replace(/\n*$/,""); }
wb = XLSX.readFile(INFILE, {cellNF: true});
//XLSX.writeFile(wb, '/tmp/test-csv.xlsx');
//var wb = XLSX.readFile('/tmp/test-csv.xlsx', {cellNF: true});
wb = XLSX.read(XLSX.write(wb, {type:"buffer", bookType:'xlsx'}), {cellNF: true})
var csv = fixcsv(XLSX.utils.make_csv(wb.Sheets[wb.SheetNames[SHEET]]))
console.log('==================')
console.log( csv);
console.log('------------')
var exp = fixcsv(fs.readFileSync(TESTFILE + SHEET+ '.csv','utf8'))
console.log(exp)
console.log('.............')
console.log(csv==exp);
console.log(csv.length, exp.length)
if (argv.d) {
for (var i=0; i<csv.length; i++) {
console.log([csv[i], exp[i]], csv[i] ==exp[i]);
}
}
//console.log(wb.Sheets[wb.SheetNames[0]].C2)

8
test-open.js Normal file

@ -0,0 +1,8 @@
var XLSX = require('./');
wbin = XLSX.readFile('/tmp/wb.xlsx', {type: "xlsx"});
XLSX.writeFile(wbin, '/tmp/wb2.xlsx', {
defaultCellStyle: { font: { name: "Verdana", sz: 11, color: "FF00FF88"}, fill: {fgColor: {rgb: "FFFFAA00"}}}
});

@ -343,7 +343,7 @@ describe("Export styles", function () {
"t": "s"
},
"B7": {
"v": "left",
"v": "center",
"s": {
"alignment": {
"horizontal": "center"
@ -352,7 +352,7 @@ describe("Export styles", function () {
"t": "s"
},
"C7": {
"v": "left",
"v": "right",
"s": {
"alignment": {
"horizontal": "right"
@ -650,6 +650,7 @@ describe("Export styles", function () {
it('can write to a buffer and read the file back', function () {
var wb2 = XLSX.read(XLSX.write(workbook, {type:"buffer", bookType: 'xlsx'}), {cellStyles: true, cellNF: true})
XLSX.writeFile(wb2, '/tmp/wb2.xlsx', { defaultCellStyle: defaultCellStyle });
assert(basicallyEquals(workbook.Sheets.Main,wb2.Sheets.Main));
});

@ -345,8 +345,6 @@ formula_stress_test.ods
merge_cells.ods
number_format.ods
rich_text_stress.ods
roo_Bibelbund.ods
roo_Bibelbund1.ods
roo_bbu.ods
roo_boolean.ods
roo_borders.ods

444
xlsx.js

@ -2192,84 +2192,123 @@ var themes = {}; // shared themes
/* 18.8.21 fills CT_Fills */
function parse_fills(t, opts) {
styles.Fills = [];
var fill = {};
t[0].match(tagregex).forEach(function(x) {
var y = parsexmltag(x);
switch(y[0]) {
case '<fills': case '<fills>': case '</fills>': break;
styles.Fills = [];
var fill = {};
t[0].match(tagregex).forEach(function (x) {
var y = parsexmltag(x);
switch (y[0]) {
case '<fills':
case '<fills>':
case '</fills>':
break;
/* 18.8.20 fill CT_Fill */
case '<fill>': break;
case '</fill>': styles.Fills.push(fill); fill = {}; break;
/* 18.8.20 fill CT_Fill */
case '<fill>':
break;
case '</fill>':
styles.Fills.push(fill);
fill = {};
break;
/* 18.8.32 patternFill CT_PatternFill */
case '<patternFill':
if(y.patternType) fill.patternType = y.patternType;
break;
case '<patternFill/>': case '</patternFill>': break;
/* 18.8.32 patternFill CT_PatternFill */
case '<patternFill':
if (y.patternType) fill.patternType = y.patternType;
break;
case '<patternFill/>':
case '</patternFill>':
break;
/* 18.8.3 bgColor CT_Color */
case '<bgColor':
if(!fill.bgColor) fill.bgColor = {};
if(y.indexed) fill.bgColor.indexed = parseInt(y.indexed, 10);
if(y.theme) fill.bgColor.theme = parseInt(y.theme, 10);
if(y.tint) fill.bgColor.tint = parseFloat(y.tint);
/* 18.8.3 bgColor CT_Color */
case '<bgColor':
if (!fill.bgColor) fill.bgColor = {};
if (y.indexed) fill.bgColor.indexed = parseInt(y.indexed, 10);
if (y.theme) fill.bgColor.theme = parseInt(y.theme, 10);
if (y.tint) fill.bgColor.tint = parseFloat(y.tint);
/* Excel uses ARGB strings */
if(y.rgb) fill.bgColor.rgb = y.rgb;//.substring(y.rgb.length - 6);
break;
case '<bgColor/>': case '</bgColor>': break;
if (y.rgb) fill.bgColor.rgb = y.rgb;//.substring(y.rgb.length - 6);
break;
case '<bgColor/>':
case '</bgColor>':
break;
/* 18.8.19 fgColor CT_Color */
case '<fgColor':
if(!fill.fgColor) fill.fgColor = {};
if(y.theme) fill.fgColor.theme = parseInt(y.theme, 10);
if(y.tint) fill.fgColor.tint = parseFloat(y.tint);
/* Excel uses ARGB strings */
if(y.rgb) fill.fgColor.rgb = y.rgb;//.substring(y.rgb.length - 6);
break;
case '<fgColor/>': case '</fgColor>': break;
/* 18.8.19 fgColor CT_Color */
case '<fgColor':
if (!fill.fgColor) fill.fgColor = {};
if (y.theme) fill.fgColor.theme = parseInt(y.theme, 10);
if (y.tint) fill.fgColor.tint = parseFloat(y.tint);
/* Excel uses ARGB strings */
if (y.rgb) fill.fgColor.rgb = y.rgb;//.substring(y.rgb.length - 6);
break;
case '<fgColor/>':
case '</fgColor>':
break;
default: if(opts.WTF) throw 'unrecognized ' + y[0] + ' in fills';
}
});
default:
if (opts.WTF) throw 'unrecognized ' + y[0] + ' in fills';
}
});
}
function parse_fonts(t, opts) {
styles.Fonts = [];
var font = {};
t[0].match(tagregex).forEach(function(x) {
t[0].match(tagregex).forEach(function (x) {
var y = parsexmltag(x);
switch(y[0]) {
switch (y[0]) {
case '<fonts': case '<fonts>': case '</fonts>': break;
case '<fonts':
case '<fonts>':
case '</fonts>':
break;
case '<font':
break;
case '</font>': styles.Fonts.push(font); ;font = {}; break;
case '</font>':
styles.Fonts.push(font);
;
font = {};
break;
case '<name':
if(y.val) font.name = y.val;
if (y.val) font.name = y.val;
break;
case '<name/>':
case '</name>':
break;
case '<name/>': case '</name>': break;
case '<b/>': font.bold = true;break;
case '<u/>': font.underline = true;break;
case '<i/>': font.italic = true;break;
case '<strike/>': font.strike = true;break;
case '<outline/>': font.outline = true;break;
case '<shadow/>': font.shadow = true;break;
case '<b/>':
font.bold = true;
break;
case '<u/>':
font.underline = true;
break;
case '<i/>':
font.italic = true;
break;
case '<strike/>':
font.strike = true;
break;
case '<outline/>':
font.outline = true;
break;
case '<shadow/>':
font.shadow = true;
break;
case '<sz':
if(y.val) font.sz = y.val;
if (y.val) font.sz = y.val;
break;
case '<sz/>':
case '</sz>':
break;
case '<sz/>': case '</sz>': break;
case '<vertAlign':
if(y.val) font.vertAlign = y.val;
if (y.val) font.vertAlign = y.val;
break;
case '<vertAlign/>':
case '</vertAlign>':
break;
case '<vertAlign/>': case '</vertAlign>': break;
case '<color':
@ -2278,32 +2317,77 @@ function parse_fonts(t, opts) {
if (y.tint) font.color.tint = y.tint;
if (y.rgb) font.color.rgb = y.rgb;
break;
case '<color/>':case '</color>': break;
case '<color/>':
case '</color>':
break;
}
});
}
function parse_borders(t, opts) {
styles.Borders = [];
var border = {};
t[0].match(tagregex).forEach(function(x) {
var border = {}, sub_border = {};
t[0].match(tagregex).forEach(function (x) {
var y = parsexmltag(x);
switch(y[0]) {
case '<borders': case '<borders>': case '</borders>': break;
case '<border>': break;
switch (y[0]) {
case '<borders':
case '<borders>':
case '</borders>':
break;
case '<border':
case '<border>':
border = {};
if (y.diagonalUp) { border.diagonalUp = y.diagonalUp; }
if (y.diagonalDown) { border.diagonalDown = y.diagonalDown; }
styles.Borders.push(border);
break;
break;
case '</border>':
styles.Fonts.push(border);
border = {}; break;
break;
case '<left':
sub_border = border.left = {};
if (y.style) {
sub_border.style = y.style;
}
break;
case '<right':
sub_border = border.right = {};
if (y.style) {
sub_border.style = y.style;
}
break;
case '<top':
sub_border = border.top = {};
if (y.style) {
sub_border.style = y.style;
}
break;
case '<bottom':
sub_border = border.bottom = {};
if (y.style) {
sub_border.style = y.style;
}
break;
case '<diagonal':
sub_border = border.diagonal = {};
if (y.style) {
sub_border.style = y.style;
}
break;
case '<color':
if(y.style) border.style = y.style;
sub_border.color = {};
if (y.theme) sub_border.color.theme = y.theme;
if (y.tint) sub_border.color.tint = y.tint;
if (y.rgb) sub_border.color.rgb = y.rgb;
break;
case '<name/>': case '</name>': break;
case '<sz':
if(y.val) font.sz = y.val;
case '<name/>':
case '</name>':
break;
default:
break;
case '<sz/>': case '</sz>': break;
}
});
@ -2311,111 +2395,153 @@ function parse_borders(t, opts) {
/* 18.8.31 numFmts CT_NumFmts */
function parse_numFmts(t, opts) {
styles.NumberFmt = [];
var k = keys(SSF._table);
for(var i=0; i < k.length; ++i) styles.NumberFmt[k[i]] = SSF._table[k[i]];
var m = t[0].match(tagregex);
for(i=0; i < m.length; ++i) {
var y = parsexmltag(m[i]);
switch(y[0]) {
case '<numFmts': case '</numFmts>': case '<numFmts/>': case '<numFmts>': break;
case '<numFmt': {
var f=unescapexml(utf8read(y.formatCode)), j=parseInt(y.numFmtId,10);
styles.NumberFmt[j] = f; if(j>0) SSF.load(f,j);
} break;
default: if(opts.WTF) throw 'unrecognized ' + y[0] + ' in numFmts';
}
}
styles.NumberFmt = [];
var k = keys(SSF._table);
for (var i = 0; i < k.length; ++i) styles.NumberFmt[k[i]] = SSF._table[k[i]];
var m = t[0].match(tagregex);
for (i = 0; i < m.length; ++i) {
var y = parsexmltag(m[i]);
switch (y[0]) {
case '<numFmts':
case '</numFmts>':
case '<numFmts/>':
case '<numFmts>':
break;
case '<numFmt':
{
var f = unescapexml(utf8read(y.formatCode)), j = parseInt(y.numFmtId, 10);
styles.NumberFmt[j] = f;
if (j > 0) SSF.load(f, j);
}
break;
default:
if (opts.WTF) throw 'unrecognized ' + y[0] + ' in numFmts';
}
}
}
function write_numFmts(NF, opts) {
var o = ["<numFmts>"];
[[5,8],[23,26],[41,44],[63,66],[164,392]].forEach(function(r) {
for(var i = r[0]; i <= r[1]; ++i) if(NF[i] !== undefined) o[o.length] = (writextag('numFmt',null,{numFmtId:i,formatCode:escapexml(NF[i])}));
});
if(o.length === 1) return "";
o[o.length] = ("</numFmts>");
o[0] = writextag('numFmts', null, { count:o.length-2 }).replace("/>", ">");
return o.join("");
var o = ["<numFmts>"];
[
[5, 8],
[23, 26],
[41, 44],
[63, 66],
[164, 392]
].forEach(function (r) {
for (var i = r[0]; i <= r[1]; ++i) if (NF[i] !== undefined) o[o.length] = (writextag('numFmt', null, {numFmtId: i, formatCode: escapexml(NF[i])}));
});
if (o.length === 1) return "";
o[o.length] = ("</numFmts>");
o[0] = writextag('numFmts', null, { count: o.length - 2 }).replace("/>", ">");
return o.join("");
}
/* 18.8.10 cellXfs CT_CellXfs */
function parse_cellXfs(t, opts) {
styles.CellXf = [];
t[0].match(tagregex).forEach(function(x) {
var y = parsexmltag(x);
switch(y[0]) {
case '<cellXfs': case '<cellXfs>': case '<cellXfs/>': case '</cellXfs>': break;
styles.CellXf = [];
var xf;
t[0].match(tagregex).forEach(function (x) {
var y = parsexmltag(x);
switch (y[0]) {
case '<cellXfs':
case '<cellXfs>':
case '<cellXfs/>':
case '</cellXfs>':
break;
/* 18.8.45 xf CT_Xf */
case '<xf': delete y[0];
if(y.numFmtId) y.numFmtId = parseInt(y.numFmtId, 10);
if(y.fillId) y.fillId = parseInt(y.fillId, 10);
styles.CellXf.push(y); break;
case '</xf>': break;
/* 18.8.45 xf CT_Xf */
case '<xf':
xf = y;
delete xf[0];
delete y[0];
if (xf.numFmtId) xf.numFmtId = parseInt(xf.numFmtId, 10);
if (xf.fillId) xf.fillId = parseInt(xf.fillId, 10);
styles.CellXf.push(xf);
break;
case '</xf>':
break;
/* 18.8.1 alignment CT_CellAlignment */
case '<alignment': case '<alignment/>': break;
/* 18.8.1 alignment CT_CellAlignment */
case '<alignment':
case '<alignment/>':
var alignment = {}
if (y.vertical) { alignment.vertical = y.vertical;}
if (y.horizontal) { alignment.horizontal = y.horizontal;}
if (y.indent) { alignment.indent = y.indent; }
if (y.wrapText) { alignment.wrapText = y.wrapText; }
xf.alignment = alignment;
/* 18.8.33 protection CT_CellProtection */
case '<protection': case '</protection>': case '<protection/>': break;
break;
case '<extLst': case '</extLst>': break;
case '<ext': break;
default: if(opts.WTF) throw 'unrecognized ' + y[0] + ' in cellXfs';
}
});
/* 18.8.33 protection CT_CellProtection */
case '<protection':
case '</protection>':
case '<protection/>':
break;
case '<extLst':
case '</extLst>':
break;
case '<ext':
break;
default:
if (opts.WTF) throw 'unrecognized ' + y[0] + ' in cellXfs';
}
});
}
function write_cellXfs(cellXfs) {
var o = [];
o[o.length] = (writextag('cellXfs',null));
cellXfs.forEach(function(c) { o[o.length] = (writextag('xf', null, c)); });
o[o.length] = ("</cellXfs>");
if(o.length === 2) return "";
o[0] = writextag('cellXfs',null, {count:o.length-2}).replace("/>",">");
return o.join("");
var o = [];
o[o.length] = (writextag('cellXfs', null));
cellXfs.forEach(function (c) {
o[o.length] = (writextag('xf', null, c));
});
o[o.length] = ("</cellXfs>");
if (o.length === 2) return "";
o[0] = writextag('cellXfs', null, {count: o.length - 2}).replace("/>", ">");
return o.join("");
}
/* 18.8 Styles CT_Stylesheet*/
var parse_sty_xml= (function make_pstyx() {
var numFmtRegex = /<numFmts([^>]*)>.*<\/numFmts>/;
var cellXfRegex = /<cellXfs([^>]*)>.*<\/cellXfs>/;
var fillsRegex = /<fills([^>]*)>.*<\/fills>/;
var bordersRegex = /<borders([^>]*)>.*<\/borders>/;
var parse_sty_xml = (function make_pstyx() {
var numFmtRegex = /<numFmts([^>]*)>.*<\/numFmts>/;
var cellXfRegex = /<cellXfs([^>]*)>.*<\/cellXfs>/;
var fillsRegex = /<fills([^>]*)>.*<\/fills>/;
var bordersRegex = /<borders([^>]*)>.*<\/borders>/;
return function parse_sty_xml(data, opts) {
/* 18.8.39 styleSheet CT_Stylesheet */
var t;
return function parse_sty_xml(data, opts) {
/* 18.8.39 styleSheet CT_Stylesheet */
var t;
/* numFmts CT_NumFmts ? */
if((t=data.match(numFmtRegex))) parse_numFmts(t, opts);
/* numFmts CT_NumFmts ? */
if ((t = data.match(numFmtRegex))) parse_numFmts(t, opts);
/* fonts CT_Fonts ? */
if((t=data.match(/<fonts([^>]*)>.*<\/fonts>/))) parse_fonts(t, opts)
/* fonts CT_Fonts ? */
if ((t = data.match(/<fonts([^>]*)>.*<\/fonts>/))) parse_fonts(t, opts)
/* fills CT_Fills */
if((t=data.match(fillsRegex))) parse_fills(t, opts);
/* fills CT_Fills */
if ((t = data.match(fillsRegex))) parse_fills(t, opts);
/* borders CT_Borders ? */
// if ((t=data.match(bordersRegex))) parse_borders(t, opts);
/* cellStyleXfs CT_CellStyleXfs ? */
/* borders CT_Borders ? */
if ((t = data.match(bordersRegex))) parse_borders(t, opts);
/* cellStyleXfs CT_CellStyleXfs ? */
/* cellXfs CT_CellXfs ? */
if((t=data.match(cellXfRegex))) parse_cellXfs(t, opts);
/* cellXfs CT_CellXfs ? */
if ((t = data.match(cellXfRegex))) parse_cellXfs(t, opts);
/* dxfs CT_Dxfs ? */
/* tableStyles CT_TableStyles ? */
/* colors CT_Colors ? */
/* extLst CT_ExtensionList ? */
/* dxfs CT_Dxfs ? */
/* tableStyles CT_TableStyles ? */
/* colors CT_Colors ? */
/* extLst CT_ExtensionList ? */
return styles;
};
return styles;
};
})();
var STYLES_XML_ROOT = writextag('styleSheet', null, {
'xmlns': XMLNS.main[0],
'xmlns:vt': XMLNS.vt
'xmlns': XMLNS.main[0],
'xmlns:vt': XMLNS.vt
});
RELS.STY = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles";
@ -2426,19 +2552,22 @@ function write_sty_xml(wb, opts) {
return style_builder.toXml();
}
var o = [XML_HEADER, STYLES_XML_ROOT], w;
if((w = write_numFmts(wb.SSF)) != null) o[o.length] = w;
o[o.length] = ('<fonts count="1"><font><sz val="12"/><color theme="1"/><name val="Calibri"/><family val="2"/><scheme val="minor"/></font></fonts>');
o[o.length] = ('<fills count="2"><fill><patternFill patternType="none"/></fill><fill><patternFill patternType="gray125"/></fill></fills>');
o[o.length] = ('<borders count="1"><border><left/><right/><top/><bottom/><diagonal/></border></borders>');
o[o.length] = ('<cellStyleXfs count="1"><xf numFmtId="0" fontId="0" fillId="0" borderId="0"/></cellStyleXfs>');
if((w = write_cellXfs(opts.cellXfs))) o[o.length] = (w);
o[o.length] = ('<cellStyles count="1"><cellStyle name="Normal" xfId="0" builtinId="0"/></cellStyles>');
o[o.length] = ('<dxfs count="0"/>');
o[o.length] = ('<tableStyles count="0" defaultTableStyle="TableStyleMedium9" defaultPivotStyle="PivotStyleMedium4"/>');
var o = [XML_HEADER, STYLES_XML_ROOT], w;
if ((w = write_numFmts(wb.SSF)) != null) o[o.length] = w;
o[o.length] = ('<fonts count="1"><font><sz val="12"/><color theme="1"/><name val="Calibri"/><family val="2"/><scheme val="minor"/></font></fonts>');
o[o.length] = ('<fills count="2"><fill><patternFill patternType="none"/></fill><fill><patternFill patternType="gray125"/></fill></fills>');
o[o.length] = ('<borders count="1"><border><left/><right/><top/><bottom/><diagonal/></border></borders>');
o[o.length] = ('<cellStyleXfs count="1"><xf numFmtId="0" fontId="0" fillId="0" borderId="0"/></cellStyleXfs>');
if ((w = write_cellXfs(opts.cellXfs))) o[o.length] = (w);
o[o.length] = ('<cellStyles count="1"><cellStyle name="Normal" xfId="0" builtinId="0"/></cellStyles>');
o[o.length] = ('<dxfs count="0"/>');
o[o.length] = ('<tableStyles count="0" defaultTableStyle="TableStyleMedium9" defaultPivotStyle="PivotStyleMedium4"/>');
if(o.length>2){ o[o.length] = ('</styleSheet>'); o[1]=o[1].replace("/>",">"); }
return o.join("");
if (o.length > 2) {
o[o.length] = ('</styleSheet>');
o[1] = o[1].replace("/>", ">");
}
return o.join("");
}
/* [MS-XLSB] 2.4.651 BrtFmt */
function parse_BrtFmt(data, length) {
@ -2892,6 +3021,7 @@ function get_cell_style(styles, cell, opts) {
function get_cell_style_csf(cellXf) {
if (cellXf) {
var s = {}
if (typeof cellXf.numFmtId != undefined) {
@ -2906,8 +3036,12 @@ function get_cell_style_csf(cellXf) {
s.font = styles.Fonts[cellXf.fontId];
}
if (cellXf.borderId) {
// s.border = styles.Borders[cellXf.borderId];
s.border = styles.Borders[cellXf.borderId];
}
if (cellXf.applyAlignment==1) {
s.alignment = cellXf.alignment;
}
return s;
}