igniteui-angular 14.2.0-alpha.4 → 14.2.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3041,10 +3041,13 @@ var ExportRecordType;
3041
3041
  ExportRecordType["DataRecord"] = "DataRecord";
3042
3042
  ExportRecordType["HierarchicalGridRecord"] = "HierarchicalGridRecord";
3043
3043
  ExportRecordType["HeaderRecord"] = "HeaderRecord";
3044
+ ExportRecordType["PivotGridRecord"] = "PivotGridRecord";
3044
3045
  })(ExportRecordType || (ExportRecordType = {}));
3045
3046
  var HeaderType;
3046
3047
  (function (HeaderType) {
3048
+ HeaderType["RowHeader"] = "RowHeader";
3047
3049
  HeaderType["ColumnHeader"] = "ColumnHeader";
3050
+ HeaderType["MultiRowHeader"] = "MultiRowHeader";
3048
3051
  HeaderType["MultiColumnHeader"] = "MultiColumnHeader";
3049
3052
  })(HeaderType || (HeaderType = {}));
3050
3053
  /**hidden
@@ -3100,6 +3103,8 @@ class IgxBaseExporter {
3100
3103
  this._sort = null;
3101
3104
  this._ownersMap = new Map();
3102
3105
  this.flatRecords = [];
3106
+ this.pivotGridColumns = [];
3107
+ this.pivotGridKeyValueMap = new Map();
3103
3108
  }
3104
3109
  /**
3105
3110
  * Method for exporting IgxGrid component's data.
@@ -3114,6 +3119,7 @@ class IgxBaseExporter {
3114
3119
  throw Error('No options provided!');
3115
3120
  }
3116
3121
  this.options = options;
3122
+ this.locale = grid.locale;
3117
3123
  let columns = grid.columns;
3118
3124
  if (this.options.ignoreMultiColumnHeaders) {
3119
3125
  columns = columns.filter(col => col.children === undefined);
@@ -3127,10 +3133,21 @@ class IgxBaseExporter {
3127
3133
  this.mapHierarchicalGridColumns(island, grid.data[0]);
3128
3134
  }
3129
3135
  }
3136
+ else if (tagName === 'igx-pivot-grid') {
3137
+ this.pivotGridColumns = [];
3138
+ this.isPivotGridExport = true;
3139
+ this.pivotGridKeyValueMap = new Map();
3140
+ this.pivotGridRowDimensionsMap = new Map();
3141
+ grid.pivotConfiguration.rows.filter(r => r.enabled).forEach(rowDimension => {
3142
+ this.addToRowDimensionsMap(rowDimension, rowDimension.memberName);
3143
+ });
3144
+ this._ownersMap.set(DEFAULT_OWNER, columnList);
3145
+ }
3130
3146
  else {
3131
3147
  this._ownersMap.set(DEFAULT_OWNER, columnList);
3132
3148
  }
3133
3149
  this.prepareData(grid);
3150
+ this.addPivotGridColumns(grid);
3134
3151
  this.exportGridRecordsData(this.flatRecords, grid);
3135
3152
  }
3136
3153
  /**
@@ -3156,6 +3173,12 @@ class IgxBaseExporter {
3156
3173
  });
3157
3174
  this.exportGridRecordsData(records);
3158
3175
  }
3176
+ addToRowDimensionsMap(rowDimension, rootParentName) {
3177
+ this.pivotGridRowDimensionsMap[rowDimension.memberName] = rootParentName;
3178
+ if (rowDimension.childLevel) {
3179
+ this.addToRowDimensionsMap(rowDimension.childLevel, rootParentName);
3180
+ }
3181
+ }
3159
3182
  exportGridRecordsData(records, grid) {
3160
3183
  if (this._ownersMap.size === 0) {
3161
3184
  const recordsData = records.map(r => r.data);
@@ -3266,7 +3289,7 @@ class IgxBaseExporter {
3266
3289
  const ownerCols = this._ownersMap.get(owner).columns;
3267
3290
  if (record.type !== ExportRecordType.HeaderRecord) {
3268
3291
  const columns = ownerCols
3269
- .filter(c => c.headerType !== HeaderType.MultiColumnHeader && !c.skip)
3292
+ .filter(c => c.headerType !== HeaderType.MultiColumnHeader && c.headerType !== HeaderType.RowHeader && c.headerType !== HeaderType.MultiRowHeader && !c.skip)
3270
3293
  .sort((a, b) => a.startIndex - b.startIndex)
3271
3294
  .sort((a, b) => a.pinnedIndex - b.pinnedIndex);
3272
3295
  record.data = columns.reduce((a, e) => {
@@ -3283,7 +3306,14 @@ class IgxBaseExporter {
3283
3306
  else if (e.dataType === 'string' && rawValue instanceof Date) {
3284
3307
  rawValue = rawValue.toString();
3285
3308
  }
3286
- a[e.field] = shouldApplyFormatter ? e.formatter(rawValue) : rawValue;
3309
+ else if (e.dataType === 'currency') {
3310
+ rawValue = formatCurrency(rawValue, e.currencyCode, e.displayFormat, e.digitsInfo, this.locale);
3311
+ }
3312
+ let formattedValue = shouldApplyFormatter ? e.formatter(rawValue) : rawValue;
3313
+ if (this.isPivotGridExport && !isNaN(parseFloat(formattedValue))) {
3314
+ formattedValue = parseFloat(formattedValue);
3315
+ }
3316
+ a[e.field] = formattedValue;
3287
3317
  }
3288
3318
  return a;
3289
3319
  }, {});
@@ -3345,6 +3375,10 @@ class IgxBaseExporter {
3345
3375
  const expressions = grid.groupingExpressions ? grid.groupingExpressions.concat(grid.sortingExpressions || []) : grid.sortingExpressions;
3346
3376
  const hasSorting = expressions && expressions.length > 0;
3347
3377
  switch (tagName) {
3378
+ case 'igx-pivot-grid': {
3379
+ this.preparePivotGridData(grid);
3380
+ break;
3381
+ }
3348
3382
  case 'igx-hierarchical-grid': {
3349
3383
  this.prepareHierarchicalGridData(grid, hasFiltering, hasSorting);
3350
3384
  break;
@@ -3359,6 +3393,21 @@ class IgxBaseExporter {
3359
3393
  }
3360
3394
  }
3361
3395
  }
3396
+ preparePivotGridData(grid) {
3397
+ for (const record of grid.filteredSortedData) {
3398
+ const recordData = Object.fromEntries(record.aggregationValues);
3399
+ record.dimensionValues.forEach((value, key) => {
3400
+ const actualKey = this.pivotGridRowDimensionsMap[key];
3401
+ recordData[actualKey] = value;
3402
+ });
3403
+ const pivotGridRecord = {
3404
+ data: recordData,
3405
+ level: record.level,
3406
+ type: ExportRecordType.PivotGridRecord
3407
+ };
3408
+ this.flatRecords.push(pivotGridRecord);
3409
+ }
3410
+ }
3362
3411
  prepareHierarchicalGridData(grid, hasFiltering, hasSorting) {
3363
3412
  const skipOperations = (!hasFiltering || !this.options.ignoreFiltering) &&
3364
3413
  (!hasSorting || !this.options.ignoreSorting);
@@ -3695,6 +3744,17 @@ class IgxBaseExporter {
3695
3744
  columnGroupParent: column.parent ? column.parent : null,
3696
3745
  columnGroup: isMultiColHeader ? column : null
3697
3746
  };
3747
+ if (column.dataType === 'currency') {
3748
+ columnInfo.currencyCode = column.pipeArgs.currencyCode
3749
+ ? column.pipeArgs.currencyCode
3750
+ : getLocaleCurrencyCode(this.locale);
3751
+ columnInfo.displayFormat = column.pipeArgs.display
3752
+ ? column.pipeArgs.display
3753
+ : 'symbol';
3754
+ columnInfo.digitsInfo = column.pipeArgs.digitsInfo
3755
+ ? column.pipeArgs.digitsInfo
3756
+ : '1.0-2';
3757
+ }
3698
3758
  if (this.options.ignoreColumnsOrder) {
3699
3759
  if (columnInfo.startIndex !== columnInfo.pinnedIndex) {
3700
3760
  columnInfo.pinnedIndex = Number.MAX_VALUE;
@@ -3783,6 +3843,68 @@ class IgxBaseExporter {
3783
3843
  };
3784
3844
  return result;
3785
3845
  }
3846
+ addPivotGridColumns(grid) {
3847
+ if (grid.nativeElement.tagName.toLowerCase() !== 'igx-pivot-grid') {
3848
+ return;
3849
+ }
3850
+ const enabledRows = grid.pivotConfiguration.rows.filter(r => r.enabled).map((r, i) => ({ name: r.memberName, level: i }));
3851
+ this.preparePivotGridColumns(enabledRows);
3852
+ this.pivotGridFilterFieldsCount = enabledRows.length;
3853
+ const columnList = this._ownersMap.get(DEFAULT_OWNER);
3854
+ columnList.columns.unshift(...this.pivotGridColumns);
3855
+ columnList.columnWidths.unshift(...Array(this.pivotGridColumns.length).fill(200));
3856
+ columnList.indexOfLastPinnedColumn = enabledRows.length - 1;
3857
+ columnList.maxRowLevel = enabledRows.length;
3858
+ this._ownersMap.set(DEFAULT_OWNER, columnList);
3859
+ }
3860
+ preparePivotGridColumns(keys, columnGroupParent) {
3861
+ if (keys.length === 0) {
3862
+ return;
3863
+ }
3864
+ let startIndex = 0;
3865
+ const key = keys[0];
3866
+ const records = this.flatRecords.map(r => r.data);
3867
+ const groupedRecords = records.reduce((hash, obj) => ({ ...hash, [obj[key.name]]: (hash[obj[key.name]] || []).concat(obj) }), {});
3868
+ if (columnGroupParent) {
3869
+ const mapKeys = [...this.pivotGridKeyValueMap.keys()];
3870
+ const mapValues = [...this.pivotGridKeyValueMap.values()];
3871
+ for (const k of Object.keys(groupedRecords)) {
3872
+ groupedRecords[k] = groupedRecords[k].filter(row => mapKeys.every(mk => Object.keys(row).includes(mk))
3873
+ && mapValues.every(mv => Object.values(row).includes(mv)));
3874
+ if (groupedRecords[k].length === 0) {
3875
+ delete groupedRecords[k];
3876
+ }
3877
+ }
3878
+ }
3879
+ for (const k of Object.keys(groupedRecords)) {
3880
+ const rowSpan = groupedRecords[k].length;
3881
+ const rowDimensionColumn = {
3882
+ rowSpan,
3883
+ field: k,
3884
+ header: k,
3885
+ startIndex,
3886
+ skip: false,
3887
+ pinnedIndex: 0,
3888
+ level: key.level,
3889
+ dataType: 'string',
3890
+ headerType: groupedRecords[k].length > 1 ? HeaderType.MultiRowHeader : HeaderType.RowHeader,
3891
+ };
3892
+ if (columnGroupParent) {
3893
+ rowDimensionColumn.columnGroupParent = columnGroupParent;
3894
+ }
3895
+ else {
3896
+ rowDimensionColumn.columnGroup = k;
3897
+ }
3898
+ this.pivotGridColumns.push(rowDimensionColumn);
3899
+ if (keys.length > 1) {
3900
+ this.pivotGridKeyValueMap.set(key.name, k);
3901
+ const newKeys = keys.filter(kdd => kdd !== key);
3902
+ this.preparePivotGridColumns(newKeys, k);
3903
+ this.pivotGridKeyValueMap.delete(key.name);
3904
+ }
3905
+ startIndex += rowSpan;
3906
+ }
3907
+ }
3786
3908
  resetDefaults() {
3787
3909
  this._sort = null;
3788
3910
  this.flatRecords = [];
@@ -4248,7 +4370,7 @@ class ExcelStrings {
4248
4370
  }
4249
4371
  static getStyles() {
4250
4372
  return ExcelStrings.XML_STRING +
4251
- '<styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="x14ac x16r2" xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac" xmlns:x16r2="http://schemas.microsoft.com/office/spreadsheetml/2015/02/main"><fonts count="2" x14ac:knownFonts="1"><font><sz val="11"/><color theme="1"/><name val="Calibri"/><family val="2"/><scheme val="minor"/></font><font><sz val="11"/><color rgb="FFB7B7B7"/><name val="Calibri"/><family val="2"/><scheme val="minor"/></font></fonts><fills count="3"><fill><patternFill patternType="none"/></fill><fill><patternFill patternType="gray125"/></fill><fill><patternFill patternType="solid"><fgColor rgb="FF0D1822"/><bgColor indexed="64"/></patternFill></fill></fills><borders count="1"><border><left/><right/><top/><bottom/><diagonal/></border></borders><cellStyleXfs count="1"><xf numFmtId="0" fontId="0" fillId="0" borderId="0"/></cellStyleXfs><cellXfs count="4"><xf numFmtId="0" fontId="0" fillId="0" borderId="0" xfId="0"/><xf numFmtId="0" fontId="0" fillId="0" borderId="0" xfId="0" applyNumberFormat="1"/> <xf numFmtId="14" fontId="0" fillId="0" borderId="0" xfId="0" applyNumberFormat="1"/> <xf numFmtId="0" fontId="1" fillId="2" borderId="0" xfId="0"/></cellXfs><cellStyles count="1"><cellStyle name="Normal" xfId="0" builtinId="0"/></cellStyles><dxfs count="0"/><tableStyles count="0" defaultTableStyle="TableStyleMedium2" defaultPivotStyle="PivotStyleLight16"/><extLst><ext uri="{EB79DEF2-80B8-43e5-95BD-54CBDDF9020C}" xmlns:x14="http://schemas.microsoft.com/office/spreadsheetml/2009/9/main"><x14:slicerStyles defaultSlicerStyle="SlicerStyleLight1"/></ext><ext uri="{9260A510-F301-46a8-8635-F512D64BE5F5}" xmlns:x15="http://schemas.microsoft.com/office/spreadsheetml/2010/11/main"><x15:timelineStyles defaultTimelineStyle="TimeSlicerStyleLight1"/></ext></extLst></styleSheet>';
4373
+ '<styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="x14ac x16r2" xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac" xmlns:x16r2="http://schemas.microsoft.com/office/spreadsheetml/2015/02/main"><fonts count="2" x14ac:knownFonts="1"><font><sz val="11"/><color theme="1"/><name val="Calibri"/><family val="2"/><scheme val="minor"/></font><font><sz val="11"/><color rgb="FFB7B7B7"/><name val="Calibri"/><family val="2"/><scheme val="minor"/></font></fonts><fills count="3"><fill><patternFill patternType="none"/></fill><fill><patternFill patternType="gray125"/></fill><fill><patternFill patternType="solid"><fgColor rgb="FF0D1822"/><bgColor indexed="64"/></patternFill></fill></fills><borders count="1"><border><left/><right/><top/><bottom/><diagonal/></border></borders><cellStyleXfs count="1"><xf numFmtId="0" fontId="0" fillId="0" borderId="0"/></cellStyleXfs><cellXfs count="5"><xf numFmtId="0" fontId="0" fillId="0" borderId="0" xfId="0"/><xf numFmtId="0" fontId="0" fillId="0" borderId="0" xfId="0" applyNumberFormat="1"/><xf numFmtId="14" fontId="0" fillId="0" borderId="0" xfId="0" applyNumberFormat="1"/><xf numFmtId="0" fontId="1" fillId="2" borderId="0" xfId="0"/><xf numFmtId="0" fontId="0" fillId="0" borderId="0" xfId="0" applyAlignment="1"><alignment horizontal="center" vertical="center"/></xf></cellXfs><cellStyles count="1"><cellStyle name="Normal" xfId="0" builtinId="0"/></cellStyles><dxfs count="0"/><tableStyles count="0" defaultTableStyle="TableStyleMedium2" defaultPivotStyle="PivotStyleLight16"/><extLst><ext uri="{EB79DEF2-80B8-43e5-95BD-54CBDDF9020C}" xmlns:x14="http://schemas.microsoft.com/office/spreadsheetml/2009/9/main"><x14:slicerStyles defaultSlicerStyle="SlicerStyleLight1"/></ext><ext uri="{9260A510-F301-46a8-8635-F512D64BE5F5}" xmlns:x15="http://schemas.microsoft.com/office/spreadsheetml/2010/11/main"><x15:timelineStyles defaultTimelineStyle="TimeSlicerStyleLight1"/></ext></extLst></styleSheet>';
4252
4374
  }
4253
4375
  static getWorkbook(worksheetName) {
4254
4376
  return ExcelStrings.XML_STRING + `<workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="x15" xmlns:x15="http://schemas.microsoft.com/office/spreadsheetml/2010/11/main"><fileVersion appName="xl" lastEdited="6" lowestEdited="6" rupBuild="14420"/><workbookPr filterPrivacy="1" defaultThemeVersion="164011"/><bookViews><workbookView xWindow="0" yWindow="0" windowWidth="22260" windowHeight="12645"/></bookViews><sheets><sheet name="${worksheetName}" sheetId="1" r:id="rId1"/></sheets><calcPr calcId="162913"/><extLst><ext uri="{140A7094-0E35-4892-8432-C4D2E57EDEB5}" xmlns:x15="http://schemas.microsoft.com/office/spreadsheetml/2010/11/main"><x15:workbookPr chartTrackingRefBase="1"/></ext></extLst></workbook>`;
@@ -4373,12 +4495,14 @@ class ThemeFile {
4373
4495
  class WorksheetFile {
4374
4496
  constructor() {
4375
4497
  this.maxOutlineLevel = 0;
4498
+ this.sheetData = '';
4376
4499
  this.dimension = '';
4377
4500
  this.freezePane = '';
4378
4501
  this.rowHeight = '';
4379
4502
  this.mergeCellStr = '';
4380
4503
  this.mergeCellsCounter = 0;
4381
4504
  this.rowIndex = 0;
4505
+ this.pivotGridRowHeadersMap = new Map();
4382
4506
  }
4383
4507
  writeElement() { }
4384
4508
  async writeElementAsync(folder, worksheetData) {
@@ -4392,63 +4516,49 @@ class WorksheetFile {
4392
4516
  });
4393
4517
  }
4394
4518
  prepareDataAsync(worksheetData, done) {
4395
- let sheetData = '';
4519
+ this.sheetData = '';
4396
4520
  let cols = '';
4397
4521
  const dictionary = worksheetData.dataDictionary;
4398
4522
  this.rowIndex = 0;
4399
4523
  if (worksheetData.isEmpty && (!worksheetData.options.alwaysExportHeaders || worksheetData.owner.columns.length === 0)) {
4400
- sheetData += '<sheetData/>';
4524
+ this.sheetData += '<sheetData/>';
4401
4525
  this.dimension = 'A1';
4402
- done('', sheetData);
4526
+ done('', this.sheetData);
4403
4527
  }
4404
4528
  else {
4405
4529
  const owner = worksheetData.owner;
4406
4530
  const isHierarchicalGrid = worksheetData.isHierarchical;
4407
4531
  const hasMultiColumnHeader = worksheetData.hasMultiColumnHeader;
4532
+ const hasMultiRowHeader = worksheetData.hasMultiRowHeader;
4408
4533
  const hasUserSetIndex = owner.columns.some(col => col.exportIndex !== undefined);
4409
4534
  const height = worksheetData.options.rowHeight;
4410
- const rowStyle = isHierarchicalGrid ? ' s="3"' : '';
4411
4535
  this.rowHeight = height ? ` ht="${height}" customHeight="1"` : '';
4412
- sheetData += `<sheetData>`;
4536
+ this.sheetData += `<sheetData>`;
4537
+ let headersForLevel = [];
4538
+ for (let i = 0; i <= owner.maxRowLevel; i++) {
4539
+ headersForLevel = owner.columns.filter(c => c.level === i && c.rowSpan > 0 && !c.skip);
4540
+ this.printHeaders(worksheetData, headersForLevel, i, true);
4541
+ this.rowIndex++;
4542
+ }
4543
+ this.rowIndex = 0;
4413
4544
  for (let i = 0; i <= owner.maxLevel; i++) {
4414
4545
  this.rowIndex++;
4415
- sheetData += `<row r="${this.rowIndex}"${this.rowHeight}>`;
4416
- const headersForLevel = hasMultiColumnHeader ?
4417
- owner.columns
4546
+ const pivotGridColumns = this.pivotGridRowHeadersMap.get(this.rowIndex) ?? "";
4547
+ this.sheetData += `<row r="${this.rowIndex}"${this.rowHeight}>${pivotGridColumns}`;
4548
+ const allowedColumns = owner.columns.filter(c => c.headerType !== HeaderType.RowHeader && c.headerType !== HeaderType.MultiRowHeader);
4549
+ headersForLevel = hasMultiColumnHeader ?
4550
+ allowedColumns
4418
4551
  .filter(c => (c.level < i &&
4419
4552
  c.headerType !== HeaderType.MultiColumnHeader || c.level === i) && c.columnSpan > 0 && !c.skip)
4420
4553
  .sort((a, b) => a.startIndex - b.startIndex)
4421
4554
  .sort((a, b) => a.pinnedIndex - b.pinnedIndex) :
4422
4555
  hasUserSetIndex ?
4423
- owner.columns.filter(c => !c.skip) :
4424
- owner.columns.filter(c => !c.skip)
4556
+ allowedColumns.filter(c => !c.skip) :
4557
+ allowedColumns.filter(c => !c.skip)
4425
4558
  .sort((a, b) => a.startIndex - b.startIndex)
4426
4559
  .sort((a, b) => a.pinnedIndex - b.pinnedIndex);
4427
- let startValue = 0;
4428
- for (const currentCol of headersForLevel) {
4429
- if (currentCol.level === i) {
4430
- let columnCoordinate;
4431
- columnCoordinate = ExcelStrings.getExcelColumn(startValue) + this.rowIndex;
4432
- const columnValue = dictionary.saveValue(currentCol.header, true);
4433
- sheetData += `<c r="${columnCoordinate}"${rowStyle} t="s"><v>${columnValue}</v></c>`;
4434
- if (i !== owner.maxLevel) {
4435
- this.mergeCellsCounter++;
4436
- this.mergeCellStr += ` <mergeCell ref="${columnCoordinate}:`;
4437
- if (currentCol.headerType === HeaderType.ColumnHeader) {
4438
- columnCoordinate = ExcelStrings.getExcelColumn(startValue) + (owner.maxLevel + 1);
4439
- }
4440
- else {
4441
- for (let k = 1; k < currentCol.columnSpan; k++) {
4442
- columnCoordinate = ExcelStrings.getExcelColumn(startValue + k) + this.rowIndex;
4443
- sheetData += `<c r="${columnCoordinate}"${rowStyle} />`;
4444
- }
4445
- }
4446
- this.mergeCellStr += `${columnCoordinate}" />`;
4447
- }
4448
- }
4449
- startValue += currentCol.columnSpan;
4450
- }
4451
- sheetData += `</row>`;
4560
+ this.printHeaders(worksheetData, headersForLevel, i, false);
4561
+ this.sheetData += `</row>`;
4452
4562
  }
4453
4563
  const multiColumnHeaderLevel = worksheetData.options.ignoreMultiColumnHeaders ? 0 : owner.maxLevel;
4454
4564
  const freezeHeaders = worksheetData.options.freezeHeaders ? 2 + multiColumnHeaderLevel : 1;
@@ -4501,12 +4611,12 @@ class WorksheetFile {
4501
4611
  }
4502
4612
  }
4503
4613
  this.processDataRecordsAsync(worksheetData, (rows) => {
4504
- sheetData += rows;
4505
- sheetData += '</sheetData>';
4506
- if (hasMultiColumnHeader && this.mergeCellsCounter > 0) {
4507
- sheetData += `<mergeCells count="${this.mergeCellsCounter}">${this.mergeCellStr}</mergeCells>`;
4614
+ this.sheetData += rows;
4615
+ this.sheetData += '</sheetData>';
4616
+ if ((hasMultiColumnHeader || hasMultiRowHeader) && this.mergeCellsCounter > 0) {
4617
+ this.sheetData += `<mergeCells count="${this.mergeCellsCounter}">${this.mergeCellStr}</mergeCells>`;
4508
4618
  }
4509
- done(cols, sheetData);
4619
+ done(cols, this.sheetData);
4510
4620
  });
4511
4621
  }
4512
4622
  }
@@ -4525,7 +4635,7 @@ class WorksheetFile {
4525
4635
  }
4526
4636
  else {
4527
4637
  recordHeaders = worksheetData.owner.columns
4528
- .filter(c => c.headerType !== HeaderType.MultiColumnHeader && !c.skip)
4638
+ .filter(c => c.headerType !== HeaderType.MultiColumnHeader && c.headerType !== HeaderType.MultiRowHeader && c.headerType !== HeaderType.RowHeader && !c.skip)
4529
4639
  .sort((a, b) => a.startIndex - b.startIndex)
4530
4640
  .sort((a, b) => a.pinnedIndex - b.pinnedIndex)
4531
4641
  .map(c => c.field);
@@ -4599,11 +4709,12 @@ class WorksheetFile {
4599
4709
  this.maxOutlineLevel = this.maxOutlineLevel < rowLevel ? rowLevel : this.maxOutlineLevel;
4600
4710
  const sHidden = record.hidden ? ` hidden="1"` : '';
4601
4711
  this.rowIndex++;
4712
+ const pivotGridColumns = this.pivotGridRowHeadersMap.get(this.rowIndex) ?? "";
4602
4713
  rowData[0] =
4603
- `<row r="${this.rowIndex}"${this.rowHeight}${outlineLevel}${sHidden}>`;
4714
+ `<row r="${this.rowIndex}"${this.rowHeight}${outlineLevel}${sHidden}>${pivotGridColumns}`;
4604
4715
  const keys = worksheetData.isSpecialData ? [record.data] : headersForLevel;
4605
4716
  for (let j = 0; j < keys.length; j++) {
4606
- const col = j + (isHierarchicalGrid ? rowLevel : 0);
4717
+ const col = j + (isHierarchicalGrid ? rowLevel : worksheetData.isPivotGrid ? worksheetData.owner.maxRowLevel : 0);
4607
4718
  const cellData = this.getCellData(worksheetData, i, col, keys[j]);
4608
4719
  rowData[j + 1] = cellData;
4609
4720
  }
@@ -4636,6 +4747,74 @@ class WorksheetFile {
4636
4747
  return `<c r="${columnName}"${type}${format}><v>${value}</v></c>`;
4637
4748
  }
4638
4749
  }
4750
+ printHeaders(worksheetData, headersForLevel, i, isVertical) {
4751
+ let startValue = 0;
4752
+ let str = '';
4753
+ const isHierarchicalGrid = worksheetData.isHierarchical;
4754
+ let rowStyle = isHierarchicalGrid ? ' s="3"' : '';
4755
+ const dictionary = worksheetData.dataDictionary;
4756
+ const owner = worksheetData.owner;
4757
+ const maxLevel = isVertical
4758
+ ? owner.maxRowLevel
4759
+ : owner.maxLevel;
4760
+ for (const currentCol of headersForLevel) {
4761
+ const spanLength = isVertical ? currentCol.rowSpan : currentCol.columnSpan;
4762
+ if (currentCol.level === i) {
4763
+ let columnCoordinate;
4764
+ const column = isVertical
4765
+ ? this.rowIndex
4766
+ : startValue + (owner.maxRowLevel ?? 0);
4767
+ const rowCoordinate = isVertical
4768
+ ? startValue + owner.maxLevel + 2
4769
+ : this.rowIndex;
4770
+ const columnValue = dictionary.saveValue(currentCol.header, true);
4771
+ columnCoordinate = ExcelStrings.getExcelColumn(column) + rowCoordinate;
4772
+ rowStyle = isVertical && currentCol.rowSpan > 1 ? ' s="4"' : rowStyle;
4773
+ str = `<c r="${columnCoordinate}"${rowStyle} t="s"><v>${columnValue}</v></c>`;
4774
+ if (isVertical) {
4775
+ if (this.pivotGridRowHeadersMap.has(rowCoordinate)) {
4776
+ this.pivotGridRowHeadersMap.set(rowCoordinate, this.pivotGridRowHeadersMap.get(rowCoordinate) + str);
4777
+ }
4778
+ else {
4779
+ this.pivotGridRowHeadersMap.set(rowCoordinate, str);
4780
+ }
4781
+ }
4782
+ else {
4783
+ this.sheetData += str;
4784
+ }
4785
+ if (i !== maxLevel) {
4786
+ this.mergeCellsCounter++;
4787
+ this.mergeCellStr += ` <mergeCell ref="${columnCoordinate}:`;
4788
+ if (currentCol.headerType === HeaderType.ColumnHeader) {
4789
+ const col = isVertical
4790
+ ? maxLevel
4791
+ : startValue + (owner.maxRowLevel ?? 0);
4792
+ const row = isVertical
4793
+ ? rowCoordinate
4794
+ : owner.maxLevel + 1;
4795
+ columnCoordinate = ExcelStrings.getExcelColumn(col) + row;
4796
+ }
4797
+ else {
4798
+ for (let k = 1; k < spanLength; k++) {
4799
+ const col = isVertical
4800
+ ? column
4801
+ : column + k;
4802
+ const row = isVertical
4803
+ ? rowCoordinate + k
4804
+ : this.rowIndex;
4805
+ columnCoordinate = ExcelStrings.getExcelColumn(col) + row;
4806
+ str = `<c r="${columnCoordinate}"${rowStyle} />`;
4807
+ isVertical
4808
+ ? this.pivotGridRowHeadersMap.set(row, str)
4809
+ : this.sheetData += str;
4810
+ }
4811
+ }
4812
+ this.mergeCellStr += `${columnCoordinate}" />`;
4813
+ }
4814
+ }
4815
+ startValue += spanLength;
4816
+ }
4817
+ }
4639
4818
  }
4640
4819
  WorksheetFile.MIN_WIDTH = 8.43;
4641
4820
  /**
@@ -5035,9 +5214,15 @@ class WorksheetData {
5035
5214
  get hasMultiColumnHeader() {
5036
5215
  return this._hasMultiColumnHeader;
5037
5216
  }
5217
+ get hasMultiRowHeader() {
5218
+ return this._hasMultiRowHeader;
5219
+ }
5038
5220
  get isHierarchical() {
5039
5221
  return this._isHierarchical;
5040
5222
  }
5223
+ get isPivotGrid() {
5224
+ return this._isPivotGrid;
5225
+ }
5041
5226
  get multiColumnHeaderRows() {
5042
5227
  return !this.options.ignoreMultiColumnHeaders ? Array.from(this.owners.values()).map(c => c.maxLevel).reduce((a, b) => a + b) : 0;
5043
5228
  }
@@ -5045,9 +5230,12 @@ class WorksheetData {
5045
5230
  this._dataDictionary = new WorksheetDataDictionary(this.columnCount, this.options.columnWidth, this.columnWidths);
5046
5231
  this._hasMultiColumnHeader = Array.from(this.owners.values())
5047
5232
  .some(o => o.columns.some(col => !col.skip && col.headerType === HeaderType.MultiColumnHeader));
5233
+ this._hasMultiRowHeader = Array.from(this.owners.values())
5234
+ .some(o => o.columns.some(col => !col.skip && col.headerType === HeaderType.MultiRowHeader));
5048
5235
  this._isHierarchical = this.data[0]?.type === ExportRecordType.HierarchicalGridRecord
5049
5236
  || !(typeof (Array.from(this.owners.keys())[0]) === 'string');
5050
- if (this._isHierarchical || (this._hasMultiColumnHeader && !this.options.ignoreMultiColumnHeaders)) {
5237
+ this._isPivotGrid = this.data[0]?.type === ExportRecordType.PivotGridRecord;
5238
+ if (this._isHierarchical || this._isPivotGrid || (this._hasMultiColumnHeader && !this.options.ignoreMultiColumnHeaders)) {
5051
5239
  this.options.exportAsTable = false;
5052
5240
  }
5053
5241
  if (!this._data || this._data.length === 0) {
@@ -5118,6 +5306,7 @@ class IgxExcelExporterService extends IgxBaseExporter {
5118
5306
  exportDataImplementation(data, options, done) {
5119
5307
  const firstDataElement = data[0];
5120
5308
  const isHierarchicalGrid = firstDataElement?.type === ExportRecordType.HierarchicalGridRecord;
5309
+ const isPivotGrid = firstDataElement?.type === ExportRecordType.PivotGridRecord;
5121
5310
  let rootKeys;
5122
5311
  let columnCount;
5123
5312
  let columnWidths;
@@ -5151,7 +5340,7 @@ class IgxExcelExporterService extends IgxBaseExporter {
5151
5340
  const columns = defaultOwner.columns.filter(col => !col.skip && col.headerType === HeaderType.ColumnHeader);
5152
5341
  columnWidths = defaultOwner.columnWidths;
5153
5342
  indexOfLastPinnedColumn = defaultOwner.indexOfLastPinnedColumn;
5154
- columnCount = columns.length;
5343
+ columnCount = isPivotGrid ? columns.length + this.pivotGridFilterFieldsCount : columns.length;
5155
5344
  rootKeys = columns.map(c => c.field);
5156
5345
  }
5157
5346
  }