@@ -4,7 +4,6 @@ var RelationshipManager = require("./RelationshipManager");
44/**
55 * This module represents an excel worksheet in its basic form - no tables, charts, etc. Its purpose is
66 * to hold data, the data's link to how it should be styled, and any links to other outside resources.
7- * @module Excel/Worksheet
87 */
98var Worksheet = /** @class */ ( function ( ) {
109 /**
@@ -23,20 +22,13 @@ var Worksheet = /** @class */ (function () {
2322 this . _orientation = null ;
2423 this . _margin = null ;
2524 this . sharedStrings = { strings : { } } ;
26- // A two dimensional array of objects with custom XML attributes to add this worksheet's cells
27- // for example an object { style: 12b } at index [1][2] would add a {@code style="12b"} attribute to cell 'C2'
2825 this . customCellAttributes = [ ] ;
29- // A one dimensional array with the same purpose as the custom cell attributes array except the custom
30- // attributes are applied to the worksheet's rows
3126 this . customRowAttributes = [ ] ;
32- // The ID and settings for pageMargins and pageSetup
3327 this . _printerSettings ;
34- // An array of attributes to apply to the 'pageMargins' element of the spreadsheet
3528 this . pageMargins = null ;
36- // An array of attributes (only "ref" Ex: "A1:D1" for now) to apply to the autoFilter element of the spreadsheet
3729 this . autoFilter = null ;
38- // An array of attributes to apply to the 'pageSetup' element of the spreadsheet
3930 this . pageSetup = null ;
31+ this . dataValidations = null ;
4032 var cfg = ( config != null ? config : { } ) ;
4133 this . name = cfg . name ;
4234 this . id = Util . _uniqueId ( "Worksheet" ) ;
@@ -82,17 +74,23 @@ var Worksheet = /** @class */ (function () {
8274 this . _drawings . push ( table ) ;
8375 this . relations . addRelation ( table , "drawingRelationship" ) ;
8476 } ;
85- Worksheet . prototype . addPagePrintSetup = function ( pageSetup , pageMargins , autoFilter ) {
77+ //public addPagePrintSetup() {
78+ // this._printerSettings = { id: Util.uniqueId('PrinterSettings') };
79+ // this.relations.addRelation(this._printerSettings, 'printerSettings');
80+ //}
81+ Worksheet . prototype . setAutoFilter = function ( autoFilter ) {
82+ this . autoFilter = autoFilter ;
83+ } ;
84+ Worksheet . prototype . setDataValidations = function ( dataValidations ) {
85+ this . dataValidations = dataValidations ;
86+ } ;
87+ Worksheet . prototype . setPageSetupAndMargins = function ( pageSetup , pageMargins ) {
8688 this . pageSetup = pageSetup ;
8789 this . pageMargins = pageMargins ;
88- this . autoFilter = autoFilter ;
89- //this._printerSettings = { id: _.uniqueId('PrinterSettings') };
90- //this.relations.addRelation(this._printerSettings, 'printerSettings');
9190 } ;
9291 /** Expects an array length of three.
93- * @see Excel/Worksheet compilePageDetailPiece
92+ * @see compilePageDetailPiece()
9493 * @see <a href='/cookbook/addingHeadersAndFooters.html'>Adding headers and footers to a worksheet</a>
95- *
9694 * @param headers [left, center, right]
9795 */
9896 Worksheet . prototype . setHeader = function ( headers ) {
@@ -102,9 +100,8 @@ var Worksheet = /** @class */ (function () {
102100 this . _headers = headers ;
103101 } ;
104102 /** Expects an array length of three.
105- * @see Excel/Worksheet compilePageDetailPiece
103+ * @see compilePageDetailPiece()
106104 * @see <a href='/cookbook/addingHeadersAndFooters.html'>Adding headers and footers to a worksheet</a>
107- *
108105 * @param footers [left, center, right]
109106 */
110107 Worksheet . prototype . setFooter = function ( footers ) {
@@ -125,9 +122,7 @@ var Worksheet = /** @class */ (function () {
125122 "&R" , this . compilePageDetailPiece ( pieces [ 2 ] || "" )
126123 ] . join ( '' ) ;
127124 } ;
128- /** Turns instructions on page header/footer details into something
129- * usable by Excel.
130- *
125+ /** Turns instructions on page header/footer details into something usable by Excel.
131126 * @param piece
132127 * @returns string | reduce
133128 */
@@ -185,8 +180,6 @@ var Worksheet = /** @class */ (function () {
185180 /** This creates some nodes ahead of time, which cuts down on generation time due to
186181 * most cell definitions being essentially the same, but having multiple nodes that need
187182 * to be created. Cloning takes less time than creation.
188- *
189- * @private
190183 * @param doc XmlDom
191184 * @returns
192185 */
@@ -213,30 +206,29 @@ var Worksheet = /** @class */ (function () {
213206 } ;
214207 /** Runs through the XML document and grabs all of the strings that will
215208 * be sent to the 'shared strings' document.
216- *
217- * @returns
209+ * @returns list of cell 'value' strings with 'metadata.type' equal to 'text'
218210 */
219211 Worksheet . prototype . collectSharedStrings = function ( ) {
220212 var data = this . data ;
221213 var maxX = 0 ;
222214 var strings = { } ;
223- for ( var row = 0 , l = data . length ; row < l ; row ++ ) {
224- var dataRow = data [ row ] ;
225- var cellCount = dataRow . length ;
226- maxX = cellCount > maxX ? cellCount : maxX ;
227- for ( var c = 0 ; c < cellCount ; c ++ ) {
228- var cellValue = dataRow [ c ] ;
229- if ( typeof dataRow [ c ] == "object" ) {
230- cellValue = dataRow [ c ] . value ;
215+ for ( var r = 0 , dLen = data . length ; r < dLen ; r ++ ) {
216+ var row = data [ r ] ;
217+ var rLen = row . length ;
218+ maxX = rLen > maxX ? rLen : maxX ;
219+ for ( var c = 0 ; c < rLen ; c ++ ) {
220+ var cellValue = row [ c ] ;
221+ if ( typeof row [ c ] = == "object" ) {
222+ cellValue = row [ c ] . value ;
231223 }
232- var metadata = dataRow [ c ] . metadata || { } ;
224+ var metadata = row [ c ] . metadata || { } ;
233225 if ( ! metadata . type ) {
234- if ( typeof cellValue == "number" ) {
226+ if ( typeof cellValue === "number" ) {
235227 metadata . type = "number" ;
236228 }
237229 }
238230 if ( metadata . type == "text" || ! metadata . type ) {
239- if ( typeof strings [ cellValue ] == "undefined" ) {
231+ if ( typeof strings [ cellValue ] === "undefined" ) {
240232 strings [ cellValue ] = true ;
241233 }
242234 }
@@ -259,21 +251,21 @@ var Worksheet = /** @class */ (function () {
259251 var sheetData = Util . createElement ( doc , "sheetData" ) ;
260252 var cellCache = this . _buildCache ( doc ) ;
261253 var sharedStrs = this . sharedStrings ;
262- for ( var row = 0 , l = data . length ; row < l ; row ++ ) {
263- var dataRow = data [ row ] ;
264- var cellCount = dataRow . length ;
265- maxX = cellCount > maxX ? cellCount : maxX ;
254+ for ( var r = 0 , dLen = data . length ; r < dLen ; r ++ ) {
255+ var row = data [ r ] ;
256+ var rLen = row . length ;
257+ maxX = rLen > maxX ? rLen : maxX ;
266258 var rowNode = doc . createElement ( "row" ) ;
267- for ( var c = 0 ; c < cellCount ; c ++ ) {
259+ for ( var c = 0 ; c < rLen ; c ++ ) {
268260 columns [ c ] = columns [ c ] || { } ;
269- var cellValue = dataRow [ c ] ;
270- if ( cellValue != null && typeof cellValue == "object" ) {
261+ var cellValue = row [ c ] ;
262+ if ( cellValue != null && typeof cellValue === "object" ) {
271263 cellValue = cellValue . value ;
272264 }
273265 //fix undefined or null value
274- var metadata = dataRow [ c ] ? ( dataRow [ c ] . metadata || { } ) : { } ;
266+ var metadata = row [ c ] ? ( row [ c ] . metadata || { } ) : { } ;
275267 if ( ! metadata . type ) {
276- if ( typeof cellValue == "number" ) {
268+ if ( typeof cellValue === "number" ) {
277269 metadata . type = "number" ;
278270 }
279271 // Allows for empty cells in switch statement below
@@ -309,20 +301,20 @@ var Worksheet = /** @class */ (function () {
309301 if ( metadata . style ) {
310302 cell . setAttribute ( "s" , metadata . style ) ;
311303 }
312- cell . setAttribute ( "r" , Util . positionToLetterRef ( c + 1 , row + 1 ) ) ;
304+ cell . setAttribute ( "r" , Util . positionToLetterRef ( c + 1 , r + 1 ) ) ;
313305 // add any additional custom attributes to this cell's XML element
314- if ( row < customCellAttributes . length && customCellAttributes [ row ] != null && c < customCellAttributes [ row ] . length ) {
315- var attribs = customCellAttributes [ row ] [ c ] ;
306+ if ( r < customCellAttributes . length && customCellAttributes [ r ] != null && c < customCellAttributes [ r ] . length ) {
307+ var attribs = customCellAttributes [ r ] [ c ] ;
316308 for ( var attrib in attribs ) {
317309 cell . setAttribute ( attrib , attribs [ attrib ] ) ;
318310 }
319311 }
320312 rowNode . appendChild ( cell ) ;
321313 }
322- rowNode . setAttribute ( "r" , row + 1 ) ;
314+ rowNode . setAttribute ( "r" , r + 1 ) ;
323315 // add any additional custom attributes to this row's XML element
324- if ( row < customRowAttributes . length ) {
325- var rowAttribs = customRowAttributes [ row ] ;
316+ if ( r < customRowAttributes . length ) {
317+ var rowAttribs = customRowAttributes [ r ] ;
326318 for ( var attrib in rowAttribs ) {
327319 rowNode . setAttribute ( attrib , rowAttribs [ attrib ] ) ;
328320 }
@@ -353,7 +345,7 @@ var Worksheet = /** @class */ (function () {
353345 if ( this . _tables . length > 0 ) {
354346 var tables = doc . createElement ( "tableParts" ) ;
355347 tables . setAttribute ( "count" , this . _tables . length ) ;
356- for ( var i = 0 , l = this . _tables . length ; i < l ; i ++ ) {
348+ for ( var i = 0 , tLen = this . _tables . length ; i < tLen ; i ++ ) {
357349 var table = doc . createElement ( "tablePart" ) ;
358350 table . setAttribute ( "r:id" , this . relations . getRelationshipId ( this . _tables [ i ] ) ) ;
359351 tables . appendChild ( table ) ;
@@ -362,7 +354,7 @@ var Worksheet = /** @class */ (function () {
362354 }
363355 if ( this . mergedCells . length > 0 ) {
364356 var mergeCells = doc . createElement ( "mergeCells" ) ;
365- for ( var i = 0 , l = this . mergedCells . length ; i < l ; i ++ ) {
357+ for ( var i = 0 , mcLen = this . mergedCells . length ; i < mcLen ; i ++ ) {
366358 var mergeCell = doc . createElement ( "mergeCell" ) ;
367359 mergeCell . setAttribute ( "ref" , this . mergedCells [ i ] [ 0 ] + ':' + this . mergedCells [ i ] [ 1 ] ) ;
368360 mergeCells . appendChild ( mergeCell ) ;
@@ -393,11 +385,42 @@ var Worksheet = /** @class */ (function () {
393385 }
394386 worksheet . appendChild ( pageSetupEl ) ;
395387 }
396- for ( var i = 0 , l = this . _drawings . length ; i < l ; i ++ ) {
388+ for ( var i = 0 , dLen = this . _drawings . length ; i < dLen ; i ++ ) {
397389 var drawing = doc . createElement ( "drawing" ) ;
398390 drawing . setAttribute ( "r:id" , this . relations . getRelationshipId ( this . _drawings [ i ] ) ) ;
399391 worksheet . appendChild ( drawing ) ;
400392 }
393+ // Add extLst element if there are custom dataValidations attributes
394+ if ( this . dataValidations ) {
395+ var extLstEl = doc . createElement ( "extLst" ) ;
396+ var extChildEl = doc . createElement ( "ext" ) ;
397+ extChildEl . setAttribute ( "xmlns:x14" , "http://schemas.microsoft.com/office/spreadsheetml/2009/9/main" ) ;
398+ extChildEl . setAttribute ( "uri" , "{CCE6A557-97BC-4b89-ADB6-D9C93CAAB3DF}" ) ;
399+ var dataValidationsEl = doc . createElement ( "x14:dataValidations" ) ;
400+ dataValidationsEl . setAttribute ( "xmlns:xm" , "http://schemas.microsoft.com/office/excel/2006/main" ) ;
401+ dataValidationsEl . setAttribute ( "count" , this . dataValidations . length . toString ( ) ) ;
402+ for ( var i = 0 ; i < this . dataValidations . length ; i ++ ) {
403+ var dataValadation = this . dataValidations [ i ] ;
404+ var dataValidationEl = doc . createElement ( "x14:dataValidation" ) ;
405+ dataValidationEl . setAttribute ( "showErrorMessage" , "1" ) ;
406+ dataValidationEl . setAttribute ( "showInputMessage" , "1" ) ;
407+ dataValidationEl . setAttribute ( "allowBlank" , "1" ) ;
408+ dataValidationEl . setAttribute ( "type" , "list" ) ;
409+ var formulaEl = doc . createElement ( "x14:formula1" ) ;
410+ var xmfEl = doc . createElement ( "xm:f" ) ;
411+ // Build formula to specify range where data set lies. Ex: SheetName!$A$5:$A$10
412+ xmfEl . appendChild ( doc . createTextNode ( dataValadation . dataSheetName + "!$" + dataValadation . column + "$" + dataValadation . topRow + ":$" + dataValadation . column + "$" + dataValadation . bottomRow ) ) ;
413+ var sqrefEl = doc . createElement ( "xm:sqref" ) ;
414+ sqrefEl . appendChild ( doc . createTextNode ( dataValadation . sqref ) ) ;
415+ formulaEl . appendChild ( xmfEl ) ;
416+ dataValidationEl . appendChild ( formulaEl ) ;
417+ dataValidationEl . appendChild ( sqrefEl ) ;
418+ dataValidationsEl . appendChild ( dataValidationEl ) ;
419+ }
420+ extChildEl . appendChild ( dataValidationsEl ) ;
421+ extLstEl . appendChild ( extChildEl ) ;
422+ worksheet . appendChild ( extLstEl ) ;
423+ }
401424 return doc ;
402425 } ;
403426 /**
@@ -433,7 +456,6 @@ var Worksheet = /** @class */ (function () {
433456 return cols ;
434457 } ;
435458 /** Sets the page settings on a worksheet node.
436- *
437459 * @param doc XmlDom
438460 * @param worksheet XmlDom.XMLNode
439461 */
@@ -476,29 +498,25 @@ var Worksheet = /** @class */ (function () {
476498 } ;
477499 /** Can be one of 'portrait' or 'landscape'.
478500 * http://www.schemacentral.com/sc/ooxml/t-ssml_ST_Orientation.html
479- *
480501 * @param orientation
481502 */
482503 Worksheet . prototype . setPageOrientation = function ( orientation ) {
483504 this . _orientation = orientation ;
484505 } ;
485506 /** Expects an array of column definitions. Each column definition needs to have a width assigned to it.
486- *
487507 * @param columns
488508 */
489509 Worksheet . prototype . setColumns = function ( columns ) {
490510 this . columns = columns ;
491511 } ;
492512 /** Expects an array of data to be translated into cells.
493- *
494513 * @param data Two dimensional array - [ [A1, A2], [B1, B2] ]
495514 * @see <a href='/cookbook/addingDataToAWorksheet.html'>Adding data to a worksheet</a>
496515 */
497516 Worksheet . prototype . setData = function ( data ) {
498517 this . data = data ;
499518 } ;
500519 /** Merge cells in given range
501- *
502520 * @param cell1 - A1, A2...
503521 * @param cell2 - A2, A3...
504522 */
0 commit comments