forked from sheetjs/sheetjs
XLSX write Sheet Protection
fixes #363 h/t @Mior note: @sheetjsdev rewrote implementation, original PR author used
This commit is contained in:
parent
6a3afe56c2
commit
d086dbecbf
22
README.md
22
README.md
@ -574,6 +574,28 @@ In addition to the base sheet keys, worksheets also add:
|
||||
will write all cells in the merge range if they exist, so be sure that only
|
||||
the first cell (upper-left) in the range is set.
|
||||
|
||||
- `ws['protect']`: object of write sheet protection properties. The `password`
|
||||
key specifies the password. The writer uses the XOR obfuscation method. The
|
||||
following keys control the sheet protection (same as ECMA-376 18.3.1.85):
|
||||
|
||||
| key | functionality disabled if value is true |
|
||||
|:----------------------|:-----------------------------------------------------|
|
||||
| `selectLockedCells` | Select locked cells |
|
||||
| `selectUnlockedCells` | Select unlocked cells |
|
||||
| `formatCells` | Format cells |
|
||||
| `formatColumns` | Format columns |
|
||||
| `formatRows` | Format rows |
|
||||
| `insertColumns` | Insert columns |
|
||||
| `insertRows` | Insert rows |
|
||||
| `insertHyperlinks` | Insert hyperlinks |
|
||||
| `deleteColumns` | Delete columns |
|
||||
| `deleteRows` | Delete rows |
|
||||
| `sort` | Sort |
|
||||
| `autoFilter` | Filter |
|
||||
| `pivotTables` | Use PivotTable reports |
|
||||
| `objects` | Edit objects |
|
||||
| `scenarios` | Edit scenarios |
|
||||
|
||||
#### Chartsheet Object
|
||||
|
||||
Chartsheets are represented as standard sheets. They are distinguished with the
|
||||
|
@ -70,6 +70,24 @@ function write_ws_xml_merges(merges) {
|
||||
return o + '</mergeCells>';
|
||||
}
|
||||
|
||||
/* 18.3.1.85 sheetPr CT_SheetProtection */
|
||||
function write_ws_xml_protection(sp)/*:string*/ {
|
||||
// algorithmName, hashValue, saltValue, spinCountpassword
|
||||
var o = ({sheet:1}/*:any*/);
|
||||
var deffalse = ["objects", "scenarios", "selectLockedCells", "selectUnlockedCells"];
|
||||
var deftrue = [
|
||||
"formatColumns", "formatRows", "formatCells",
|
||||
"insertColumns", "insertRows", "insertHyperlinks",
|
||||
"deleteColumns", "deleteRows",
|
||||
"sort", "autoFilter", "pivotTables"
|
||||
];
|
||||
deffalse.forEach(function(n) { if(sp[n] != null && sp[n]) o[n] = "1"; });
|
||||
deftrue.forEach(function(n) { if(sp[n] != null && !sp[n]) o[n] = "0"; });
|
||||
/* TODO: algorithm */
|
||||
if(sp.password) o.password = crypto_CreatePasswordVerifier_Method1(sp.password).toString(16).toUpperCase();
|
||||
return writextag('sheetProtection', null, o);
|
||||
}
|
||||
|
||||
function parse_ws_xml_hlinks(s, data/*:Array<string>*/, rels) {
|
||||
for(var i = 0; i != data.length; ++i) {
|
||||
var val = parsexmltag(data[i], true);
|
||||
@ -348,6 +366,8 @@ function write_ws_xml(idx/*:number*/, opts, wb/*:Workbook*/, rels)/*:string*/ {
|
||||
}
|
||||
if(o.length>sidx+1) { o[o.length] = ('</sheetData>'); o[sidx]=o[sidx].replace("/>",">"); }
|
||||
|
||||
if(ws['!protect'] != null) o[o.length] = write_ws_xml_protection(ws['!protect']);
|
||||
|
||||
if(ws['!merges'] != null && ws['!merges'].length > 0) o[o.length] = (write_ws_xml_merges(ws['!merges']));
|
||||
|
||||
var relc = -1, rel, rId = -1;
|
||||
|
@ -13,6 +13,28 @@ In addition to the base sheet keys, worksheets also add:
|
||||
will write all cells in the merge range if they exist, so be sure that only
|
||||
the first cell (upper-left) in the range is set.
|
||||
|
||||
- `ws['protect']`: object of write sheet protection properties. The `password`
|
||||
key specifies the password. The writer uses the XOR obfuscation method. The
|
||||
following keys control the sheet protection (same as ECMA-376 18.3.1.85):
|
||||
|
||||
| key | functionality disabled if value is true |
|
||||
|:----------------------|:-----------------------------------------------------|
|
||||
| `selectLockedCells` | Select locked cells |
|
||||
| `selectUnlockedCells` | Select unlocked cells |
|
||||
| `formatCells` | Format cells |
|
||||
| `formatColumns` | Format columns |
|
||||
| `formatRows` | Format rows |
|
||||
| `insertColumns` | Insert columns |
|
||||
| `insertRows` | Insert rows |
|
||||
| `insertHyperlinks` | Insert hyperlinks |
|
||||
| `deleteColumns` | Delete columns |
|
||||
| `deleteRows` | Delete rows |
|
||||
| `sort` | Sort |
|
||||
| `autoFilter` | Filter |
|
||||
| `pivotTables` | Use PivotTable reports |
|
||||
| `objects` | Edit objects |
|
||||
| `scenarios` | Edit scenarios |
|
||||
|
||||
#### Chartsheet Object
|
||||
|
||||
Chartsheets are represented as standard sheets. They are distinguished with the
|
||||
|
@ -102,6 +102,13 @@ wb.Props = {
|
||||
ws['A4'].c = [];
|
||||
ws['A4'].c.push({a:"SheetJS",t:"I'm a little comment, short and stout!\n\nWell, Stout may be the wrong word"});
|
||||
|
||||
/* TEST: sheet protection */
|
||||
ws['!protect'] = {
|
||||
password:"password",
|
||||
objects:1,
|
||||
scenarios:1
|
||||
};
|
||||
|
||||
console.log("Worksheet Model:")
|
||||
console.log(ws);
|
||||
|
||||
|
20
xlsx.flow.js
20
xlsx.flow.js
@ -9715,6 +9715,24 @@ function write_ws_xml_merges(merges) {
|
||||
return o + '</mergeCells>';
|
||||
}
|
||||
|
||||
/* 18.3.1.85 sheetPr CT_SheetProtection */
|
||||
function write_ws_xml_protection(sp)/*:string*/ {
|
||||
// algorithmName, hashValue, saltValue, spinCountpassword
|
||||
var o = ({sheet:1}/*:any*/);
|
||||
var deffalse = ["objects", "scenarios", "selectLockedCells", "selectUnlockedCells"];
|
||||
var deftrue = [
|
||||
"formatColumns", "formatRows", "formatCells",
|
||||
"insertColumns", "insertRows", "insertHyperlinks",
|
||||
"deleteColumns", "deleteRows",
|
||||
"sort", "autoFilter", "pivotTables"
|
||||
];
|
||||
deffalse.forEach(function(n) { if(sp[n] != null && sp[n]) o[n] = "1"; });
|
||||
deftrue.forEach(function(n) { if(sp[n] != null && !sp[n]) o[n] = "0"; });
|
||||
/* TODO: algorithm */
|
||||
if(sp.password) o.password = crypto_CreatePasswordVerifier_Method1(sp.password).toString(16).toUpperCase();
|
||||
return writextag('sheetProtection', null, o);
|
||||
}
|
||||
|
||||
function parse_ws_xml_hlinks(s, data/*:Array<string>*/, rels) {
|
||||
for(var i = 0; i != data.length; ++i) {
|
||||
var val = parsexmltag(data[i], true);
|
||||
@ -9993,6 +10011,8 @@ function write_ws_xml(idx/*:number*/, opts, wb/*:Workbook*/, rels)/*:string*/ {
|
||||
}
|
||||
if(o.length>sidx+1) { o[o.length] = ('</sheetData>'); o[sidx]=o[sidx].replace("/>",">"); }
|
||||
|
||||
if(ws['!protect'] != null) o[o.length] = write_ws_xml_protection(ws['!protect']);
|
||||
|
||||
if(ws['!merges'] != null && ws['!merges'].length > 0) o[o.length] = (write_ws_xml_merges(ws['!merges']));
|
||||
|
||||
var relc = -1, rel, rId = -1;
|
||||
|
20
xlsx.js
20
xlsx.js
@ -9658,6 +9658,24 @@ function write_ws_xml_merges(merges) {
|
||||
return o + '</mergeCells>';
|
||||
}
|
||||
|
||||
/* 18.3.1.85 sheetPr CT_SheetProtection */
|
||||
function write_ws_xml_protection(sp) {
|
||||
// algorithmName, hashValue, saltValue, spinCountpassword
|
||||
var o = ({sheet:1});
|
||||
var deffalse = ["objects", "scenarios", "selectLockedCells", "selectUnlockedCells"];
|
||||
var deftrue = [
|
||||
"formatColumns", "formatRows", "formatCells",
|
||||
"insertColumns", "insertRows", "insertHyperlinks",
|
||||
"deleteColumns", "deleteRows",
|
||||
"sort", "autoFilter", "pivotTables"
|
||||
];
|
||||
deffalse.forEach(function(n) { if(sp[n] != null && sp[n]) o[n] = "1"; });
|
||||
deftrue.forEach(function(n) { if(sp[n] != null && !sp[n]) o[n] = "0"; });
|
||||
/* TODO: algorithm */
|
||||
if(sp.password) o.password = crypto_CreatePasswordVerifier_Method1(sp.password).toString(16).toUpperCase();
|
||||
return writextag('sheetProtection', null, o);
|
||||
}
|
||||
|
||||
function parse_ws_xml_hlinks(s, data, rels) {
|
||||
for(var i = 0; i != data.length; ++i) {
|
||||
var val = parsexmltag(data[i], true);
|
||||
@ -9936,6 +9954,8 @@ function write_ws_xml(idx, opts, wb, rels) {
|
||||
}
|
||||
if(o.length>sidx+1) { o[o.length] = ('</sheetData>'); o[sidx]=o[sidx].replace("/>",">"); }
|
||||
|
||||
if(ws['!protect'] != null) o[o.length] = write_ws_xml_protection(ws['!protect']);
|
||||
|
||||
if(ws['!merges'] != null && ws['!merges'].length > 0) o[o.length] = (write_ws_xml_merges(ws['!merges']));
|
||||
|
||||
var relc = -1, rel, rId = -1;
|
||||
|
Loading…
Reference in New Issue
Block a user