Skip to content

Commit

Permalink
feat(ExcelExport): migrate to Excel-Builder-Vanilla (ESM)
Browse files Browse the repository at this point in the history
  • Loading branch information
ghiscoding committed Feb 12, 2024
1 parent ca4b39b commit 823317b
Show file tree
Hide file tree
Showing 9 changed files with 165 additions and 175 deletions.
1 change: 0 additions & 1 deletion angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
"allowedCommonJsDependencies": [
"autocompleter",
"dompurify",
"excel-builder-webpacker",
"fetch-jsonp",
"flatpickr",
"moment-mini",
Expand Down
16 changes: 0 additions & 16 deletions docs/getting-started/quick-start.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,18 +40,6 @@ Then modify your `angular.json` file with the following Styles and Scripts:
],
```

#### if you use `@slickgrid-universal/excel-export` you need to update your `tsconfig.app.json`
You need to change your `tsconfig.app.json` file to include `jszip` path (only required if you use the optional Slickgrid-Universal [Excel-Export](https://github.com/ghiscoding/slickgrid-universal/tree/master/packages/excel-export) package) by adding the following lines. If you forget to do this then your Angular Build will fail with a `jszip` error or `Sortable` error due to default exports that cannot be found. JSZip is used by the Excel Export to compress the data before downloading it and if you use it then the build seems to have problems finding the correct path of jszip unless we tell it where to find it.
```js
"compilerOptions": {
// ...
"allowSyntheticDefaultImports": true,
"paths": {
"jszip": ["../node_modules/jszip/dist/jszip.min.js"]
}
},
```

<a name="step3"></a>
### 3. CSS / SASS Styles
Load the default Bootstrap theme style and/or customize it to your taste (either by using SASS or CSS variables)
Expand Down Expand Up @@ -222,10 +210,8 @@ You should also add `Angular-Slickgrid` and any dependency that Angular shows a
"allowedCommonJsDependencies": [
"autocompleter",
"dompurify",
"excel-builder-webpacker",
"flatpickr",
"moment-mini",
"slickgrid",
"stream"
],
}
Expand Down Expand Up @@ -258,10 +244,8 @@ This is no longer the case. Verify if you need this module and configure a polyf
"allowedCommonJsDependencies": [
"autocompleter",
"dompurify",
"excel-builder-webpacker",
"fetch-jsonp",
"flatpickr",
"slickgrid",
"stream"
],
],
Expand Down
18 changes: 14 additions & 4 deletions docs/grid-functionalities/Export-to-Excel.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,16 @@ You can Export to Excel, it will create an Excel file with the `.xlsx` default e
### Demo
[Demo Page](https://ghiscoding.github.io/Angular-Slickgrid/#/localization) / [Demo Component](https://github.com/ghiscoding/Angular-Slickgrid/blob/master/src/app/examples/grid-localization.component.ts)

### CSP (Content Security Policy)
Since we use the library `Excel-Builder-Vanilla`, which itself uses `fflate` as a dependency, that library uses Web Worker when it can which might throw a CSP error.

The easiest way to fix this problem is to modify your CSP header by adding the rule `worker-src 'self' blob:;`

```html
<meta http-equiv="Content-Security-Policy"
content="default-src 'self'; ...other rules... worker-src 'self' blob:;" />
```

### Grid Menu (hamburger menu)
The Grid Menu already has the "Export to Excel" enabled by default, so you will see it automatically in your Grid Menu. You still have the options to show/hide from the Grid Menu if you wish
- `hideExportExcelCommand` false by default, so it's optional
Expand Down Expand Up @@ -136,7 +146,7 @@ this.gridOptions = {
```
### Styling the Header Titles
By default the header titles (first row) will be styled as Bold text, however you can choose to style them differently with custom styles as shown below. To find out what styling you can use, you can take a look [Web Archive - Excel Builder](http://web.archive.org/web/20160907052007/http://excelbuilderjs.com/cookbook/fontsAndColors.html) website. The code shown below is used in [Example 26](https://ghiscoding.github.io/Angular-Slickgrid/#/context) if you wish to see the result.
By default the header titles (first row) will be styled as Bold text, however you can choose to style them differently with custom styles as shown below. To find out what styling you can use, you can take a look at Excel Builder-Vanilla [Documentation](https://ghiscoding.gitbook.io/excel-builder-vanilla/cookbook/fonts-and-colors) website. The code shown below is used in [Example 26](https://ghiscoding.github.io/Angular-Slickgrid/#/context) if you wish to see the result.
```ts
this.gridOptions = {
Expand All @@ -150,7 +160,7 @@ this.gridOptions = {
```
### Provide a Custom Header Title
You can optionally add a custom header title, you can see the UI Sample below, (that will be shown on first row of the Excel file) through the `customExcelHeader` callback method. We use the library `Excel-Builder` to create the export, however note that this library is no longer supported (but still the best) and the documentation site no longer exist but you can find all info on [Web Archive - Excel Builder](http://web.archive.org/web/20160907052007/http://excelbuilderjs.com/cookbook/fontsAndColors.html)
You can optionally add a custom header title, you can see the UI Sample below, (that will be shown on the first row of the Excel file) through the `customExcelHeader` callback method. We use the library `Excel-Builder-Vanilla` to create the export. Visit their [Documentation](https://ghiscoding.gitbook.io/excel-builder-vanilla/) website for more info.
The example below shows a title which uses a merged cell from "B1" to "D1" with a red bold color (pay attention to the color code, you need to add an extra "FF" in front of an html color code).
#### ViewModel
Expand All @@ -163,8 +173,8 @@ export class MyExample {
externalResources: [new ExcelExportService()],
excelExportOptions: {
// optionally pass a custom header to the Excel Sheet
// a lot of the info can be found on Web Archive of Excel-Builder
// http://web.archive.org/web/20160907052007/http://excelbuilderjs.com/cookbook/fontsAndColors.html
// a lot of the info can be found on Excel-Builder-Vanilla
// https://ghiscoding.gitbook.io/excel-builder-vanilla/cookbook/fonts-and-colors
customExcelHeader: (workbook, sheet) => {
const customTitle = this.translate.currentLang === 'fr' ? 'Titre qui est suffisament long pour être coupé' : 'My header that is long enough to wrap';
const stylesheet = workbook.getStyleSheet();
Expand Down
26 changes: 25 additions & 1 deletion docs/migrations/Migration-to-7.x.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ With this new major version release, we can now say that the journey to moderniz
- TypeScript builds are now targeting ES2021 (bumped from ES2018)
- more CSP (Content Security Policy) safe
- you can create custom Formatter with native HTML element (to be more CSP safe), HTML strings are still accepted
- migrate to [Excel-Builder-Vanilla](https://github.com/ghiscoding/excel-builder-vanilla) (since >=4.4.0)
- for CSP safe, you also need to add `worker-src 'self' blob:;`

> **Note** for the full internal list of code changes applied in this Slickgrid-Universal release, you can take a look at the [Discussion - Roadmap to 4.0](https://github.com/ghiscoding/slickgrid-universal/discussions/1108)
Expand Down Expand Up @@ -46,7 +48,7 @@ Since we moved all the code into the Slickgrid-Universal project and is now writ
"allowedCommonJsDependencies": [
"autocompleter",
"dompurify",
"excel-builder-webpacker",
- "excel-builder-webpacker",
"fetch-jsonp",
"flatpickr",
- "slickgrid",
Expand All @@ -58,6 +60,7 @@ Since we moved all the code into the Slickgrid-Universal project and is now writ
- "node_modules/sortablejs/Sortable.min.js"
],
// ...
}
```

### Distribution folder
Expand Down Expand Up @@ -162,6 +165,27 @@ Some of the DomUtils Service function were renamed, if you use any of them then
- `findFirstElementAttribute` renamed to `findFirstAttribute`
- `htmlEncodedStringWithPadding` renamed to `htmlEncodeWithPadding`

### Excel Export
_requires version >=7.4.0_

Migrate to a new [Excel-Builder-Vanilla](https://github.com/ghiscoding/excel-builder-vanilla) which is a fork of the `excel-builder.js` library. The new fork is all about modernizing Excel-Builder, it drops `Q`, `Lodash` and also replace `JSZip` to `fflate`.

By migrating from `JSZip` to `fflate`, the users should remove any `JSZip` references (like `tsconfig.json`)

```diff
{
"compilerOptions": {
- "paths": {
- "jszip": [
- "node_modules/jszip/dist/jszip.min.js"
- ]
- }
}
}
```

Also note that `fflate` could use Web Worker for performance reasons and by doing this you might have new CSP errors thrown. You simply need to add a CSP rule to avoid the error `worker-src 'self' blob:;`

## Formatters / CSP (Content Security Policy) Compliance
### Formatters Cleanup & Removals
I decided to remove a bunch of Formatters (like `Formatters.bold`, `Formatters.uppercase`, ...) because they could and should be using the column `cssClass` option. Basically, I did not myself use the best practice available when creating soo many Formatters and I did not realized that we could simply use `cssClass` which is a much more efficient way and so I'm correcting this inadvertence in this new release. With that in mind, I decided to do a big cleanup in the list of Formatters to make the project a little more lightweight with less code to support and replace some of them with more generic alternatives (see below).
Expand Down
26 changes: 13 additions & 13 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,13 @@
},
"dependencies": {
"@ngx-translate/core": "^15.0.0",
"@slickgrid-universal/common": "~4.3.1",
"@slickgrid-universal/custom-footer-component": "~4.3.1",
"@slickgrid-universal/empty-warning-component": "~4.3.1",
"@slickgrid-universal/event-pub-sub": "~4.3.0",
"@slickgrid-universal/pagination-component": "~4.3.1",
"@slickgrid-universal/row-detail-view-plugin": "~4.3.1",
"@slickgrid-universal/rxjs-observable": "~4.3.1",
"@slickgrid-universal/common": "~4.4.0",
"@slickgrid-universal/custom-footer-component": "~4.4.0",
"@slickgrid-universal/empty-warning-component": "~4.4.0",
"@slickgrid-universal/event-pub-sub": "~4.4.0",
"@slickgrid-universal/pagination-component": "~4.4.0",
"@slickgrid-universal/row-detail-view-plugin": "~4.4.0",
"@slickgrid-universal/rxjs-observable": "~4.4.0",
"dequal": "^2.0.3",
"dompurify": "^3.0.8",
"rxjs": "^7.8.1",
Expand Down Expand Up @@ -87,12 +87,12 @@
"@ngx-translate/http-loader": "^8.0.0",
"@popperjs/core": "^2.11.8",
"@release-it/conventional-changelog": "^8.0.1",
"@slickgrid-universal/composite-editor-component": "~4.3.1",
"@slickgrid-universal/custom-tooltip-plugin": "~4.3.1",
"@slickgrid-universal/excel-export": "~4.3.1",
"@slickgrid-universal/graphql": "~4.3.1",
"@slickgrid-universal/odata": "~4.3.1",
"@slickgrid-universal/text-export": "~4.3.1",
"@slickgrid-universal/composite-editor-component": "~4.4.0",
"@slickgrid-universal/custom-tooltip-plugin": "~4.4.0",
"@slickgrid-universal/excel-export": "~4.4.0",
"@slickgrid-universal/graphql": "~4.4.0",
"@slickgrid-universal/odata": "~4.4.0",
"@slickgrid-universal/text-export": "~4.4.0",
"@types/dompurify": "^3.0.5",
"@types/flatpickr": "^3.1.2",
"@types/fnando__sparkline": "^0.3.7",
Expand Down
4 changes: 2 additions & 2 deletions src/app/examples/grid-localization.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,8 @@ export class GridLocalizationComponent implements OnInit, OnDestroy {
},
excelExportOptions: {
// optionally pass a custom header to the Excel Sheet
// a lot of the info can be found on Web Archive of Excel-Builder
// http://web.archive.org/web/20160907052007/http://excelbuilderjs.com/cookbook/fontsAndColors.html
// a lot of the info can be found on Excel-Builder-Vanilla
// https://ghiscoding.gitbook.io/excel-builder-vanilla/cookbook/fonts-and-colors
customExcelHeader: (workbook, sheet) => {
const customTitle = this.translate.currentLang === 'fr' ? 'Titre qui est suffisament long pour être coupé' : 'My header that is long enough to wrap';
const stylesheet = workbook.getStyleSheet();
Expand Down
12 changes: 8 additions & 4 deletions src/app/examples/grid-tree-data-hierarchical.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Component, OnInit, ViewEncapsulation } from '@angular/core';
import { ExcelExportService } from '@slickgrid-universal/excel-export';

import {
addWhiteSpaces,
AngularGridInstance,
Aggregators,
Column,
Expand Down Expand Up @@ -259,19 +260,22 @@ export class GridTreeDataHierarchicalComponent implements OnInit {
const identifierPropName = dataView.getIdPropertyName() || 'id';
const idx = dataView.getIdxById(dataContext[identifierPropName]) as number;
const prefix = this.getFileIcon(value);
const treeLevel = dataContext[treeLevelPropName];
const exportIndentationLeadingChar = '.';

value = value.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
const spacer = `<span style="display:inline-block; width:${(15 * dataContext[treeLevelPropName])}px;"></span>`;
const spacer = `<span style="display:inline-block; width:${(15 * treeLevel)}px;"></span>`;
const indentSpacer = addWhiteSpaces(5 * treeLevel);

if (data[idx + 1]?.[treeLevelPropName] > data[idx][treeLevelPropName] || data[idx]['__hasChildren']) {
const folderPrefix = `<span class="mdi icon color-alt-warning ${dataContext.__collapsed ? 'mdi-folder' : 'mdi-folder-open'}"></span>`;
if (dataContext.__collapsed) {
return `${spacer} <span class="slick-group-toggle collapsed" level="${dataContext[treeLevelPropName]}"></span>${folderPrefix} ${prefix}&nbsp;${value}`;
return `${exportIndentationLeadingChar}${spacer}${indentSpacer} <span class="slick-group-toggle collapsed" level="${treeLevel}"></span>${folderPrefix} ${prefix} ${value}`;
} else {
return `${spacer} <span class="slick-group-toggle expanded" level="${dataContext[treeLevelPropName]}"></span>${folderPrefix} ${prefix}&nbsp;${value}`;
return `${exportIndentationLeadingChar}${spacer}${indentSpacer} <span class="slick-group-toggle expanded" level="${treeLevel}"></span>${folderPrefix} ${prefix} ${value}`;
}
} else {
return `${spacer} <span class="slick-group-toggle" level="${dataContext[treeLevelPropName]}"></span>${prefix}&nbsp;${value}`;
return `${exportIndentationLeadingChar}${spacer}${indentSpacer} <span class="slick-group-toggle" level="${treeLevel}"></span>${prefix} ${value}`;
}
};

Expand Down
3 changes: 0 additions & 3 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,6 @@
"module": "es2020",
"baseUrl": "./",
"paths": {
"jszip": [
"node_modules/jszip/dist/jszip.min.js"
],
"stream": [
"./node_modules/stream-browserify"
]
Expand Down

0 comments on commit 823317b

Please sign in to comment.