@@ -4,13 +4,14 @@ import * as moment from 'moment-mini';
44
55import {
66 Column ,
7+ ExcelExportOption ,
8+ FieldType ,
79 FileType ,
810 Formatter ,
911 GridOption ,
10- FieldType ,
1112 GroupTotalsFormatter ,
13+ ItemMetadata ,
1214 SortDirectionNumber ,
13- ExcelExportOption ,
1415} from '../../models' ;
1516import { ExcelExportService } from '../excelExport.service' ;
1617import { Formatters } from '../../formatters/index' ;
@@ -20,8 +21,8 @@ import { GroupTotalFormatters } from '../..';
2021// URL object is not supported in JSDOM, we can simply mock it
2122( global as any ) . URL . createObjectURL = jest . fn ( ) ;
2223
23- const myBoldHtmlFormatter : Formatter = ( row , cell , value , columnDef , dataContext ) => value !== null ? { text : `<b>${ value } </b>` } : null ;
24- const myUppercaseFormatter : Formatter = ( row , cell , value , columnDef , dataContext ) => value ? { text : value . toUpperCase ( ) } : null ;
24+ const myBoldHtmlFormatter : Formatter = ( row , cell , value ) => value !== null ? { text : `<b>${ value } </b>` } : '' ;
25+ const myUppercaseFormatter : Formatter = ( row , cell , value ) => value ? { text : value . toUpperCase ( ) } : '' ;
2526const myUppercaseGroupTotalFormatter : GroupTotalsFormatter = ( totals : any , columnDef : Column ) => {
2627 const field = columnDef . field || '' ;
2728 const val = totals . sum && totals . sum [ field ] ;
@@ -44,6 +45,7 @@ const myCustomObjectFormatter: Formatter = (row: number, cell: number, value: an
4445const dataViewStub = {
4546 getGrouping : jest . fn ( ) ,
4647 getItem : jest . fn ( ) ,
48+ getItemMetadata : jest . fn ( ) ,
4749 getLength : jest . fn ( ) ,
4850 setGrouping : jest . fn ( ) ,
4951} ;
@@ -58,6 +60,7 @@ const gridStub = {
5860 getColumnIndex : jest . fn ( ) ,
5961 getOptions : ( ) => mockGridOptions ,
6062 getColumns : jest . fn ( ) ,
63+ getData : ( ) => dataViewStub ,
6164 getGrouping : jest . fn ( ) ,
6265} ;
6366
@@ -72,7 +75,7 @@ describe('ExcelExportService', () => {
7275 beforeEach ( ( ) => {
7376 // @ts -ignore
7477 navigator . __defineGetter__ ( 'appName' , ( ) => 'Netscape' ) ;
75- navigator . msSaveOrOpenBlob = undefined ;
78+ navigator . msSaveOrOpenBlob = undefined as any ;
7679 mockExcelBlob = new Blob ( [ '' , '' ] , { type : `text/xlsx;charset=utf-8;` } ) ;
7780
7881 mockExportExcelOptions = {
@@ -535,7 +538,6 @@ describe('ExcelExportService', () => {
535538 jest . spyOn ( gridStub , 'getColumns' ) . mockReturnValue ( mockColumns ) ;
536539 } ) ;
537540
538-
539541 it ( `should expect Date exported correctly when Field Type is provided and we use "exportWithFormatter" set to True & False` , async ( ) => {
540542 mockCollection = [
541543 { id : 0 , userId : '1E06' , firstName : 'John' , lastName : 'Z' , position : 'SALES_REP' , startDate : '2005-12-20T18:19:19.992Z' , endDate : null } ,
@@ -696,10 +698,10 @@ describe('ExcelExportService', () => {
696698 aggregateEmpty : false ,
697699 aggregators : [ { _count : 2 , _field : 'order' , _nonNullCount : 2 , _sum : 4 , } ] ,
698700 collapsed : false ,
699- comparer : ( a , b ) => Sorters . numeric ( a . value , b . value , SortDirectionNumber . asc ) ,
701+ comparer : ( a : any , b : any ) => Sorters . numeric ( a . value , b . value , SortDirectionNumber . asc ) ,
700702 compiledAccumulators : [ jest . fn ( ) , jest . fn ( ) ] ,
701703 displayTotalsRow : true ,
702- formatter : ( g ) => `Order: ${ g . value } <span style="color:green">(${ g . count } items)</span>` ,
704+ formatter : ( g : any ) => `Order: ${ g . value } <span style="color:green">(${ g . count } items)</span>` ,
703705 getter : 'order' ,
704706 getterIsAFn : false ,
705707 lazyTotalsCalculation : true ,
@@ -790,10 +792,10 @@ describe('ExcelExportService', () => {
790792 aggregateEmpty : false ,
791793 aggregators : [ { _count : 2 , _field : 'order' , _nonNullCount : 2 , _sum : 4 , } ] ,
792794 collapsed : false ,
793- comparer : ( a , b ) => Sorters . numeric ( a . value , b . value , SortDirectionNumber . asc ) ,
795+ comparer : ( a : any , b : any ) => Sorters . numeric ( a . value , b . value , SortDirectionNumber . asc ) ,
794796 compiledAccumulators : [ jest . fn ( ) , jest . fn ( ) ] ,
795797 displayTotalsRow : true ,
796- formatter : ( g ) => `Order: ${ g . value } <span style="color:green">(${ g . count } items)</span>` ,
798+ formatter : ( g : any ) => `Order: ${ g . value } <span style="color:green">(${ g . count } items)</span>` ,
797799 getter : 'order' ,
798800 getterIsAFn : false ,
799801 lazyTotalsCalculation : true ,
@@ -888,10 +890,10 @@ describe('ExcelExportService', () => {
888890 aggregateEmpty : false ,
889891 aggregators : [ { _count : 2 , _field : 'order' , _nonNullCount : 2 , _sum : 4 , } ] ,
890892 collapsed : false ,
891- comparer : ( a , b ) => Sorters . numeric ( a . value , b . value , SortDirectionNumber . asc ) ,
893+ comparer : ( a : any , b : any ) => Sorters . numeric ( a . value , b . value , SortDirectionNumber . asc ) ,
892894 compiledAccumulators : [ jest . fn ( ) , jest . fn ( ) ] ,
893895 displayTotalsRow : true ,
894- formatter : ( g ) => `Order: ${ g . value } <span style="color:green">(${ g . count } items)</span>` ,
896+ formatter : ( g : any ) => `Order: ${ g . value } <span style="color:green">(${ g . count } items)</span>` ,
895897 getter : 'order' ,
896898 getterIsAFn : false ,
897899 lazyTotalsCalculation : true ,
@@ -904,10 +906,10 @@ describe('ExcelExportService', () => {
904906 aggregateEmpty : false ,
905907 aggregators : [ { _count : 1 , _field : 'lastName' , _nonNullCount : 2 , _sum : 4 , } ] ,
906908 collapsed : false ,
907- comparer : ( a , b ) => Sorters . numeric ( a . value , b . value , SortDirectionNumber . asc ) ,
909+ comparer : ( a : any , b : any ) => Sorters . numeric ( a . value , b . value , SortDirectionNumber . asc ) ,
908910 compiledAccumulators : [ jest . fn ( ) , jest . fn ( ) ] ,
909911 displayTotalsRow : true ,
910- formatter : ( g ) => `Last Name: ${ g . value } <span style="color:green">(${ g . count } items)</span>` ,
912+ formatter : ( g : any ) => `Last Name: ${ g . value } <span style="color:green">(${ g . count } items)</span>` ,
911913 getter : 'lastName' ,
912914 getterIsAFn : false ,
913915 lazyTotalsCalculation : true ,
@@ -998,7 +1000,7 @@ describe('ExcelExportService', () => {
9981000 it ( `should have a xlsx export with grouping but without indentation when "addGroupIndentation" is set to False
9991001 and field should be exported as metadata when "exportWithFormatter" is false and the field type is number` , async ( ) => {
10001002 mockColumns [ 5 ] . exportWithFormatter = false ; // "order" field that is of type number will be exported as a number cell format metadata
1001- mockGridOptions . excelExportOptions . addGroupIndentation = false ;
1003+ mockGridOptions . excelExportOptions ! . addGroupIndentation = false ;
10021004 const spyOnAfter = jest . spyOn ( service . onGridAfterExportToExcel , 'next' ) ;
10031005 const spyUrlCreate = jest . spyOn ( URL , 'createObjectURL' ) ;
10041006 const spyDownload = jest . spyOn ( service , 'startDownloadFile' ) ;
@@ -1022,9 +1024,9 @@ describe('ExcelExportService', () => {
10221024 ] ,
10231025 [ 'Order: 20 (2 items)' ] ,
10241026 [ 'Last Name: Z (1 items)' ] ,
1025- [ '' , '1E06' , 'John' , 'Z' , 'Sales Rep.' , { metadata : { style : 3 } , value : '10' , } ] ,
1027+ [ '' , '1E06' , 'John' , 'Z' , 'Sales Rep.' , { metadata : { style : 3 , type : 'number' } , value : 10 , } ] ,
10261028 [ 'Last Name: Doe (1 items)' ] ,
1027- [ '' , '2B02' , 'Jane' , 'DOE' , 'Finance Manager' , { metadata : { style : 3 } , value : '10' , } ] ,
1029+ [ '' , '2B02' , 'Jane' , 'DOE' , 'Finance Manager' , { metadata : { style : 3 , type : 'number' } , value : 10 , } ] ,
10281030 [ 'Last Name: null (0 items)' ] ,
10291031 [ '' , '' , '' , '' , '' , '20' ] ,
10301032 [ '' , '' , '' , '' , '' , '10' ] ,
@@ -1367,7 +1369,7 @@ describe('ExcelExportService', () => {
13671369 } ) ;
13681370
13691371 it ( `should have the LastName header title translated when defined as a "headerKey" and "i18n" is set in grid option` , async ( ) => {
1370- mockGridOptions . excelExportOptions . sanitizeDataExport = false ;
1372+ mockGridOptions . excelExportOptions ! . sanitizeDataExport = false ;
13711373 mockCollection2 = [ { id : 0 , userId : '1E06' , firstName : 'John' , lastName : 'Z' , position : 'SALES_REP' , order : 10 } ] ;
13721374 jest . spyOn ( dataViewStub , 'getLength' ) . mockReturnValue ( mockCollection2 . length ) ;
13731375 jest . spyOn ( dataViewStub , 'getItem' ) . mockReturnValue ( null ) . mockReturnValueOnce ( mockCollection2 [ 0 ] ) ;
@@ -1404,6 +1406,83 @@ describe('ExcelExportService', () => {
14041406 } ) ;
14051407 } ) ;
14061408 } ) ;
1409+
1410+ describe ( 'grid with colspan' , ( ) => {
1411+ let mockCollection ;
1412+ let oddMetatadata = { columns : { lastName : { colspan : 2 } } } as ItemMetadata ;
1413+ let evenMetatadata = { columns : { 0 : { colspan : '*' } } } as ItemMetadata ;
1414+
1415+ beforeEach ( ( ) => {
1416+ mockGridOptions . enableTranslate = true ;
1417+ mockGridOptions . i18n = translate ;
1418+ mockGridOptions . excelExportOptions = { } ;
1419+ mockGridOptions . createPreHeaderPanel = false ;
1420+ mockGridOptions . showPreHeaderPanel = false ;
1421+ mockGridOptions . colspanCallback = ( item : any ) => ( item . id % 2 === 1 ) ? evenMetatadata : oddMetatadata ;
1422+
1423+ mockColumns = [
1424+ { id : 'userId' , field : 'userId' , name : 'User Id' , width : 100 } ,
1425+ { id : 'firstName' , nameKey : 'FIRST_NAME' , width : 100 , formatter : myBoldHtmlFormatter } ,
1426+ { id : 'lastName' , field : 'lastName' , nameKey : 'LAST_NAME' , width : 100 , formatter : myBoldHtmlFormatter , exportCustomFormatter : myUppercaseFormatter , sanitizeDataExport : true , exportWithFormatter : true } ,
1427+ { id : 'position' , field : 'position' , name : 'Position' , width : 100 , formatter : Formatters . translate , exportWithFormatter : true } ,
1428+ { id : 'order' , field : 'order' , width : 100 , } ,
1429+ ] as Column [ ] ;
1430+
1431+ jest . spyOn ( gridStub , 'getColumns' ) . mockReturnValue ( mockColumns ) ;
1432+ } ) ;
1433+
1434+ afterEach ( ( ) => {
1435+ jest . clearAllMocks ( ) ;
1436+ } ) ;
1437+
1438+ it ( 'should return associated Excel column name when calling "getExcelColumnNameByIndex" method with a column index' , ( ) => {
1439+ const excelColumnA = service . getExcelColumnNameByIndex ( 1 ) ;
1440+ const excelColumnZ = service . getExcelColumnNameByIndex ( 26 ) ;
1441+ const excelColumnAA = service . getExcelColumnNameByIndex ( 27 ) ;
1442+ const excelColumnCA = service . getExcelColumnNameByIndex ( 79 ) ;
1443+
1444+ expect ( excelColumnA ) . toBe ( 'A' ) ;
1445+ expect ( excelColumnZ ) . toBe ( 'Z' ) ;
1446+ expect ( excelColumnAA ) . toBe ( 'AA' ) ;
1447+ expect ( excelColumnCA ) . toBe ( 'CA' ) ;
1448+ } ) ;
1449+
1450+ it ( `should export same colspan in the export excel as defined in the grid` , async ( ) => {
1451+ mockCollection = [
1452+ { id : 0 , userId : '1E06' , firstName : 'John' , lastName : 'Z' , position : 'SALES_REP' , order : 10 } ,
1453+ { id : 1 , userId : '1E09' , firstName : 'Jane' , lastName : 'Doe' , position : 'DEVELOPER' , order : 15 } ,
1454+ { id : 2 , userId : '2ABC' , firstName : 'Sponge' , lastName : 'Bob' , position : 'IT_ADMIN' , order : 33 } ,
1455+ ] ;
1456+ jest . spyOn ( dataViewStub , 'getLength' ) . mockReturnValue ( mockCollection . length ) ;
1457+ jest . spyOn ( dataViewStub , 'getItem' ) . mockReturnValue ( null ) . mockReturnValueOnce ( mockCollection [ 0 ] ) . mockReturnValueOnce ( mockCollection [ 1 ] ) . mockReturnValueOnce ( mockCollection [ 2 ] ) ;
1458+ jest . spyOn ( dataViewStub , 'getItemMetadata' ) . mockReturnValue ( oddMetatadata ) . mockReturnValueOnce ( evenMetatadata ) . mockReturnValueOnce ( oddMetatadata ) . mockReturnValueOnce ( evenMetatadata ) ;
1459+ const spyOnAfter = jest . spyOn ( service . onGridAfterExportToExcel , 'next' ) ;
1460+ const spyUrlCreate = jest . spyOn ( URL , 'createObjectURL' ) ;
1461+ const spyDownload = jest . spyOn ( service , 'startDownloadFile' ) ;
1462+
1463+ const optionExpectation = { filename : 'export.xlsx' , format : FileType . xlsx } ;
1464+
1465+ service . init ( gridStub , dataViewStub ) ;
1466+ await service . exportToExcel ( mockExportExcelOptions ) ;
1467+
1468+ expect ( spyOnAfter ) . toHaveBeenCalledWith ( optionExpectation ) ;
1469+ expect ( spyUrlCreate ) . toHaveBeenCalledWith ( mockExcelBlob ) ;
1470+ expect ( spyDownload ) . toHaveBeenCalledWith ( {
1471+ ...optionExpectation , blob : new Blob ( ) , data : [
1472+ [
1473+ { metadata : { style : 1 , } , value : 'User Id' , } ,
1474+ { metadata : { style : 1 , } , value : 'First Name' , } ,
1475+ { metadata : { style : 1 , } , value : 'Last Name' , } ,
1476+ { metadata : { style : 1 , } , value : 'Position' , } ,
1477+ { metadata : { style : 1 , } , value : 'Order' , } ,
1478+ ] ,
1479+ [ '1E06' , '' , '' , '' ] ,
1480+ [ '1E09' , 'Jane' , 'DOE' , '' , 15 ] ,
1481+ [ '2ABC' , '' , '' , '' ] ,
1482+ ]
1483+ } ) ;
1484+ } ) ;
1485+ } ) ;
14071486 } ) ;
14081487
14091488 describe ( 'without ngx-translate' , ( ) => {
0 commit comments