From abdae52822c4496286a653ed84be964213e1d32f Mon Sep 17 00:00:00 2001 From: ghiscoding Date: Mon, 15 Nov 2021 11:34:44 -0500 Subject: [PATCH] fix(export): sanitize any html that could exist in header titles - also fix a number cell format in Excel export --- .../src/examples/example16.ts | 12 ++++++++++-- packages/excel-export/package.json | 4 ++-- .../excel-export/src/excelExport.service.ts | 7 ++++--- packages/text-export/src/textExport.service.ts | 2 +- yarn.lock | 18 +++++++++--------- 5 files changed, 26 insertions(+), 17 deletions(-) diff --git a/examples/webpack-demo-vanilla-bundle/src/examples/example16.ts b/examples/webpack-demo-vanilla-bundle/src/examples/example16.ts index 051e05bf2..e3d5b6926 100644 --- a/examples/webpack-demo-vanilla-bundle/src/examples/example16.ts +++ b/examples/webpack-demo-vanilla-bundle/src/examples/example16.ts @@ -3,7 +3,6 @@ import { Column, Editors, FieldType, - FileType, Filters, Formatters, GridOption, @@ -11,6 +10,7 @@ import { } from '@slickgrid-universal/common'; import { SlickCustomTooltip } from '@slickgrid-universal/custom-tooltip-plugin'; import { ExcelExportService } from '@slickgrid-universal/excel-export'; +import { TextExportService } from '@slickgrid-universal/text-export'; import { Slicker, SlickVanillaGridBundle } from '@slickgrid-universal/vanilla-bundle'; import { ExampleGridOptions } from './example-grid-options'; @@ -98,6 +98,7 @@ export class Example16 { minLength: 5, maxLength: 255, }, + exportWithFormatter: false, formatter: (row, cell, value, column, dataContext) => `${value || ''}`, // define tooltip options here OR for the entire grid via the grid options (cell tooltip options will have precedence over grid options) customTooltip: { @@ -113,6 +114,7 @@ export class Example16 { minLength: 5, maxLength: 255, }, + exportWithFormatter: false, formatter: (row, cell, value, column, dataContext) => `${value || ''}`, // define tooltip options here OR for the entire grid via the grid options (cell tooltip options will have precedence over grid options) customTooltip: { @@ -128,6 +130,7 @@ export class Example16 { width: 90, sortable: true, filterable: true, + exportWithFormatter: false, // filter: { model: Filters.compoundInput }, // formatter: Formatters.dollar, formatter: Formatters.multiple, @@ -147,6 +150,7 @@ export class Example16 { maxValue: 100, // params: { hideSliderNumber: true }, }, + exportWithFormatter: false, formatter: Formatters.percentCompleteBar, sortable: true, filterable: true, filter: { model: Filters.slider, operator: '>=' }, @@ -315,8 +319,12 @@ export class Example16 { excelExportOptions: { exportWithFormatter: true }, + enableTextExport: true, + textExportOptions: { + exportWithFormatter: true + }, // Custom Tooltip options can be defined in a Column or Grid Options or a mixed of both (first options found wins) - registerExternalResources: [new SlickCustomTooltip(), new ExcelExportService()], + registerExternalResources: [new SlickCustomTooltip(), new ExcelExportService(), new TextExportService()], customTooltip: { formatter: this.tooltipFormatter.bind(this), headerFormatter: this.headerFormatter, diff --git a/packages/excel-export/package.json b/packages/excel-export/package.json index bbd6aecc8..abf8b3c56 100644 --- a/packages/excel-export/package.json +++ b/packages/excel-export/package.json @@ -49,7 +49,7 @@ ], "dependencies": { "@slickgrid-universal/common": "^0.19.0", - "excel-builder-webpacker": "^2.1.5", + "excel-builder-webpacker": "^2.1.6", "moment-mini": "^2.24.0" }, "devDependencies": { @@ -57,4 +57,4 @@ "npm-run-all": "^4.1.5", "rimraf": "^3.0.2" } -} +} \ No newline at end of file diff --git a/packages/excel-export/src/excelExport.service.ts b/packages/excel-export/src/excelExport.service.ts index 3a55a6f9d..c1fc948a4 100644 --- a/packages/excel-export/src/excelExport.service.ts +++ b/packages/excel-export/src/excelExport.service.ts @@ -210,7 +210,7 @@ export class ExcelExportService implements ExternalResource, BaseExcelExportServ } else { // this trick will generate a temp tag // the code will then trigger a hidden click for it to start downloading - const link = document && document.createElement('a'); + const link = document.createElement('a'); const url = URL.createObjectURL(options.blob); if (link && document) { @@ -267,7 +267,8 @@ export class ExcelExportService implements ExternalResource, BaseExcelExportServ } break; case FieldType.number: - const val = isNaN(+data) ? null : +data; + const num = parseFloat(data as string); + const val = isNaN(num) ? null : num; outputData = { value: val, metadata: { style: this._stylesheetFormats.numberFormatter.id } }; break; default: @@ -374,7 +375,7 @@ export class ExcelExportService implements ExternalResource, BaseExcelExportServ this._columnHeaders = this.getColumnHeaders(columns) || []; if (this._columnHeaders && Array.isArray(this._columnHeaders) && this._columnHeaders.length > 0) { // add the header row + add a new line at the end of the row - outputHeaderTitles = this._columnHeaders.map((header) => ({ value: header.title, metadata })); + outputHeaderTitles = this._columnHeaders.map((header) => ({ value: sanitizeHtmlToText(header.title), metadata })); } // do we have a Group by title? diff --git a/packages/text-export/src/textExport.service.ts b/packages/text-export/src/textExport.service.ts index cc21f7978..5390f96f5 100644 --- a/packages/text-export/src/textExport.service.ts +++ b/packages/text-export/src/textExport.service.ts @@ -228,7 +228,7 @@ export class TextExportService implements ExternalResource, BaseTextExportServic this._columnHeaders = this.getColumnHeaders(columns) || []; if (this._columnHeaders && Array.isArray(this._columnHeaders) && this._columnHeaders.length > 0) { // add the header row + add a new line at the end of the row - const outputHeaderTitles = this._columnHeaders.map((header) => `${this._exportQuoteWrapper}${header.title}${this._exportQuoteWrapper}`); + const outputHeaderTitles = this._columnHeaders.map((header) => sanitizeHtmlToText(`${this._exportQuoteWrapper}${header.title}${this._exportQuoteWrapper}`)); outputDataString += (outputHeaderTitles.join(this._delimiter) + this._lineCarriageReturn); } diff --git a/yarn.lock b/yarn.lock index 1db358806..0da2e86f7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4840,12 +4840,12 @@ events@^3.2.0: resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== -excel-builder-webpacker@^2.1.5: - version "2.1.5" - resolved "https://registry.yarnpkg.com/excel-builder-webpacker/-/excel-builder-webpacker-2.1.5.tgz#8e5c8c40bbad5f31b9ee3ed6b657453caeba8986" - integrity sha512-78n0Qci3GmmrQY8eiTdcMm0VA66QI5dykXDLyWFt8KzpqF9nYnOYreiYSc5I2UftBrv095qdOZ0rCvR3bO8hsg== +excel-builder-webpacker@^2.1.6: + version "2.1.6" + resolved "https://registry.yarnpkg.com/excel-builder-webpacker/-/excel-builder-webpacker-2.1.6.tgz#7d318f5c25a6d60db0986778e13d01fbdb267825" + integrity sha512-hHhZ+NgzuZ6TLltDgLtNNIRXn1vToEh4TwjWkwNDDq35qjo8Dlt2Vhm7VZr1Tf76hNesyMKg0IlmahsXkYqHYw== dependencies: - jszip "3.5.0" + jszip "^3.7.1" lodash "^4.17.21" q "^1.5.1" @@ -7590,10 +7590,10 @@ jsprim@^1.2.2: json-schema "0.2.3" verror "1.10.0" -jszip@3.5.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/jszip/-/jszip-3.5.0.tgz#b4fd1f368245346658e781fec9675802489e15f6" - integrity sha512-WRtu7TPCmYePR1nazfrtuF216cIVon/3GWOvHS9QR5bIwSbnxtdpma6un3jyGGNhHsKCSzn5Ypk+EkDRvTGiFA== +jszip@^3.7.1: + version "3.7.1" + resolved "https://registry.yarnpkg.com/jszip/-/jszip-3.7.1.tgz#bd63401221c15625a1228c556ca8a68da6fda3d9" + integrity sha512-ghL0tz1XG9ZEmRMcEN2vt7xabrDdqHHeykgARpmZ0BiIctWxM47Vt63ZO2dnp4QYt/xJVLLy5Zv1l/xRdh2byg== dependencies: lie "~3.3.0" pako "~1.0.2"