forked from sheetjs/sheetjs
explicitly share styles and themes
This commit is contained in:
parent
5a3774e36e
commit
7888070603
@ -113,7 +113,6 @@ var parse_rs = (function parse_rs_factory() {
|
||||
if(y[0].charCodeAt(1) !== 47) throw 'Unrecognized rich format ' + y[0];
|
||||
}
|
||||
}
|
||||
/* TODO: These should be generated styles, not inline */
|
||||
var style = [];
|
||||
if(font.b) style.push("font-weight: bold;");
|
||||
if(font.i) style.push("font-style: italic;");
|
||||
|
@ -1,4 +0,0 @@
|
||||
var styles = {}; // shared styles
|
||||
|
||||
var themes = {}; // shared themes
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* 18.8.21 fills CT_Fills */
|
||||
function parse_fills(t, opts) {
|
||||
function parse_fills(t, styles, opts) {
|
||||
styles.Fills = [];
|
||||
var fill = {};
|
||||
t[0].match(tagregex).forEach(function(x) {
|
||||
@ -39,13 +39,13 @@ function parse_fills(t, opts) {
|
||||
break;
|
||||
case '<fgColor/>': case '</fgColor>': break;
|
||||
|
||||
default: if(opts.WTF) throw new Error('unrecognized ' + y[0] + ' in fills');
|
||||
default: if(opts && opts.WTF) throw new Error('unrecognized ' + y[0] + ' in fills');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* 18.8.31 numFmts CT_NumFmts */
|
||||
function parse_numFmts(t, opts) {
|
||||
function parse_numFmts(t, styles, opts) {
|
||||
styles.NumberFmt = [];
|
||||
var k/*Array<number>*/ = (keys(SSF._table)/*:any*/);
|
||||
for(var i=0; i < k.length; ++i) styles.NumberFmt[k[i]] = SSF._table[k[i]];
|
||||
@ -77,7 +77,7 @@ function write_numFmts(NF/*:{[n:number]:string}*/, opts) {
|
||||
}
|
||||
|
||||
/* 18.8.10 cellXfs CT_CellXfs */
|
||||
function parse_cellXfs(t, opts) {
|
||||
function parse_cellXfs(t, styles, opts) {
|
||||
styles.CellXf = [];
|
||||
t[0].match(tagregex).forEach(function(x) {
|
||||
var y = parsexmltag(x);
|
||||
@ -121,24 +121,25 @@ var cellXfRegex = /<cellXfs([^>]*)>.*<\/cellXfs>/;
|
||||
var fillsRegex = /<fills([^>]*)>.*<\/fills>/;
|
||||
|
||||
return function parse_sty_xml(data, opts) {
|
||||
var styles = {};
|
||||
if(!data) return styles;
|
||||
/* 18.8.39 styleSheet CT_Stylesheet */
|
||||
var t;
|
||||
|
||||
/* numFmts CT_NumFmts ? */
|
||||
if((t=data.match(numFmtRegex))) parse_numFmts(t, opts);
|
||||
if((t=data.match(numFmtRegex))) parse_numFmts(t, styles, 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);
|
||||
if((t=data.match(fillsRegex))) parse_fills(t, styles, opts);
|
||||
|
||||
/* borders CT_Borders ? */
|
||||
/* cellStyleXfs CT_CellStyleXfs ? */
|
||||
|
||||
/* cellXfs CT_CellXfs ? */
|
||||
if((t=data.match(cellXfRegex))) parse_cellXfs(t, opts);
|
||||
if((t=data.match(cellXfRegex))) parse_cellXfs(t, styles, opts);
|
||||
|
||||
/* dxfs CT_Dxfs ? */
|
||||
/* tableStyles CT_TableStyles ? */
|
||||
|
@ -42,6 +42,7 @@ function parse_BrtXF(data, length/*:number*/) {
|
||||
|
||||
/* [MS-XLSB] 2.1.7.50 Styles */
|
||||
function parse_sty_bin(data, opts) {
|
||||
var styles = {};
|
||||
styles.NumberFmt = ([]/*:any*/);
|
||||
for(var y in SSF._table) styles.NumberFmt[y] = SSF._table[y];
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
RELS.THEME = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme";
|
||||
|
||||
/* 20.1.6.2 clrScheme CT_ColorScheme */
|
||||
function parse_clrScheme(t, opts) {
|
||||
function parse_clrScheme(t, themes, opts) {
|
||||
themes.themeElements.clrScheme = [];
|
||||
var color = {};
|
||||
(t[0].match(tagregex)||[]).forEach(function(x) {
|
||||
@ -59,23 +59,23 @@ function parse_clrScheme(t, opts) {
|
||||
}
|
||||
break;
|
||||
|
||||
default: if(opts.WTF) throw 'unrecognized ' + y[0] + ' in clrScheme';
|
||||
default: if(opts && opts.WTF) throw new Error('Unrecognized ' + y[0] + ' in clrScheme');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* 20.1.4.1.18 fontScheme CT_FontScheme */
|
||||
function parse_fontScheme(t, opts) { }
|
||||
function parse_fontScheme(t, themes, opts) { }
|
||||
|
||||
/* 20.1.4.1.15 fmtScheme CT_StyleMatrix */
|
||||
function parse_fmtScheme(t, opts) { }
|
||||
function parse_fmtScheme(t, themes, opts) { }
|
||||
|
||||
var clrsregex = /<a:clrScheme([^>]*)>[^\u2603]*<\/a:clrScheme>/;
|
||||
var fntsregex = /<a:fontScheme([^>]*)>[^\u2603]*<\/a:fontScheme>/;
|
||||
var fmtsregex = /<a:fmtScheme([^>]*)>[^\u2603]*<\/a:fmtScheme>/;
|
||||
|
||||
/* 20.1.6.10 themeElements CT_BaseStyles */
|
||||
function parse_themeElements(data, opts) {
|
||||
function parse_themeElements(data, themes, opts) {
|
||||
themes.themeElements = {};
|
||||
|
||||
var t;
|
||||
@ -89,7 +89,7 @@ function parse_themeElements(data, opts) {
|
||||
['fmtScheme', fmtsregex, parse_fmtScheme]
|
||||
].forEach(function(m) {
|
||||
if(!(t=data.match(m[1]))) throw new Error(m[0] + ' not found in themeElements');
|
||||
m[2](t, opts);
|
||||
m[2](t, themes, opts);
|
||||
});
|
||||
}
|
||||
|
||||
@ -98,18 +98,19 @@ var themeltregex = /<a:themeElements([^>]*)>[^\u2603]*<\/a:themeElements>/;
|
||||
/* 14.2.7 Theme Part */
|
||||
function parse_theme_xml(data/*:string*/, opts) {
|
||||
/* 20.1.6.9 theme CT_OfficeStyleSheet */
|
||||
if(!data || data.length === 0) return themes;
|
||||
if(!data || data.length === 0) return parse_theme_xml(write_theme());
|
||||
|
||||
var t;
|
||||
var themes = {};
|
||||
|
||||
/* themeElements CT_BaseStyles */
|
||||
if(!(t=data.match(themeltregex))) throw 'themeElements not found in theme';
|
||||
parse_themeElements(t[0], opts);
|
||||
parse_themeElements(t[0], themes, opts);
|
||||
|
||||
return themes;
|
||||
}
|
||||
|
||||
function write_theme() {
|
||||
function write_theme(Themes, opts)/*:string*/ {
|
||||
var o = [XML_HEADER];
|
||||
o[o.length] = '<a:theme xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" name="Office Theme">';
|
||||
o[o.length] = '<a:themeElements>';
|
||||
@ -264,15 +265,15 @@ function write_theme() {
|
||||
o[o.length] = '</a:gradFill>';
|
||||
o[o.length] = '</a:bgFillStyleLst>';
|
||||
o[o.length] = '</a:fmtScheme>';
|
||||
|
||||
o[o.length] = '</a:themeElements>';
|
||||
|
||||
o[o.length] = '<a:objectDefaults>';
|
||||
o[o.length] = '<a:spDef>';
|
||||
o[o.length] = '<a:spPr/><a:bodyPr/><a:lstStyle/><a:style><a:lnRef idx="1"><a:schemeClr val="accent1"/></a:lnRef><a:fillRef idx="3"><a:schemeClr val="accent1"/></a:fillRef><a:effectRef idx="2"><a:schemeClr val="accent1"/></a:effectRef><a:fontRef idx="minor"><a:schemeClr val="lt1"/></a:fontRef></a:style>';
|
||||
o[o.length] = '</a:spDef>';
|
||||
o[o.length] = '<a:lnDef>';
|
||||
o[o.length] = '<a:spPr/><a:bodyPr/><a:lstStyle/><a:style><a:lnRef idx="2"><a:schemeClr val="accent1"/></a:lnRef><a:fillRef idx="0"><a:schemeClr val="accent1"/></a:fillRef><a:effectRef idx="1"><a:schemeClr val="accent1"/></a:effectRef><a:fontRef idx="minor"><a:schemeClr val="tx1"/></a:fontRef></a:style>';
|
||||
o[o.length] = '</a:lnDef>';
|
||||
o[o.length] = '</a:lnDef>';
|
||||
o[o.length] = '</a:objectDefaults>';
|
||||
o[o.length] = '<a:extraClrSchemeLst/>';
|
||||
o[o.length] = '</a:theme>';
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* [MS-XLS] 2.4.326 TODO: payload is a zip file */
|
||||
function parse_Theme(blob, length) {
|
||||
function parse_Theme(blob, length, opts) {
|
||||
var dwThemeVersion = blob.read_shift(4);
|
||||
if(dwThemeVersion === 124226) return;
|
||||
blob.l += length-4;
|
||||
|
@ -22,7 +22,7 @@ function get_cell_style(styles, cell, opts) {
|
||||
return len;
|
||||
}
|
||||
|
||||
function safe_format(p, fmtid, fillid, opts) {
|
||||
function safe_format(p, fmtid, fillid, opts, themes, styles) {
|
||||
if(p.t === 'z') return;
|
||||
if(p.t === 'd' && typeof p.v === 'string') p.v = new Date(p.v);
|
||||
try {
|
||||
|
@ -8,7 +8,7 @@ var hlinkregex = /<(?:\w*:)?hyperlink[^>]*\/>/g;
|
||||
var dimregex = /"(\w*:\w*)"/;
|
||||
var colregex = /<(?:\w*:)?col[^>]*\/>/g;
|
||||
/* 18.3 Worksheets */
|
||||
function parse_ws_xml(data/*:?string*/, opts, rels)/*:Worksheet*/ {
|
||||
function parse_ws_xml(data/*:?string*/, opts, rels, wb, themes, styles)/*:Worksheet*/ {
|
||||
if(!data) return data;
|
||||
/* 18.3.1.99 worksheet CT_Worksheet */
|
||||
var s = ({}/*:any*/);
|
||||
@ -39,7 +39,7 @@ function parse_ws_xml(data/*:?string*/, opts, rels)/*:Worksheet*/ {
|
||||
|
||||
/* 18.3.1.80 sheetData CT_SheetData ? */
|
||||
var mtch=data.match(sheetdataregex);
|
||||
if(mtch) parse_ws_xml_data(mtch[1], s, opts, refguess);
|
||||
if(mtch) parse_ws_xml_data(mtch[1], s, opts, refguess, themes, styles);
|
||||
|
||||
/* 18.3.1.48 hyperlinks CT_Hyperlinks */
|
||||
var hlink = data.match(hlinkregex);
|
||||
@ -173,7 +173,7 @@ var parse_ws_xml_data = (function parse_ws_xml_data_factory() {
|
||||
var refregex = /ref=["']([^"']*)["']/;
|
||||
var match_v = matchtag("v"), match_f = matchtag("f");
|
||||
|
||||
return function parse_ws_xml_data(sdata, s, opts, guess) {
|
||||
return function parse_ws_xml_data(sdata, s, opts, guess, themes, styles) {
|
||||
var ri = 0, x = "", cells = [], cref = [], idx = 0, i=0, cc=0, d="", p/*:any*/;
|
||||
var tag, tagr = 0, tagc = 0;
|
||||
var sstr, ftag;
|
||||
@ -288,7 +288,7 @@ return function parse_ws_xml_data(sdata, s, opts, guess) {
|
||||
if(opts.cellStyles && cf.fillId != null) fillid = cf.fillId;
|
||||
}
|
||||
}
|
||||
safe_format(p, fmtid, fillid, opts);
|
||||
safe_format(p, fmtid, fillid, opts, themes, styles);
|
||||
s[tag.r] = p;
|
||||
}
|
||||
}
|
||||
|
@ -256,7 +256,7 @@ function parse_BrtShrFmla(data, length, opts) {
|
||||
}
|
||||
|
||||
/* [MS-XLSB] 2.1.7.61 Worksheet */
|
||||
function parse_ws_bin(data, opts, rels, wb)/*:Worksheet*/ {
|
||||
function parse_ws_bin(data, opts, rels, wb, themes, styles)/*:Worksheet*/ {
|
||||
if(!data) return data;
|
||||
if(!rels) rels = {'!id':{}};
|
||||
var s = {};
|
||||
@ -311,7 +311,7 @@ function parse_ws_bin(data, opts, rels, wb)/*:Worksheet*/ {
|
||||
case 'e': p.v = val[1]; p.w = BErr[p.v]; break;
|
||||
case 'str': p.t = 's'; p.v = utf8read(val[1]); break;
|
||||
}
|
||||
if((cf = styles.CellXf[val[0].iStyleRef])) safe_format(p,cf.ifmt,null,opts);
|
||||
if((cf = styles.CellXf[val[0].iStyleRef])) safe_format(p,cf.ifmt,null,opts, themes, styles);
|
||||
s[encode_col(C=val[0].c) + rr] = p;
|
||||
if(opts.cellFormula) {
|
||||
af = false;
|
||||
|
@ -3,9 +3,9 @@ function parse_wb(data, name/*:string*/, opts)/*:WorkbookFile*/ {
|
||||
return parse_wb_xml((data/*:any*/), opts);
|
||||
}
|
||||
|
||||
function parse_ws(data, name/*:string*/, opts, rels, wb)/*:Worksheet*/ {
|
||||
if(name.slice(-4)===".bin") return parse_ws_bin((data/*:any*/), opts, rels, wb);
|
||||
return parse_ws_xml((data/*:any*/), opts, rels, wb);
|
||||
function parse_ws(data, name/*:string*/, opts, rels, wb, themes, styles)/*:Worksheet*/ {
|
||||
if(name.slice(-4)===".bin") return parse_ws_bin((data/*:any*/), opts, rels, wb, themes, styles);
|
||||
return parse_ws_xml((data/*:any*/), opts, rels, wb, themes, styles);
|
||||
}
|
||||
|
||||
function parse_sty(data, name/*:string*/, opts) {
|
||||
|
@ -149,7 +149,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
||||
biff: 8, // BIFF version
|
||||
codepage: 0, // CP from CodePage record
|
||||
winlocked: 0, // fLockWn from WinProtect
|
||||
wtf: false
|
||||
WTF: !!options && !!options.wtf
|
||||
}/*:any*/);
|
||||
if(options.password) opts.password = options.password;
|
||||
var mergecells = [];
|
||||
|
@ -35,6 +35,7 @@ var parse_content_xml = (function() {
|
||||
var rept = 1, isstub = false;
|
||||
var i = 0;
|
||||
xlmlregex.lastIndex = 0;
|
||||
str = str.replace(/<!--([^\u2603]*?)-->/mg,"").replace(/<!DOCTYPE[^\[]*\[[^\]]*\]>/gm,"");
|
||||
while((Rn = xlmlregex.exec(str))) switch((Rn[3]=Rn[3].replace(/_.*$/,""))) {
|
||||
|
||||
case 'table': case '工作表': // 9.1.2 <table:table>
|
||||
@ -388,7 +389,7 @@ var parse_content_xml = (function() {
|
||||
if(Rn[2] === 'uof:') break; // TODO: uof
|
||||
if(Rn[2] === '表:') break; // TODO: uof
|
||||
if(Rn[2] === '字:') break; // TODO: uof
|
||||
if(opts.WTF) throw Rn;
|
||||
if(opts.WTF) throw new Error(Rn);
|
||||
}
|
||||
var out = {
|
||||
Sheets: Sheets,
|
||||
|
@ -6,10 +6,10 @@ function safe_parse_wbrels(wbrels, sheets) {
|
||||
return !wbrels || wbrels.length === 0 ? null : wbrels;
|
||||
}
|
||||
|
||||
function safe_parse_ws(zip, path/*:string*/, relsPath/*:string*/, sheet, sheetRels, sheets, opts, wb) {
|
||||
function safe_parse_ws(zip, path/*:string*/, relsPath/*:string*/, sheet, sheetRels, sheets, opts, wb, themes, styles) {
|
||||
try {
|
||||
sheetRels[sheet]=parse_rels(getzipstr(zip, relsPath, true), path);
|
||||
sheets[sheet]=parse_ws(getzipdata(zip, path),path,opts,sheetRels[sheet], wb);
|
||||
sheets[sheet]=parse_ws(getzipdata(zip, path),path,opts,sheetRels[sheet], wb, themes, styles);
|
||||
} catch(e) { if(opts.WTF) throw e; }
|
||||
}
|
||||
|
||||
@ -42,14 +42,14 @@ function parse_zip(zip/*:ZIP*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
|
||||
if(dir.workbooks[0].slice(-3) == "bin") xlsb = true;
|
||||
if(xlsb) set_cp(1200);
|
||||
|
||||
var themes = ({}/*:any*/);
|
||||
var styles = ({}/*:any*/);
|
||||
if(!opts.bookSheets && !opts.bookProps) {
|
||||
strs = [];
|
||||
if(dir.sst) strs=parse_sst(getzipdata(zip, dir.sst.replace(/^\//,'')), dir.sst, opts);
|
||||
|
||||
styles = {};
|
||||
if(dir.style) styles = parse_sty(getzipdata(zip, dir.style.replace(/^\//,'')),dir.style, opts);
|
||||
|
||||
themes = {};
|
||||
if(opts.cellStyles && dir.themes.length) themes = parse_theme(getzipstr(zip, dir.themes[0].replace(/^\//,''), true)||"",dir.themes[0], opts);
|
||||
}
|
||||
|
||||
@ -112,7 +112,7 @@ function parse_zip(zip/*:ZIP*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
|
||||
path = path.replace(/sheet0\./,"sheet.");
|
||||
}
|
||||
relsPath = path.replace(/^(.*)(\/)([^\/]*)$/, "$1/_rels/$3.rels");
|
||||
safe_parse_ws(zip, path, relsPath, props.SheetNames[i], sheetRels, sheets, opts, wb);
|
||||
safe_parse_ws(zip, path, relsPath, props.SheetNames[i], sheetRels, sheets, opts, wb, themes, styles);
|
||||
}
|
||||
|
||||
if(dir.comments) parse_comments(zip, dir.comments, sheets, sheetRels, opts);
|
||||
|
@ -78,7 +78,7 @@ function write_zip(wb/*:Workbook*/, opts/*:WriteOpts*/)/*:ZIP*/ {
|
||||
/* TODO: something more intelligent with themes */
|
||||
|
||||
f = "xl/theme/theme1.xml";
|
||||
zip.file(f, write_theme());
|
||||
zip.file(f, write_theme(wb.Themes, opts));
|
||||
ct.themes.push(f);
|
||||
add_rels(opts.wbrels, ++rId, "theme/theme1.xml", RELS.THEME);
|
||||
|
||||
|
@ -15,6 +15,7 @@ type Workbook = {
|
||||
|
||||
Props?: any;
|
||||
Custprops?: any;
|
||||
Themes?: any;
|
||||
|
||||
SSF?: {[n:number]:string};
|
||||
cfb?: any;
|
||||
|
6
test.js
6
test.js
@ -601,7 +601,7 @@ function diffsty(ws, r1,r2) {
|
||||
}
|
||||
|
||||
describe('parse features', function() {
|
||||
it('should have comment as part of cell properties', function(){
|
||||
if(fs.existsSync(paths.swcxlsx)) it('should have comment as part of cell properties', function(){
|
||||
var X = require(modp);
|
||||
var sheet = 'Sheet1';
|
||||
var wb1=X.readFile(paths.swcxlsx);
|
||||
@ -620,7 +620,7 @@ describe('parse features', function() {
|
||||
});
|
||||
|
||||
describe('should parse core properties and custom properties', function() {
|
||||
var wb1, wb2;
|
||||
var wb1, wb2, wb3, wb4;
|
||||
var bef = (function() {
|
||||
wb1 = X.readFile(paths.cpxlsx);
|
||||
wb2 = X.readFile(paths.cpxlsb);
|
||||
@ -1142,7 +1142,7 @@ describe('corner cases', function() {
|
||||
["foo","bar",new Date("2014-02-19T14:30Z"), "0.3"],
|
||||
["baz", null, "q\"ux"]
|
||||
];
|
||||
ws = sheet_from_array_of_arrays(data);
|
||||
var ws = sheet_from_array_of_arrays(data);
|
||||
ws.A1.f = ""; ws.A1.w = "";
|
||||
delete ws.C3.w; delete ws.C3.z; ws.C3.XF = {ifmt:14};
|
||||
ws.A4.t = "e";
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit e0b7060b10ef972ad48869faa4efffd089e1a428
|
||||
Subproject commit 664ad78895cb8dad33e8e993614555baf7d999ae
|
106
tests.lst
106
tests.lst
@ -353,8 +353,8 @@ openpyxl_r_null_file.xlsx.pending
|
||||
phonetic_text.xlsx
|
||||
pivot_table_named_range.xlsx
|
||||
rich_text_stress.xlsx
|
||||
roo-xls_numbers1.xlsx
|
||||
roo-xls_type_excel.xlsx
|
||||
roo_numbers1.xlsx
|
||||
# roo_type_excel.xlsx # incorrect baseline
|
||||
roo_1900_base.xlsx
|
||||
roo_1904_base.xlsx
|
||||
roo_Bibelbund.xlsx
|
||||
@ -538,8 +538,8 @@ formula_stress_test.ods
|
||||
merge_cells.ods
|
||||
number_format.ods
|
||||
rich_text_stress.ods
|
||||
roo-xls_numbers1.ods
|
||||
roo-xls_type_excel.ods
|
||||
roo_numbers1.ods
|
||||
roo_type_excel.ods
|
||||
roo_Bibelbund.ods
|
||||
roo_Bibelbund1.ods
|
||||
roo_advanced_header.ods
|
||||
@ -1193,34 +1193,34 @@ pyExcelerator_mini-mini.xls
|
||||
pyExcelerator_mini.xls
|
||||
pyExcelerator_oo14.xls
|
||||
rich_text_stress.xls
|
||||
roo-xls_1900_base.xls
|
||||
roo-xls_1904_base.xls
|
||||
roo-xls_Bibelbund.xls
|
||||
roo-xls_bad_excel_date.xls
|
||||
roo-xls_bbu.xls
|
||||
roo-xls_boolean.xls
|
||||
roo-xls_borders.xls
|
||||
roo-xls_bug-row-column-fixnum-float.xls
|
||||
roo-xls_comments.xls
|
||||
roo-xls_datetime.xls
|
||||
roo-xls_datetime_floatconv.xls
|
||||
roo-xls_emptysheets.xls
|
||||
roo-xls_false_encoding.xls
|
||||
roo-xls_formula.xls
|
||||
roo-xls_formula_parse_error.xls
|
||||
roo-xls_link.xls
|
||||
roo-xls_matrix.xls
|
||||
roo-xls_named_cells.xls
|
||||
roo-xls_numbers1.xls
|
||||
roo-xls_only_one_sheet.xls
|
||||
roo-xls_paragraph.xls
|
||||
roo-xls_prova.xls
|
||||
roo-xls_simple_spreadsheet.xls
|
||||
roo-xls_simple_spreadsheet_from_italo.xls
|
||||
roo-xls_style.xls
|
||||
roo-xls_time-test.xls
|
||||
roo-xls_type_excelx.xls
|
||||
roo-xls_type_openoffice.xls
|
||||
roo_1900_base.xls
|
||||
roo_1904_base.xls
|
||||
roo_Bibelbund.xls
|
||||
roo_bad_excel_date.xls
|
||||
roo_bbu.xls
|
||||
roo_boolean.xls
|
||||
roo_borders.xls
|
||||
roo_bug-row-column-fixnum-float.xls
|
||||
roo_comments.xls
|
||||
roo_datetime.xls
|
||||
roo_datetime_floatconv.xls
|
||||
roo_emptysheets.xls
|
||||
roo_false_encoding.xls
|
||||
roo_formula.xls
|
||||
roo_formula_parse_error.xls
|
||||
roo_link.xls
|
||||
roo_matrix.xls
|
||||
roo_named_cells.xls
|
||||
roo_numbers1.xls
|
||||
roo_only_one_sheet.xls
|
||||
roo_paragraph.xls
|
||||
roo_prova.xls
|
||||
roo_simple_spreadsheet.xls
|
||||
roo_simple_spreadsheet_from_italo.xls
|
||||
roo_style.xls
|
||||
roo_time-test.xls
|
||||
roo_type_excelx.xls
|
||||
# roo_type_openoffice.xls # incorrect baseline
|
||||
roo_whitespace.xls
|
||||
smart_tags_2007.xls
|
||||
sushi.xls
|
||||
@ -1300,27 +1300,27 @@ protect_stress_test_xml.xml
|
||||
rich_text_stress.xls.xml
|
||||
rich_text_stress.xlsb.xml
|
||||
rich_text_stress.xlsx.xml
|
||||
roo-xls_Bibelbund.xml
|
||||
roo-xls_bbu.xml
|
||||
roo-xls_boolean.xml
|
||||
roo-xls_borders.xml
|
||||
roo-xls_bug-row-column-fixnum-float.xml
|
||||
roo-xls_datetime.xml
|
||||
roo-xls_datetime_floatconv.xml
|
||||
roo-xls_emptysheets.xml
|
||||
roo-xls_excel2003.xml
|
||||
roo-xls_excel2003_namespace.xml
|
||||
roo-xls_false_encoding.xml
|
||||
roo-xls_formula.xml
|
||||
roo-xls_formula_parse_error.xml
|
||||
roo-xls_numbers1.xml
|
||||
roo-xls_only_one_sheet.xml
|
||||
roo-xls_paragraph.xml
|
||||
roo-xls_simple_spreadsheet.xml
|
||||
roo-xls_simple_spreadsheet_from_italo.xml
|
||||
roo-xls_style.xml
|
||||
roo-xls_time-test.xml
|
||||
roo-xls_whitespace.xml
|
||||
roo_Bibelbund.xml
|
||||
# roo_bbu.xml # SSF TODO
|
||||
# roo_boolean.xml # SSF TODO
|
||||
roo_borders.xml
|
||||
roo_bug-row-column-fixnum-float.xml
|
||||
# roo_datetime.xml # SSF TODO
|
||||
# roo_datetime_floatconv.xml # SSF TODO
|
||||
roo_emptysheets.xml
|
||||
# roo_excel2003.xml # SSF TODO
|
||||
roo_excel2003_namespace.xml
|
||||
# roo_false_encoding.xml # SSF TODO
|
||||
roo_formula.xml
|
||||
roo_formula_parse_error.xml
|
||||
# roo_numbers1.xml # SSF TODO
|
||||
roo_only_one_sheet.xml
|
||||
roo_paragraph.xml
|
||||
# roo_simple_spreadsheet.xml # SSF TODO
|
||||
# roo_simple_spreadsheet_from_italo.xml # SSF TODO
|
||||
roo_style.xml
|
||||
# roo_time-test.xml # SSF TODO
|
||||
# roo_whitespace.xml # SSF TODO
|
||||
# roo_sheet1.xml
|
||||
smart_tags_2007.xml
|
||||
sushi.xml
|
||||
|
83
xlsx.flow.js
83
xlsx.flow.js
@ -4666,7 +4666,6 @@ var parse_rs = (function parse_rs_factory() {
|
||||
if(y[0].charCodeAt(1) !== 47) throw 'Unrecognized rich format ' + y[0];
|
||||
}
|
||||
}
|
||||
/* TODO: These should be generated styles, not inline */
|
||||
var style = [];
|
||||
if(font.b) style.push("font-weight: bold;");
|
||||
if(font.i) style.push("font-style: italic;");
|
||||
@ -5072,12 +5071,8 @@ var XLMLPatternTypeMap = {
|
||||
"ThinHorzCross": "lightGrid"
|
||||
};
|
||||
|
||||
var styles = {}; // shared styles
|
||||
|
||||
var themes = {}; // shared themes
|
||||
|
||||
/* 18.8.21 fills CT_Fills */
|
||||
function parse_fills(t, opts) {
|
||||
function parse_fills(t, styles, opts) {
|
||||
styles.Fills = [];
|
||||
var fill = {};
|
||||
t[0].match(tagregex).forEach(function(x) {
|
||||
@ -5117,13 +5112,13 @@ function parse_fills(t, opts) {
|
||||
break;
|
||||
case '<fgColor/>': case '</fgColor>': break;
|
||||
|
||||
default: if(opts.WTF) throw new Error('unrecognized ' + y[0] + ' in fills');
|
||||
default: if(opts && opts.WTF) throw new Error('unrecognized ' + y[0] + ' in fills');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* 18.8.31 numFmts CT_NumFmts */
|
||||
function parse_numFmts(t, opts) {
|
||||
function parse_numFmts(t, styles, opts) {
|
||||
styles.NumberFmt = [];
|
||||
var k/*Array<number>*/ = (keys(SSF._table)/*:any*/);
|
||||
for(var i=0; i < k.length; ++i) styles.NumberFmt[k[i]] = SSF._table[k[i]];
|
||||
@ -5155,7 +5150,7 @@ function write_numFmts(NF/*:{[n:number]:string}*/, opts) {
|
||||
}
|
||||
|
||||
/* 18.8.10 cellXfs CT_CellXfs */
|
||||
function parse_cellXfs(t, opts) {
|
||||
function parse_cellXfs(t, styles, opts) {
|
||||
styles.CellXf = [];
|
||||
t[0].match(tagregex).forEach(function(x) {
|
||||
var y = parsexmltag(x);
|
||||
@ -5199,24 +5194,25 @@ var cellXfRegex = /<cellXfs([^>]*)>.*<\/cellXfs>/;
|
||||
var fillsRegex = /<fills([^>]*)>.*<\/fills>/;
|
||||
|
||||
return function parse_sty_xml(data, opts) {
|
||||
var styles = {};
|
||||
if(!data) return styles;
|
||||
/* 18.8.39 styleSheet CT_Stylesheet */
|
||||
var t;
|
||||
|
||||
/* numFmts CT_NumFmts ? */
|
||||
if((t=data.match(numFmtRegex))) parse_numFmts(t, opts);
|
||||
if((t=data.match(numFmtRegex))) parse_numFmts(t, styles, 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);
|
||||
if((t=data.match(fillsRegex))) parse_fills(t, styles, opts);
|
||||
|
||||
/* borders CT_Borders ? */
|
||||
/* cellStyleXfs CT_CellStyleXfs ? */
|
||||
|
||||
/* cellXfs CT_CellXfs ? */
|
||||
if((t=data.match(cellXfRegex))) parse_cellXfs(t, opts);
|
||||
if((t=data.match(cellXfRegex))) parse_cellXfs(t, styles, opts);
|
||||
|
||||
/* dxfs CT_Dxfs ? */
|
||||
/* tableStyles CT_TableStyles ? */
|
||||
@ -5293,6 +5289,7 @@ function parse_BrtXF(data, length/*:number*/) {
|
||||
|
||||
/* [MS-XLSB] 2.1.7.50 Styles */
|
||||
function parse_sty_bin(data, opts) {
|
||||
var styles = {};
|
||||
styles.NumberFmt = ([]/*:any*/);
|
||||
for(var y in SSF._table) styles.NumberFmt[y] = SSF._table[y];
|
||||
|
||||
@ -5385,7 +5382,7 @@ function write_sty_bin(data, opts) {
|
||||
RELS.THEME = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme";
|
||||
|
||||
/* 20.1.6.2 clrScheme CT_ColorScheme */
|
||||
function parse_clrScheme(t, opts) {
|
||||
function parse_clrScheme(t, themes, opts) {
|
||||
themes.themeElements.clrScheme = [];
|
||||
var color = {};
|
||||
(t[0].match(tagregex)||[]).forEach(function(x) {
|
||||
@ -5443,23 +5440,23 @@ function parse_clrScheme(t, opts) {
|
||||
}
|
||||
break;
|
||||
|
||||
default: if(opts.WTF) throw 'unrecognized ' + y[0] + ' in clrScheme';
|
||||
default: if(opts && opts.WTF) throw new Error('Unrecognized ' + y[0] + ' in clrScheme');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* 20.1.4.1.18 fontScheme CT_FontScheme */
|
||||
function parse_fontScheme(t, opts) { }
|
||||
function parse_fontScheme(t, themes, opts) { }
|
||||
|
||||
/* 20.1.4.1.15 fmtScheme CT_StyleMatrix */
|
||||
function parse_fmtScheme(t, opts) { }
|
||||
function parse_fmtScheme(t, themes, opts) { }
|
||||
|
||||
var clrsregex = /<a:clrScheme([^>]*)>[^\u2603]*<\/a:clrScheme>/;
|
||||
var fntsregex = /<a:fontScheme([^>]*)>[^\u2603]*<\/a:fontScheme>/;
|
||||
var fmtsregex = /<a:fmtScheme([^>]*)>[^\u2603]*<\/a:fmtScheme>/;
|
||||
|
||||
/* 20.1.6.10 themeElements CT_BaseStyles */
|
||||
function parse_themeElements(data, opts) {
|
||||
function parse_themeElements(data, themes, opts) {
|
||||
themes.themeElements = {};
|
||||
|
||||
var t;
|
||||
@ -5473,7 +5470,7 @@ function parse_themeElements(data, opts) {
|
||||
['fmtScheme', fmtsregex, parse_fmtScheme]
|
||||
].forEach(function(m) {
|
||||
if(!(t=data.match(m[1]))) throw new Error(m[0] + ' not found in themeElements');
|
||||
m[2](t, opts);
|
||||
m[2](t, themes, opts);
|
||||
});
|
||||
}
|
||||
|
||||
@ -5482,18 +5479,19 @@ var themeltregex = /<a:themeElements([^>]*)>[^\u2603]*<\/a:themeElements>/;
|
||||
/* 14.2.7 Theme Part */
|
||||
function parse_theme_xml(data/*:string*/, opts) {
|
||||
/* 20.1.6.9 theme CT_OfficeStyleSheet */
|
||||
if(!data || data.length === 0) return themes;
|
||||
if(!data || data.length === 0) return parse_theme_xml(write_theme());
|
||||
|
||||
var t;
|
||||
var themes = {};
|
||||
|
||||
/* themeElements CT_BaseStyles */
|
||||
if(!(t=data.match(themeltregex))) throw 'themeElements not found in theme';
|
||||
parse_themeElements(t[0], opts);
|
||||
parse_themeElements(t[0], themes, opts);
|
||||
|
||||
return themes;
|
||||
}
|
||||
|
||||
function write_theme() {
|
||||
function write_theme(Themes, opts)/*:string*/ {
|
||||
var o = [XML_HEADER];
|
||||
o[o.length] = '<a:theme xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" name="Office Theme">';
|
||||
o[o.length] = '<a:themeElements>';
|
||||
@ -5648,22 +5646,22 @@ function write_theme() {
|
||||
o[o.length] = '</a:gradFill>';
|
||||
o[o.length] = '</a:bgFillStyleLst>';
|
||||
o[o.length] = '</a:fmtScheme>';
|
||||
|
||||
o[o.length] = '</a:themeElements>';
|
||||
|
||||
o[o.length] = '<a:objectDefaults>';
|
||||
o[o.length] = '<a:spDef>';
|
||||
o[o.length] = '<a:spPr/><a:bodyPr/><a:lstStyle/><a:style><a:lnRef idx="1"><a:schemeClr val="accent1"/></a:lnRef><a:fillRef idx="3"><a:schemeClr val="accent1"/></a:fillRef><a:effectRef idx="2"><a:schemeClr val="accent1"/></a:effectRef><a:fontRef idx="minor"><a:schemeClr val="lt1"/></a:fontRef></a:style>';
|
||||
o[o.length] = '</a:spDef>';
|
||||
o[o.length] = '<a:lnDef>';
|
||||
o[o.length] = '<a:spPr/><a:bodyPr/><a:lstStyle/><a:style><a:lnRef idx="2"><a:schemeClr val="accent1"/></a:lnRef><a:fillRef idx="0"><a:schemeClr val="accent1"/></a:fillRef><a:effectRef idx="1"><a:schemeClr val="accent1"/></a:effectRef><a:fontRef idx="minor"><a:schemeClr val="tx1"/></a:fontRef></a:style>';
|
||||
o[o.length] = '</a:lnDef>';
|
||||
o[o.length] = '</a:lnDef>';
|
||||
o[o.length] = '</a:objectDefaults>';
|
||||
o[o.length] = '<a:extraClrSchemeLst/>';
|
||||
o[o.length] = '</a:theme>';
|
||||
return o.join("");
|
||||
}
|
||||
/* [MS-XLS] 2.4.326 TODO: payload is a zip file */
|
||||
function parse_Theme(blob, length) {
|
||||
function parse_Theme(blob, length, opts) {
|
||||
var dwThemeVersion = blob.read_shift(4);
|
||||
if(dwThemeVersion === 124226) return;
|
||||
blob.l += length-4;
|
||||
@ -8248,7 +8246,7 @@ function get_cell_style(styles, cell, opts) {
|
||||
return len;
|
||||
}
|
||||
|
||||
function safe_format(p, fmtid, fillid, opts) {
|
||||
function safe_format(p, fmtid, fillid, opts, themes, styles) {
|
||||
if(p.t === 'z') return;
|
||||
if(p.t === 'd' && typeof p.v === 'string') p.v = new Date(p.v);
|
||||
try {
|
||||
@ -8292,7 +8290,7 @@ var hlinkregex = /<(?:\w*:)?hyperlink[^>]*\/>/g;
|
||||
var dimregex = /"(\w*:\w*)"/;
|
||||
var colregex = /<(?:\w*:)?col[^>]*\/>/g;
|
||||
/* 18.3 Worksheets */
|
||||
function parse_ws_xml(data/*:?string*/, opts, rels)/*:Worksheet*/ {
|
||||
function parse_ws_xml(data/*:?string*/, opts, rels, wb, themes, styles)/*:Worksheet*/ {
|
||||
if(!data) return data;
|
||||
/* 18.3.1.99 worksheet CT_Worksheet */
|
||||
var s = ({}/*:any*/);
|
||||
@ -8323,7 +8321,7 @@ function parse_ws_xml(data/*:?string*/, opts, rels)/*:Worksheet*/ {
|
||||
|
||||
/* 18.3.1.80 sheetData CT_SheetData ? */
|
||||
var mtch=data.match(sheetdataregex);
|
||||
if(mtch) parse_ws_xml_data(mtch[1], s, opts, refguess);
|
||||
if(mtch) parse_ws_xml_data(mtch[1], s, opts, refguess, themes, styles);
|
||||
|
||||
/* 18.3.1.48 hyperlinks CT_Hyperlinks */
|
||||
var hlink = data.match(hlinkregex);
|
||||
@ -8457,7 +8455,7 @@ var parse_ws_xml_data = (function parse_ws_xml_data_factory() {
|
||||
var refregex = /ref=["']([^"']*)["']/;
|
||||
var match_v = matchtag("v"), match_f = matchtag("f");
|
||||
|
||||
return function parse_ws_xml_data(sdata, s, opts, guess) {
|
||||
return function parse_ws_xml_data(sdata, s, opts, guess, themes, styles) {
|
||||
var ri = 0, x = "", cells = [], cref = [], idx = 0, i=0, cc=0, d="", p/*:any*/;
|
||||
var tag, tagr = 0, tagc = 0;
|
||||
var sstr, ftag;
|
||||
@ -8572,7 +8570,7 @@ return function parse_ws_xml_data(sdata, s, opts, guess) {
|
||||
if(opts.cellStyles && cf.fillId != null) fillid = cf.fillId;
|
||||
}
|
||||
}
|
||||
safe_format(p, fmtid, fillid, opts);
|
||||
safe_format(p, fmtid, fillid, opts, themes, styles);
|
||||
s[tag.r] = p;
|
||||
}
|
||||
}
|
||||
@ -8878,7 +8876,7 @@ function parse_BrtShrFmla(data, length, opts) {
|
||||
}
|
||||
|
||||
/* [MS-XLSB] 2.1.7.61 Worksheet */
|
||||
function parse_ws_bin(data, opts, rels, wb)/*:Worksheet*/ {
|
||||
function parse_ws_bin(data, opts, rels, wb, themes, styles)/*:Worksheet*/ {
|
||||
if(!data) return data;
|
||||
if(!rels) rels = {'!id':{}};
|
||||
var s = {};
|
||||
@ -8933,7 +8931,7 @@ function parse_ws_bin(data, opts, rels, wb)/*:Worksheet*/ {
|
||||
case 'e': p.v = val[1]; p.w = BErr[p.v]; break;
|
||||
case 'str': p.t = 's'; p.v = utf8read(val[1]); break;
|
||||
}
|
||||
if((cf = styles.CellXf[val[0].iStyleRef])) safe_format(p,cf.ifmt,null,opts);
|
||||
if((cf = styles.CellXf[val[0].iStyleRef])) safe_format(p,cf.ifmt,null,opts, themes, styles);
|
||||
s[encode_col(C=val[0].c) + rr] = p;
|
||||
if(opts.cellFormula) {
|
||||
af = false;
|
||||
@ -9704,9 +9702,9 @@ function parse_wb(data, name/*:string*/, opts)/*:WorkbookFile*/ {
|
||||
return parse_wb_xml((data/*:any*/), opts);
|
||||
}
|
||||
|
||||
function parse_ws(data, name/*:string*/, opts, rels, wb)/*:Worksheet*/ {
|
||||
if(name.slice(-4)===".bin") return parse_ws_bin((data/*:any*/), opts, rels, wb);
|
||||
return parse_ws_xml((data/*:any*/), opts, rels, wb);
|
||||
function parse_ws(data, name/*:string*/, opts, rels, wb, themes, styles)/*:Worksheet*/ {
|
||||
if(name.slice(-4)===".bin") return parse_ws_bin((data/*:any*/), opts, rels, wb, themes, styles);
|
||||
return parse_ws_xml((data/*:any*/), opts, rels, wb, themes, styles);
|
||||
}
|
||||
|
||||
function parse_sty(data, name/*:string*/, opts) {
|
||||
@ -10756,7 +10754,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
||||
biff: 8, // BIFF version
|
||||
codepage: 0, // CP from CodePage record
|
||||
winlocked: 0, // fLockWn from WinProtect
|
||||
wtf: false
|
||||
WTF: !!options && !!options.wtf
|
||||
}/*:any*/);
|
||||
if(options.password) opts.password = options.password;
|
||||
var mergecells = [];
|
||||
@ -12763,6 +12761,7 @@ var parse_content_xml = (function() {
|
||||
var rept = 1, isstub = false;
|
||||
var i = 0;
|
||||
xlmlregex.lastIndex = 0;
|
||||
str = str.replace(/<!--([^\u2603]*?)-->/mg,"").replace(/<!DOCTYPE[^\[]*\[[^\]]*\]>/gm,"");
|
||||
while((Rn = xlmlregex.exec(str))) switch((Rn[3]=Rn[3].replace(/_.*$/,""))) {
|
||||
|
||||
case 'table': case '工作表': // 9.1.2 <table:table>
|
||||
@ -13116,7 +13115,7 @@ var parse_content_xml = (function() {
|
||||
if(Rn[2] === 'uof:') break; // TODO: uof
|
||||
if(Rn[2] === '表:') break; // TODO: uof
|
||||
if(Rn[2] === '字:') break; // TODO: uof
|
||||
if(opts.WTF) throw Rn;
|
||||
if(opts.WTF) throw new Error(Rn);
|
||||
}
|
||||
var out = {
|
||||
Sheets: Sheets,
|
||||
@ -13296,10 +13295,10 @@ function safe_parse_wbrels(wbrels, sheets) {
|
||||
return !wbrels || wbrels.length === 0 ? null : wbrels;
|
||||
}
|
||||
|
||||
function safe_parse_ws(zip, path/*:string*/, relsPath/*:string*/, sheet, sheetRels, sheets, opts, wb) {
|
||||
function safe_parse_ws(zip, path/*:string*/, relsPath/*:string*/, sheet, sheetRels, sheets, opts, wb, themes, styles) {
|
||||
try {
|
||||
sheetRels[sheet]=parse_rels(getzipstr(zip, relsPath, true), path);
|
||||
sheets[sheet]=parse_ws(getzipdata(zip, path),path,opts,sheetRels[sheet], wb);
|
||||
sheets[sheet]=parse_ws(getzipdata(zip, path),path,opts,sheetRels[sheet], wb, themes, styles);
|
||||
} catch(e) { if(opts.WTF) throw e; }
|
||||
}
|
||||
|
||||
@ -13332,14 +13331,14 @@ function parse_zip(zip/*:ZIP*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
|
||||
if(dir.workbooks[0].slice(-3) == "bin") xlsb = true;
|
||||
if(xlsb) set_cp(1200);
|
||||
|
||||
var themes = ({}/*:any*/);
|
||||
var styles = ({}/*:any*/);
|
||||
if(!opts.bookSheets && !opts.bookProps) {
|
||||
strs = [];
|
||||
if(dir.sst) strs=parse_sst(getzipdata(zip, dir.sst.replace(/^\//,'')), dir.sst, opts);
|
||||
|
||||
styles = {};
|
||||
if(dir.style) styles = parse_sty(getzipdata(zip, dir.style.replace(/^\//,'')),dir.style, opts);
|
||||
|
||||
themes = {};
|
||||
if(opts.cellStyles && dir.themes.length) themes = parse_theme(getzipstr(zip, dir.themes[0].replace(/^\//,''), true)||"",dir.themes[0], opts);
|
||||
}
|
||||
|
||||
@ -13402,7 +13401,7 @@ function parse_zip(zip/*:ZIP*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
|
||||
path = path.replace(/sheet0\./,"sheet.");
|
||||
}
|
||||
relsPath = path.replace(/^(.*)(\/)([^\/]*)$/, "$1/_rels/$3.rels");
|
||||
safe_parse_ws(zip, path, relsPath, props.SheetNames[i], sheetRels, sheets, opts, wb);
|
||||
safe_parse_ws(zip, path, relsPath, props.SheetNames[i], sheetRels, sheets, opts, wb, themes, styles);
|
||||
}
|
||||
|
||||
if(dir.comments) parse_comments(zip, dir.comments, sheets, sheetRels, opts);
|
||||
@ -13510,7 +13509,7 @@ function write_zip(wb/*:Workbook*/, opts/*:WriteOpts*/)/*:ZIP*/ {
|
||||
/* TODO: something more intelligent with themes */
|
||||
|
||||
f = "xl/theme/theme1.xml";
|
||||
zip.file(f, write_theme());
|
||||
zip.file(f, write_theme(wb.Themes, opts));
|
||||
ct.themes.push(f);
|
||||
add_rels(opts.wbrels, ++rId, "theme/theme1.xml", RELS.THEME);
|
||||
|
||||
|
83
xlsx.js
83
xlsx.js
@ -4614,7 +4614,6 @@ var parse_rs = (function parse_rs_factory() {
|
||||
if(y[0].charCodeAt(1) !== 47) throw 'Unrecognized rich format ' + y[0];
|
||||
}
|
||||
}
|
||||
/* TODO: These should be generated styles, not inline */
|
||||
var style = [];
|
||||
if(font.b) style.push("font-weight: bold;");
|
||||
if(font.i) style.push("font-style: italic;");
|
||||
@ -5020,12 +5019,8 @@ var XLMLPatternTypeMap = {
|
||||
"ThinHorzCross": "lightGrid"
|
||||
};
|
||||
|
||||
var styles = {}; // shared styles
|
||||
|
||||
var themes = {}; // shared themes
|
||||
|
||||
/* 18.8.21 fills CT_Fills */
|
||||
function parse_fills(t, opts) {
|
||||
function parse_fills(t, styles, opts) {
|
||||
styles.Fills = [];
|
||||
var fill = {};
|
||||
t[0].match(tagregex).forEach(function(x) {
|
||||
@ -5065,13 +5060,13 @@ function parse_fills(t, opts) {
|
||||
break;
|
||||
case '<fgColor/>': case '</fgColor>': break;
|
||||
|
||||
default: if(opts.WTF) throw new Error('unrecognized ' + y[0] + ' in fills');
|
||||
default: if(opts && opts.WTF) throw new Error('unrecognized ' + y[0] + ' in fills');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* 18.8.31 numFmts CT_NumFmts */
|
||||
function parse_numFmts(t, opts) {
|
||||
function parse_numFmts(t, styles, opts) {
|
||||
styles.NumberFmt = [];
|
||||
var k/*Array<number>*/ = (keys(SSF._table));
|
||||
for(var i=0; i < k.length; ++i) styles.NumberFmt[k[i]] = SSF._table[k[i]];
|
||||
@ -5103,7 +5098,7 @@ function write_numFmts(NF, opts) {
|
||||
}
|
||||
|
||||
/* 18.8.10 cellXfs CT_CellXfs */
|
||||
function parse_cellXfs(t, opts) {
|
||||
function parse_cellXfs(t, styles, opts) {
|
||||
styles.CellXf = [];
|
||||
t[0].match(tagregex).forEach(function(x) {
|
||||
var y = parsexmltag(x);
|
||||
@ -5147,24 +5142,25 @@ var cellXfRegex = /<cellXfs([^>]*)>.*<\/cellXfs>/;
|
||||
var fillsRegex = /<fills([^>]*)>.*<\/fills>/;
|
||||
|
||||
return function parse_sty_xml(data, opts) {
|
||||
var styles = {};
|
||||
if(!data) return styles;
|
||||
/* 18.8.39 styleSheet CT_Stylesheet */
|
||||
var t;
|
||||
|
||||
/* numFmts CT_NumFmts ? */
|
||||
if((t=data.match(numFmtRegex))) parse_numFmts(t, opts);
|
||||
if((t=data.match(numFmtRegex))) parse_numFmts(t, styles, 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);
|
||||
if((t=data.match(fillsRegex))) parse_fills(t, styles, opts);
|
||||
|
||||
/* borders CT_Borders ? */
|
||||
/* cellStyleXfs CT_CellStyleXfs ? */
|
||||
|
||||
/* cellXfs CT_CellXfs ? */
|
||||
if((t=data.match(cellXfRegex))) parse_cellXfs(t, opts);
|
||||
if((t=data.match(cellXfRegex))) parse_cellXfs(t, styles, opts);
|
||||
|
||||
/* dxfs CT_Dxfs ? */
|
||||
/* tableStyles CT_TableStyles ? */
|
||||
@ -5241,6 +5237,7 @@ function parse_BrtXF(data, length) {
|
||||
|
||||
/* [MS-XLSB] 2.1.7.50 Styles */
|
||||
function parse_sty_bin(data, opts) {
|
||||
var styles = {};
|
||||
styles.NumberFmt = ([]);
|
||||
for(var y in SSF._table) styles.NumberFmt[y] = SSF._table[y];
|
||||
|
||||
@ -5333,7 +5330,7 @@ function write_sty_bin(data, opts) {
|
||||
RELS.THEME = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme";
|
||||
|
||||
/* 20.1.6.2 clrScheme CT_ColorScheme */
|
||||
function parse_clrScheme(t, opts) {
|
||||
function parse_clrScheme(t, themes, opts) {
|
||||
themes.themeElements.clrScheme = [];
|
||||
var color = {};
|
||||
(t[0].match(tagregex)||[]).forEach(function(x) {
|
||||
@ -5391,23 +5388,23 @@ function parse_clrScheme(t, opts) {
|
||||
}
|
||||
break;
|
||||
|
||||
default: if(opts.WTF) throw 'unrecognized ' + y[0] + ' in clrScheme';
|
||||
default: if(opts && opts.WTF) throw new Error('Unrecognized ' + y[0] + ' in clrScheme');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* 20.1.4.1.18 fontScheme CT_FontScheme */
|
||||
function parse_fontScheme(t, opts) { }
|
||||
function parse_fontScheme(t, themes, opts) { }
|
||||
|
||||
/* 20.1.4.1.15 fmtScheme CT_StyleMatrix */
|
||||
function parse_fmtScheme(t, opts) { }
|
||||
function parse_fmtScheme(t, themes, opts) { }
|
||||
|
||||
var clrsregex = /<a:clrScheme([^>]*)>[^\u2603]*<\/a:clrScheme>/;
|
||||
var fntsregex = /<a:fontScheme([^>]*)>[^\u2603]*<\/a:fontScheme>/;
|
||||
var fmtsregex = /<a:fmtScheme([^>]*)>[^\u2603]*<\/a:fmtScheme>/;
|
||||
|
||||
/* 20.1.6.10 themeElements CT_BaseStyles */
|
||||
function parse_themeElements(data, opts) {
|
||||
function parse_themeElements(data, themes, opts) {
|
||||
themes.themeElements = {};
|
||||
|
||||
var t;
|
||||
@ -5421,7 +5418,7 @@ function parse_themeElements(data, opts) {
|
||||
['fmtScheme', fmtsregex, parse_fmtScheme]
|
||||
].forEach(function(m) {
|
||||
if(!(t=data.match(m[1]))) throw new Error(m[0] + ' not found in themeElements');
|
||||
m[2](t, opts);
|
||||
m[2](t, themes, opts);
|
||||
});
|
||||
}
|
||||
|
||||
@ -5430,18 +5427,19 @@ var themeltregex = /<a:themeElements([^>]*)>[^\u2603]*<\/a:themeElements>/;
|
||||
/* 14.2.7 Theme Part */
|
||||
function parse_theme_xml(data, opts) {
|
||||
/* 20.1.6.9 theme CT_OfficeStyleSheet */
|
||||
if(!data || data.length === 0) return themes;
|
||||
if(!data || data.length === 0) return parse_theme_xml(write_theme());
|
||||
|
||||
var t;
|
||||
var themes = {};
|
||||
|
||||
/* themeElements CT_BaseStyles */
|
||||
if(!(t=data.match(themeltregex))) throw 'themeElements not found in theme';
|
||||
parse_themeElements(t[0], opts);
|
||||
parse_themeElements(t[0], themes, opts);
|
||||
|
||||
return themes;
|
||||
}
|
||||
|
||||
function write_theme() {
|
||||
function write_theme(Themes, opts) {
|
||||
var o = [XML_HEADER];
|
||||
o[o.length] = '<a:theme xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" name="Office Theme">';
|
||||
o[o.length] = '<a:themeElements>';
|
||||
@ -5596,22 +5594,22 @@ function write_theme() {
|
||||
o[o.length] = '</a:gradFill>';
|
||||
o[o.length] = '</a:bgFillStyleLst>';
|
||||
o[o.length] = '</a:fmtScheme>';
|
||||
|
||||
o[o.length] = '</a:themeElements>';
|
||||
|
||||
o[o.length] = '<a:objectDefaults>';
|
||||
o[o.length] = '<a:spDef>';
|
||||
o[o.length] = '<a:spPr/><a:bodyPr/><a:lstStyle/><a:style><a:lnRef idx="1"><a:schemeClr val="accent1"/></a:lnRef><a:fillRef idx="3"><a:schemeClr val="accent1"/></a:fillRef><a:effectRef idx="2"><a:schemeClr val="accent1"/></a:effectRef><a:fontRef idx="minor"><a:schemeClr val="lt1"/></a:fontRef></a:style>';
|
||||
o[o.length] = '</a:spDef>';
|
||||
o[o.length] = '<a:lnDef>';
|
||||
o[o.length] = '<a:spPr/><a:bodyPr/><a:lstStyle/><a:style><a:lnRef idx="2"><a:schemeClr val="accent1"/></a:lnRef><a:fillRef idx="0"><a:schemeClr val="accent1"/></a:fillRef><a:effectRef idx="1"><a:schemeClr val="accent1"/></a:effectRef><a:fontRef idx="minor"><a:schemeClr val="tx1"/></a:fontRef></a:style>';
|
||||
o[o.length] = '</a:lnDef>';
|
||||
o[o.length] = '</a:lnDef>';
|
||||
o[o.length] = '</a:objectDefaults>';
|
||||
o[o.length] = '<a:extraClrSchemeLst/>';
|
||||
o[o.length] = '</a:theme>';
|
||||
return o.join("");
|
||||
}
|
||||
/* [MS-XLS] 2.4.326 TODO: payload is a zip file */
|
||||
function parse_Theme(blob, length) {
|
||||
function parse_Theme(blob, length, opts) {
|
||||
var dwThemeVersion = blob.read_shift(4);
|
||||
if(dwThemeVersion === 124226) return;
|
||||
blob.l += length-4;
|
||||
@ -8195,7 +8193,7 @@ function get_cell_style(styles, cell, opts) {
|
||||
return len;
|
||||
}
|
||||
|
||||
function safe_format(p, fmtid, fillid, opts) {
|
||||
function safe_format(p, fmtid, fillid, opts, themes, styles) {
|
||||
if(p.t === 'z') return;
|
||||
if(p.t === 'd' && typeof p.v === 'string') p.v = new Date(p.v);
|
||||
try {
|
||||
@ -8239,7 +8237,7 @@ var hlinkregex = /<(?:\w*:)?hyperlink[^>]*\/>/g;
|
||||
var dimregex = /"(\w*:\w*)"/;
|
||||
var colregex = /<(?:\w*:)?col[^>]*\/>/g;
|
||||
/* 18.3 Worksheets */
|
||||
function parse_ws_xml(data, opts, rels) {
|
||||
function parse_ws_xml(data, opts, rels, wb, themes, styles) {
|
||||
if(!data) return data;
|
||||
/* 18.3.1.99 worksheet CT_Worksheet */
|
||||
var s = ({});
|
||||
@ -8270,7 +8268,7 @@ function parse_ws_xml(data, opts, rels) {
|
||||
|
||||
/* 18.3.1.80 sheetData CT_SheetData ? */
|
||||
var mtch=data.match(sheetdataregex);
|
||||
if(mtch) parse_ws_xml_data(mtch[1], s, opts, refguess);
|
||||
if(mtch) parse_ws_xml_data(mtch[1], s, opts, refguess, themes, styles);
|
||||
|
||||
/* 18.3.1.48 hyperlinks CT_Hyperlinks */
|
||||
var hlink = data.match(hlinkregex);
|
||||
@ -8404,7 +8402,7 @@ var parse_ws_xml_data = (function parse_ws_xml_data_factory() {
|
||||
var refregex = /ref=["']([^"']*)["']/;
|
||||
var match_v = matchtag("v"), match_f = matchtag("f");
|
||||
|
||||
return function parse_ws_xml_data(sdata, s, opts, guess) {
|
||||
return function parse_ws_xml_data(sdata, s, opts, guess, themes, styles) {
|
||||
var ri = 0, x = "", cells = [], cref = [], idx = 0, i=0, cc=0, d="", p;
|
||||
var tag, tagr = 0, tagc = 0;
|
||||
var sstr, ftag;
|
||||
@ -8519,7 +8517,7 @@ return function parse_ws_xml_data(sdata, s, opts, guess) {
|
||||
if(opts.cellStyles && cf.fillId != null) fillid = cf.fillId;
|
||||
}
|
||||
}
|
||||
safe_format(p, fmtid, fillid, opts);
|
||||
safe_format(p, fmtid, fillid, opts, themes, styles);
|
||||
s[tag.r] = p;
|
||||
}
|
||||
}
|
||||
@ -8825,7 +8823,7 @@ function parse_BrtShrFmla(data, length, opts) {
|
||||
}
|
||||
|
||||
/* [MS-XLSB] 2.1.7.61 Worksheet */
|
||||
function parse_ws_bin(data, opts, rels, wb) {
|
||||
function parse_ws_bin(data, opts, rels, wb, themes, styles) {
|
||||
if(!data) return data;
|
||||
if(!rels) rels = {'!id':{}};
|
||||
var s = {};
|
||||
@ -8880,7 +8878,7 @@ function parse_ws_bin(data, opts, rels, wb) {
|
||||
case 'e': p.v = val[1]; p.w = BErr[p.v]; break;
|
||||
case 'str': p.t = 's'; p.v = utf8read(val[1]); break;
|
||||
}
|
||||
if((cf = styles.CellXf[val[0].iStyleRef])) safe_format(p,cf.ifmt,null,opts);
|
||||
if((cf = styles.CellXf[val[0].iStyleRef])) safe_format(p,cf.ifmt,null,opts, themes, styles);
|
||||
s[encode_col(C=val[0].c) + rr] = p;
|
||||
if(opts.cellFormula) {
|
||||
af = false;
|
||||
@ -9651,9 +9649,9 @@ function parse_wb(data, name, opts) {
|
||||
return parse_wb_xml((data), opts);
|
||||
}
|
||||
|
||||
function parse_ws(data, name, opts, rels, wb) {
|
||||
if(name.slice(-4)===".bin") return parse_ws_bin((data), opts, rels, wb);
|
||||
return parse_ws_xml((data), opts, rels, wb);
|
||||
function parse_ws(data, name, opts, rels, wb, themes, styles) {
|
||||
if(name.slice(-4)===".bin") return parse_ws_bin((data), opts, rels, wb, themes, styles);
|
||||
return parse_ws_xml((data), opts, rels, wb, themes, styles);
|
||||
}
|
||||
|
||||
function parse_sty(data, name, opts) {
|
||||
@ -10699,7 +10697,7 @@ function parse_workbook(blob, options) {
|
||||
biff: 8, // BIFF version
|
||||
codepage: 0, // CP from CodePage record
|
||||
winlocked: 0, // fLockWn from WinProtect
|
||||
wtf: false
|
||||
WTF: !!options && !!options.wtf
|
||||
});
|
||||
if(options.password) opts.password = options.password;
|
||||
var mergecells = [];
|
||||
@ -12706,6 +12704,7 @@ var parse_content_xml = (function() {
|
||||
var rept = 1, isstub = false;
|
||||
var i = 0;
|
||||
xlmlregex.lastIndex = 0;
|
||||
str = str.replace(/<!--([^\u2603]*?)-->/mg,"").replace(/<!DOCTYPE[^\[]*\[[^\]]*\]>/gm,"");
|
||||
while((Rn = xlmlregex.exec(str))) switch((Rn[3]=Rn[3].replace(/_.*$/,""))) {
|
||||
|
||||
case 'table': case '工作表': // 9.1.2 <table:table>
|
||||
@ -13059,7 +13058,7 @@ var parse_content_xml = (function() {
|
||||
if(Rn[2] === 'uof:') break; // TODO: uof
|
||||
if(Rn[2] === '表:') break; // TODO: uof
|
||||
if(Rn[2] === '字:') break; // TODO: uof
|
||||
if(opts.WTF) throw Rn;
|
||||
if(opts.WTF) throw new Error(Rn);
|
||||
}
|
||||
var out = {
|
||||
Sheets: Sheets,
|
||||
@ -13238,10 +13237,10 @@ function safe_parse_wbrels(wbrels, sheets) {
|
||||
return !wbrels || wbrels.length === 0 ? null : wbrels;
|
||||
}
|
||||
|
||||
function safe_parse_ws(zip, path, relsPath, sheet, sheetRels, sheets, opts, wb) {
|
||||
function safe_parse_ws(zip, path, relsPath, sheet, sheetRels, sheets, opts, wb, themes, styles) {
|
||||
try {
|
||||
sheetRels[sheet]=parse_rels(getzipstr(zip, relsPath, true), path);
|
||||
sheets[sheet]=parse_ws(getzipdata(zip, path),path,opts,sheetRels[sheet], wb);
|
||||
sheets[sheet]=parse_ws(getzipdata(zip, path),path,opts,sheetRels[sheet], wb, themes, styles);
|
||||
} catch(e) { if(opts.WTF) throw e; }
|
||||
}
|
||||
|
||||
@ -13274,14 +13273,14 @@ function parse_zip(zip, opts) {
|
||||
if(dir.workbooks[0].slice(-3) == "bin") xlsb = true;
|
||||
if(xlsb) set_cp(1200);
|
||||
|
||||
var themes = ({});
|
||||
var styles = ({});
|
||||
if(!opts.bookSheets && !opts.bookProps) {
|
||||
strs = [];
|
||||
if(dir.sst) strs=parse_sst(getzipdata(zip, dir.sst.replace(/^\//,'')), dir.sst, opts);
|
||||
|
||||
styles = {};
|
||||
if(dir.style) styles = parse_sty(getzipdata(zip, dir.style.replace(/^\//,'')),dir.style, opts);
|
||||
|
||||
themes = {};
|
||||
if(opts.cellStyles && dir.themes.length) themes = parse_theme(getzipstr(zip, dir.themes[0].replace(/^\//,''), true)||"",dir.themes[0], opts);
|
||||
}
|
||||
|
||||
@ -13344,7 +13343,7 @@ function parse_zip(zip, opts) {
|
||||
path = path.replace(/sheet0\./,"sheet.");
|
||||
}
|
||||
relsPath = path.replace(/^(.*)(\/)([^\/]*)$/, "$1/_rels/$3.rels");
|
||||
safe_parse_ws(zip, path, relsPath, props.SheetNames[i], sheetRels, sheets, opts, wb);
|
||||
safe_parse_ws(zip, path, relsPath, props.SheetNames[i], sheetRels, sheets, opts, wb, themes, styles);
|
||||
}
|
||||
|
||||
if(dir.comments) parse_comments(zip, dir.comments, sheets, sheetRels, opts);
|
||||
@ -13450,7 +13449,7 @@ f = "docProps/app.xml";
|
||||
/* TODO: something more intelligent with themes */
|
||||
|
||||
f = "xl/theme/theme1.xml";
|
||||
zip.file(f, write_theme());
|
||||
zip.file(f, write_theme(wb.Themes, opts));
|
||||
ct.themes.push(f);
|
||||
add_rels(opts.wbrels, ++rId, "theme/theme1.xml", RELS.THEME);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user