Skip to content

Commit 83ddb4c

Browse files
committed
unified autofilter defined name sync on export
1 parent 5d18f82 commit 83ddb4c

32 files changed

+510
-508
lines changed

bits/27_csfutils.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,17 @@ function encode_range(cs/*:CellAddrSpec|Range*/,ce/*:?CellAddrSpec*/)/*:string*/
4444
/*:: if(typeof ce !== 'string') throw "unreachable"; */
4545
return cs == ce ? cs : cs + ":" + ce;
4646
}
47+
function fix_range(a1/*:string*/)/*:string*/ {
48+
var s = decode_range(a1);
49+
return "$" + encode_col(s.s.c) + "$" + encode_row(s.s.r) + ":$" + encode_col(s.e.c) + "$" + encode_row(s.e.r);
50+
}
51+
52+
// List of invalid characters needs to be tested further
53+
function formula_quote_sheet_name(sname/*:string*/, opts)/*:string*/ {
54+
if(!sname && !(opts && opts.biff <= 5 && opts.biff >= 2)) throw new Error("empty sheet name");
55+
if (/[^\w\u4E00-\u9FFF\u3040-\u30FF]/.test(sname)) return "'" + sname.replace(/'/g, "''") + "'";
56+
return sname;
57+
}
4758

4859
function safe_decode_range(range/*:string*/)/*:Range*/ {
4960
var o = {s:{c:0,r:0},e:{c:0,r:0}};

bits/29_xlsenum.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,3 +304,20 @@ var RBErr = {
304304
"#WTF?": 0xFF
305305
};
306306

307+
var XLSLblBuiltIn = [
308+
"_xlnm.Consolidate_Area",
309+
"_xlnm.Auto_Open",
310+
"_xlnm.Auto_Close",
311+
"_xlnm.Extract",
312+
"_xlnm.Database",
313+
"_xlnm.Criteria",
314+
"_xlnm.Print_Area",
315+
"_xlnm.Print_Titles",
316+
"_xlnm.Recorder",
317+
"_xlnm.Data_Form",
318+
"_xlnm.Auto_Activate",
319+
"_xlnm.Auto_Deactivate",
320+
"_xlnm.Sheet_Title",
321+
"_xlnm._FilterDatabase"
322+
];
323+

bits/39_xlsbiff.js

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -669,22 +669,6 @@ function parse_ExternName(blob, length, opts) {
669669
}
670670

671671
/* [MS-XLS] 2.4.150 TODO */
672-
var XLSLblBuiltIn = [
673-
"_xlnm.Consolidate_Area",
674-
"_xlnm.Auto_Open",
675-
"_xlnm.Auto_Close",
676-
"_xlnm.Extract",
677-
"_xlnm.Database",
678-
"_xlnm.Criteria",
679-
"_xlnm.Print_Area",
680-
"_xlnm.Print_Titles",
681-
"_xlnm.Recorder",
682-
"_xlnm.Data_Form",
683-
"_xlnm.Auto_Activate",
684-
"_xlnm.Auto_Deactivate",
685-
"_xlnm.Sheet_Title",
686-
"_xlnm._FilterDatabase"
687-
];
688672
function parse_Lbl(blob, length, opts) {
689673
var target = blob.l + length;
690674
var flags = blob.read_shift(2);

bits/61_fcommon.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ var a1_to_rc = /*#__PURE__*/(function(){
2929
return fstr.replace(crefregex, function($0, $1, $2, $3, $4, $5) {
3030
var c = decode_col($3) - ($2 ? 0 : base.c);
3131
var r = decode_row($5) - ($4 ? 0 : base.r);
32-
var R = (r == 0 ? "" : !$4 ? "[" + r + "]" : (r+1));
33-
var C = (c == 0 ? "" : !$2 ? "[" + c + "]" : (c+1));
32+
var R = $4 == "$" ? (r+1) : (r == 0 ? "" : "[" + r + "]");
33+
var C = $2 == "$" ? (c+1) : (c == 0 ? "" : "[" + c + "]");
3434
return $1 + "R" + R + "C" + C;
3535
});
3636
};

bits/62_fxls.js

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -697,12 +697,6 @@ function make_3d_range(start, end) {
697697
return start + ":" + end;
698698
}
699699

700-
// List of invalid characters needs to be tested further
701-
function formula_quote_sheet_name(sname/*:string*/, opts)/*:string*/ {
702-
if(!sname && !(opts && opts.biff <= 5 && opts.biff >= 2)) throw new Error("empty sheet name");
703-
if (/[^\w\u4E00-\u9FFF\u3040-\u30FF]/.test(sname)) return "'" + sname + "'";
704-
return sname;
705-
}
706700
function get_ixti_raw(supbooks, ixti/*:number*/, opts)/*:string*/ {
707701
if(!supbooks) return "SH33TJSERR0";
708702
if(opts.biff > 8 && (!supbooks.XTI || !supbooks.XTI[ixti])) return supbooks.SheetNames[ixti];

bits/67_wsxml.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ function write_ws_xml_autofilter(data, ws, wb, idx)/*:string*/ {
228228
var name = names[i];
229229
if(name.Name != '_xlnm._FilterDatabase') continue;
230230
if(name.Sheet != idx) continue;
231-
name.Ref = "'" + wb.SheetNames[idx] + "'!" + ref; break;
231+
name.Ref = formula_quote_sheet_name(wb.SheetNames[idx]) + "!" + fix_range(ref); break;
232232
}
233233
if(i == names.length) names.push({ Name: '_xlnm._FilterDatabase', Sheet: idx, Ref: "'" + wb.SheetNames[idx] + "'!" + ref });
234234
return writextag("autoFilter", null, {ref:ref});

bits/68_wsbin.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -938,9 +938,9 @@ function write_AUTOFILTER(ba, ws, wb, idx) {
938938
var name = names[i];
939939
if(name.Name != '_xlnm._FilterDatabase') continue;
940940
if(name.Sheet != idx) continue;
941-
name.Ref = "'" + wb.SheetNames[idx] + "'!" + ref; break;
941+
name.Ref = formula_quote_sheet_name(wb.SheetNames[idx]) + "!" + fix_range(ref); break;
942942
}
943-
if(i == names.length) names.push({ Name: '_xlnm._FilterDatabase', Sheet: idx, Ref: "'" + wb.SheetNames[idx] + "'!" + ref });
943+
if(i == names.length) names.push({ Name: '_xlnm._FilterDatabase', Sheet: idx, Ref: formula_quote_sheet_name(wb.SheetNames[idx]) + "!" + fix_range(ref) });
944944

945945
write_record(ba, 0x00A1 /* BrtBeginAFilter */, write_UncheckedRfX(safe_decode_range(ref)));
946946
/* *FILTERCOLUMN */

bits/71_wbcommon.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,5 +140,16 @@ function check_wb(wb) {
140140
var Sheets = (wb.Workbook && wb.Workbook.Sheets) || [];
141141
check_wb_names(wb.SheetNames, Sheets, !!wb.vbaraw);
142142
for(var i = 0; i < wb.SheetNames.length; ++i) check_ws(wb.Sheets[wb.SheetNames[i]], wb.SheetNames[i], i);
143+
wb.SheetNames.forEach(function(n, i) {
144+
var ws = wb.Sheets[n];
145+
if(!ws || !ws["!autofilter"]) return;
146+
var DN;
147+
if(!wb.Workbook) wb.Workbook = {};
148+
if(!wb.Workbook.Names) wb.Workbook.Names = [];
149+
wb.Workbook.Names.forEach(function(dn) { if(dn.Name == "_xlnm._FilterDatabase" && dn.Sheet == i) DN = dn; });
150+
var nn = formula_quote_sheet_name(n) + "!" + fix_range(ws["!autofilter"].ref);
151+
if(DN) DN.Ref = nn;
152+
else wb.Workbook.Names.push({Name: "_xlnm._FilterDatabase", Sheet: i, Ref: nn});
153+
});
143154
/* TODO: validate workbook */
144155
}

bits/75_xlml.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,10 @@ function parse_xlml_data(xml, ss, data, cell/*:any*/, base, styles, csty, row, a
159159
if(cell.StyleID !== undefined) cell.ixfe = cell.StyleID;
160160
}
161161

162+
function xlml_prefix_dname(dname) {
163+
return XLSLblBuiltIn.indexOf("_xlnm." + dname) > -1 ? "_xlnm." + dname : dname;
164+
}
165+
162166
function xlml_clean_comment(comment/*:any*/) {
163167
comment.t = comment.v || "";
164168
comment.t = comment.t.replace(/\r\n/g,"\n").replace(/\r/g,"\n");
@@ -366,7 +370,7 @@ function parse_xlml_xml(d, _opts)/*:Workbook*/ {
366370
if(!Workbook.Names) Workbook.Names = [];
367371
var _NamedRange = parsexmltag(Rn[0]);
368372
var _DefinedName/*:DefinedName*/ = ({
369-
Name: _NamedRange.Name,
373+
Name: xlml_prefix_dname(_NamedRange.Name),
370374
Ref: rc_to_a1(_NamedRange.RefersTo.slice(1), {r:0, c:0})
371375
}/*:any*/);
372376
if(Workbook.Sheets.length>0) _DefinedName.Sheet=Workbook.Sheets.length-1;
@@ -956,7 +960,7 @@ function write_sty_xlml(wb, opts)/*:string*/ {
956960
});
957961
return writextag("Styles", styles.join(""));
958962
}
959-
function write_name_xlml(n) { return writextag("NamedRange", null, {"ss:Name": n.Name, "ss:RefersTo":"=" + a1_to_rc(n.Ref, {r:0,c:0})}); }
963+
function write_name_xlml(n) { return writextag("NamedRange", null, {"ss:Name": n.Name.slice(0,6) == "_xlnm." ? n.Name.slice(6) : n.Name, "ss:RefersTo":"=" + a1_to_rc(n.Ref, {r:0,c:0})}); }
960964
function write_names_xlml(wb/*::, opts*/)/*:string*/ {
961965
if(!((wb||{}).Workbook||{}).Names) return "";
962966
/*:: if(!wb || !wb.Workbook || !wb.Workbook.Names) throw new Error("unreachable"); */
@@ -1209,6 +1213,8 @@ function write_ws_xlml(idx/*:number*/, opts, wb/*:Workbook*/)/*:string*/ {
12091213
/* WorksheetOptions */
12101214
o.push(write_ws_xlml_wsopts(ws, opts, idx, wb));
12111215

1216+
if(ws["!autofilter"]) o.push('<AutoFilter x:Range="' + a1_to_rc(fix_range(ws["!autofilter"].ref), {r:0,c:0}) + '" xmlns="urn:schemas-microsoft-com:office:excel"></AutoFilter>');
1217+
12121218
return o.join("");
12131219
}
12141220
function write_xlml(wb, opts)/*:string*/ {

demos/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ can be installed with Bash on Windows or with `cygwin`.
4444
- [`nw.js application`](nwjs/)
4545
- [`Chrome / Chromium extensions`](chrome/)
4646
- [`Google Sheets API`](https://docs.sheetjs.com/docs/getting-started/demos/gsheet)
47-
- [`Adobe ExtendScript`](extendscript/)
47+
- [`Adobe Apps`](https://docs.sheetjs.com/docs/getting-started/demos/extendscript)
4848
- [`Headless Browsers`](headless/)
4949
- [`canvas-datagrid`](datagrid/)
5050
- [`x-spreadsheet`](xspreadsheet/)

0 commit comments

Comments
 (0)