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