@mui/x-data-grid-premium 7.26.0 → 7.27.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.
- package/CHANGELOG.md +62 -0
- package/DataGridPremium/DataGridPremium.js +6 -0
- package/DataGridPremium/useDataGridPremiumComponent.js +1 -1
- package/esm/DataGridPremium/DataGridPremium.js +6 -0
- package/esm/DataGridPremium/useDataGridPremiumComponent.js +1 -1
- package/esm/hooks/features/clipboard/useGridClipboardImport.js +2 -2
- package/esm/hooks/features/export/index.js +1 -1
- package/esm/hooks/features/export/serializer/excelSerializer.js +69 -180
- package/esm/hooks/features/export/serializer/setupExcelExportWebWorker.js +53 -0
- package/esm/hooks/features/export/serializer/utils.js +93 -0
- package/esm/hooks/features/export/useGridExcelExport.js +11 -5
- package/esm/setupExcelExportWebWorker.js +1 -0
- package/esm/utils/releaseInfo.js +1 -1
- package/hooks/features/clipboard/useGridClipboardImport.js +2 -2
- package/hooks/features/export/index.d.ts +1 -1
- package/hooks/features/export/index.js +2 -2
- package/hooks/features/export/serializer/excelSerializer.d.ts +3 -31
- package/hooks/features/export/serializer/excelSerializer.js +74 -187
- package/hooks/features/export/serializer/setupExcelExportWebWorker.d.ts +2 -0
- package/hooks/features/export/serializer/setupExcelExportWebWorker.js +59 -0
- package/hooks/features/export/serializer/utils.d.ts +36 -0
- package/hooks/features/export/serializer/utils.js +106 -0
- package/hooks/features/export/useGridExcelExport.js +10 -3
- package/index.js +1 -1
- package/modern/DataGridPremium/DataGridPremium.js +6 -0
- package/modern/DataGridPremium/useDataGridPremiumComponent.js +1 -1
- package/modern/hooks/features/clipboard/useGridClipboardImport.js +2 -2
- package/modern/hooks/features/export/index.js +1 -1
- package/modern/hooks/features/export/serializer/excelSerializer.js +69 -180
- package/modern/hooks/features/export/serializer/setupExcelExportWebWorker.js +53 -0
- package/modern/hooks/features/export/serializer/utils.js +93 -0
- package/modern/hooks/features/export/useGridExcelExport.js +11 -5
- package/modern/index.js +1 -1
- package/modern/setupExcelExportWebWorker.js +1 -0
- package/modern/utils/releaseInfo.js +1 -1
- package/package.json +3 -3
- package/setupExcelExportWebWorker.d.ts +1 -0
- package/setupExcelExportWebWorker.js +12 -0
- package/utils/releaseInfo.js +1 -1
|
@@ -5,7 +5,7 @@ import { useGridApiMethod, useGridLogger, useGridApiOptionHandler } from '@mui/x
|
|
|
5
5
|
import { useGridRegisterPipeProcessor, exportAs, getColumnsToExport, defaultGetRowsToExport } from '@mui/x-data-grid/internals';
|
|
6
6
|
import { buildExcel, getDataForValueOptionsSheet, serializeColumns, serializeRowUnsafe } from "./serializer/excelSerializer.js";
|
|
7
7
|
import { GridExcelExportMenuItem } from "../../../components/index.js";
|
|
8
|
-
|
|
8
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
9
9
|
/**
|
|
10
10
|
* @requires useGridColumns (state)
|
|
11
11
|
* @requires useGridFilter (state)
|
|
@@ -13,7 +13,6 @@ import { GridExcelExportMenuItem } from "../../../components/index.js";
|
|
|
13
13
|
* @requires useGridSelection (state)
|
|
14
14
|
* @requires useGridParamsApi (method)
|
|
15
15
|
*/
|
|
16
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
17
16
|
export const useGridExcelExport = (apiRef, props) => {
|
|
18
17
|
const logger = useGridLogger(apiRef, 'useGridExcelExport');
|
|
19
18
|
const getDataAsExcel = React.useCallback((options = {}) => {
|
|
@@ -89,15 +88,22 @@ export const useGridExcelExport = (apiRef, props) => {
|
|
|
89
88
|
const valueOptionsData = await getDataForValueOptionsSheet(exportedColumns, valueOptionsSheetName, apiRef.current);
|
|
90
89
|
const serializedColumns = serializeColumns(exportedColumns, options.columnsStyles || {});
|
|
91
90
|
apiRef.current.resetColSpan();
|
|
92
|
-
const serializedRows =
|
|
93
|
-
|
|
94
|
-
|
|
91
|
+
const serializedRows = [];
|
|
92
|
+
for (let i = 0; i < exportedRowIds.length; i += 1) {
|
|
93
|
+
const id = exportedRowIds[i];
|
|
94
|
+
const serializedRow = serializeRowUnsafe(id, exportedColumns, apiRef, valueOptionsData, {
|
|
95
|
+
escapeFormulas: options.escapeFormulas ?? true
|
|
96
|
+
});
|
|
97
|
+
serializedRows.push(serializedRow);
|
|
98
|
+
}
|
|
95
99
|
apiRef.current.resetColSpan();
|
|
96
100
|
const columnGroupPaths = exportedColumns.reduce((acc, column) => {
|
|
97
101
|
acc[column.field] = apiRef.current.getColumnGroupPath(column.field);
|
|
98
102
|
return acc;
|
|
99
103
|
}, {});
|
|
100
104
|
const message = {
|
|
105
|
+
// workers share the pub-sub channel namespace. Use this property to filter out messages.
|
|
106
|
+
namespace: 'mui-x-data-grid-export',
|
|
101
107
|
serializedColumns,
|
|
102
108
|
serializedRows,
|
|
103
109
|
valueOptionsData,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { setupExcelExportWebWorker } from "./hooks/features/export/serializer/setupExcelExportWebWorker.js";
|
package/esm/utils/releaseInfo.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ponyfillGlobal } from '@mui/utils';
|
|
2
2
|
export const getReleaseInfo = () => {
|
|
3
|
-
const releaseInfo = "
|
|
3
|
+
const releaseInfo = "MTczOTc0NjgwMDAwMA==";
|
|
4
4
|
if (process.env.NODE_ENV !== 'production') {
|
|
5
5
|
// A simple hack to set the value in the test environment (has no build step).
|
|
6
6
|
// eslint-disable-next-line no-useless-concat
|
|
@@ -263,7 +263,6 @@ const useGridClipboardImport = (apiRef, props) => {
|
|
|
263
263
|
const onProcessRowUpdateError = props.onProcessRowUpdateError;
|
|
264
264
|
const getRowId = props.getRowId;
|
|
265
265
|
const enableClipboardPaste = !props.disableClipboardPaste;
|
|
266
|
-
const rootEl = apiRef.current.rootElementRef?.current;
|
|
267
266
|
const logger = (0, _internals.useGridLogger)(apiRef, 'useGridClipboardImport');
|
|
268
267
|
const splitClipboardPastedText = props.splitClipboardPastedText;
|
|
269
268
|
const {
|
|
@@ -286,6 +285,7 @@ const useGridClipboardImport = (apiRef, props) => {
|
|
|
286
285
|
return;
|
|
287
286
|
}
|
|
288
287
|
}
|
|
288
|
+
const rootEl = apiRef.current.rootElementRef?.current;
|
|
289
289
|
if (!rootEl) {
|
|
290
290
|
return;
|
|
291
291
|
}
|
|
@@ -326,7 +326,7 @@ const useGridClipboardImport = (apiRef, props) => {
|
|
|
326
326
|
paginationMode
|
|
327
327
|
});
|
|
328
328
|
cellUpdater.applyUpdates();
|
|
329
|
-
}, [apiRef, processRowUpdate, onProcessRowUpdateError, getRowId, enableClipboardPaste,
|
|
329
|
+
}, [apiRef, processRowUpdate, onProcessRowUpdateError, getRowId, enableClipboardPaste, splitClipboardPastedText, pagination, paginationMode, onBeforeClipboardPasteStart, logger]);
|
|
330
330
|
const checkIfCanStartEditing = React.useCallback((initialValue, {
|
|
331
331
|
event
|
|
332
332
|
}) => {
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export * from './gridExcelExportInterface';
|
|
2
|
-
export { setupExcelExportWebWorker } from './serializer/
|
|
2
|
+
export { setupExcelExportWebWorker } from './serializer/setupExcelExportWebWorker';
|
|
@@ -9,7 +9,7 @@ var _exportNames = {
|
|
|
9
9
|
Object.defineProperty(exports, "setupExcelExportWebWorker", {
|
|
10
10
|
enumerable: true,
|
|
11
11
|
get: function () {
|
|
12
|
-
return
|
|
12
|
+
return _setupExcelExportWebWorker.setupExcelExportWebWorker;
|
|
13
13
|
}
|
|
14
14
|
});
|
|
15
15
|
var _gridExcelExportInterface = require("./gridExcelExportInterface");
|
|
@@ -24,4 +24,4 @@ Object.keys(_gridExcelExportInterface).forEach(function (key) {
|
|
|
24
24
|
}
|
|
25
25
|
});
|
|
26
26
|
});
|
|
27
|
-
var
|
|
27
|
+
var _setupExcelExportWebWorker = require("./serializer/setupExcelExportWebWorker");
|
|
@@ -1,18 +1,11 @@
|
|
|
1
1
|
import type * as Excel from 'exceljs';
|
|
2
2
|
import { RefObject } from '@mui/x-internals/types';
|
|
3
3
|
import { GridRowId, GridColDef } from '@mui/x-data-grid-pro';
|
|
4
|
-
import { GridStateColDef
|
|
4
|
+
import { GridStateColDef } from '@mui/x-data-grid/internals';
|
|
5
5
|
import { ColumnsStylesInterface, GridExcelExportOptions } from '../gridExcelExportInterface';
|
|
6
6
|
import { GridPrivateApiPremium } from '../../../../models/gridApiPremium';
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
dataValidation: Record<string, Excel.DataValidation>;
|
|
10
|
-
outlineLevel: number;
|
|
11
|
-
mergedCells: {
|
|
12
|
-
leftIndex: number;
|
|
13
|
-
rightIndex: number;
|
|
14
|
-
}[];
|
|
15
|
-
}
|
|
7
|
+
import { SerializedColumns, SerializedRow, ValueOptionsData } from './utils';
|
|
8
|
+
export type { ExcelExportInitEvent } from './utils';
|
|
16
9
|
/**
|
|
17
10
|
* FIXME: This function mutates the colspan info, but colspan info assumes that the columns
|
|
18
11
|
* passed to it are always consistent. In this case, the exported columns may differ from the
|
|
@@ -37,17 +30,7 @@ export declare const serializeColumn: (column: GridColDef, columnsStyles: Column
|
|
|
37
30
|
fill?: Excel.Fill | undefined;
|
|
38
31
|
};
|
|
39
32
|
};
|
|
40
|
-
type SerializedColumns = Array<{
|
|
41
|
-
key: string;
|
|
42
|
-
width: number;
|
|
43
|
-
style: Partial<Excel.Style>;
|
|
44
|
-
headerText: string;
|
|
45
|
-
}>;
|
|
46
33
|
export declare function serializeColumns(columns: GridStateColDef[], styles: ColumnsStylesInterface): SerializedColumns;
|
|
47
|
-
type ValueOptionsData = Record<string, {
|
|
48
|
-
values: (string | number)[];
|
|
49
|
-
address: string;
|
|
50
|
-
}>;
|
|
51
34
|
export declare function getDataForValueOptionsSheet(columns: GridStateColDef[], valueOptionsSheetName: string, api: GridPrivateApiPremium): Promise<ValueOptionsData>;
|
|
52
35
|
interface BuildExcelOptions extends Pick<GridExcelExportOptions, 'exceljsPreProcess' | 'exceljsPostProcess'>, Pick<Required<GridExcelExportOptions>, 'valueOptionsSheetName' | 'includeHeaders' | 'includeColumnGroupsHeaders' | 'escapeFormulas'> {
|
|
53
36
|
columns: GridStateColDef[];
|
|
@@ -55,14 +38,3 @@ interface BuildExcelOptions extends Pick<GridExcelExportOptions, 'exceljsPreProc
|
|
|
55
38
|
columnsStyles?: ColumnsStylesInterface;
|
|
56
39
|
}
|
|
57
40
|
export declare function buildExcel(options: BuildExcelOptions, apiRef: RefObject<GridPrivateApiPremium>): Promise<Excel.Workbook>;
|
|
58
|
-
export interface ExcelExportInitEvent {
|
|
59
|
-
serializedColumns: SerializedColumns;
|
|
60
|
-
serializedRows: SerializedRow[];
|
|
61
|
-
valueOptionsSheetName: string;
|
|
62
|
-
columnGroupPaths: Record<string, string[]>;
|
|
63
|
-
columnGroupDetails: GridColumnGroupLookup;
|
|
64
|
-
valueOptionsData: ValueOptionsData;
|
|
65
|
-
options: Omit<GridExcelExportOptions, 'exceljsPreProcess' | 'exceljsPostProcess' | 'columnsStyles' | 'valueOptionsSheetName'>;
|
|
66
|
-
}
|
|
67
|
-
export declare function setupExcelExportWebWorker(workerOptions?: Pick<GridExcelExportOptions, 'exceljsPostProcess' | 'exceljsPreProcess'>): void;
|
|
68
|
-
export {};
|
|
@@ -9,33 +9,36 @@ exports.getDataForValueOptionsSheet = getDataForValueOptionsSheet;
|
|
|
9
9
|
exports.serializeColumn = void 0;
|
|
10
10
|
exports.serializeColumns = serializeColumns;
|
|
11
11
|
exports.serializeRowUnsafe = void 0;
|
|
12
|
-
exports.setupExcelExportWebWorker = setupExcelExportWebWorker;
|
|
13
12
|
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
|
|
14
|
-
var _interopRequireWildcard2 = _interopRequireDefault(require("@babel/runtime/helpers/interopRequireWildcard"));
|
|
15
13
|
var _xDataGridPro = require("@mui/x-data-grid-pro");
|
|
16
14
|
var _internals = require("@mui/x-data-grid/internals");
|
|
17
15
|
var _warning = require("@mui/x-internals/warning");
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
return excelJsModule.default ?? excelJsModule;
|
|
21
|
-
};
|
|
22
|
-
const getFormattedValueOptions = (colDef, row, valueOptions, api) => {
|
|
16
|
+
var _utils = require("./utils");
|
|
17
|
+
const getFormattedValueOptions = (colDef, row, valueOptions, api, callback) => {
|
|
23
18
|
if (!colDef.valueOptions) {
|
|
24
|
-
return
|
|
19
|
+
return;
|
|
25
20
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
21
|
+
const valueFormatter = colDef.valueFormatter;
|
|
22
|
+
for (let i = 0; i < valueOptions.length; i += 1) {
|
|
23
|
+
const option = valueOptions[i];
|
|
24
|
+
let value;
|
|
25
|
+
if (valueFormatter) {
|
|
29
26
|
if (typeof option === 'object') {
|
|
30
|
-
|
|
27
|
+
value = option.label;
|
|
28
|
+
} else {
|
|
29
|
+
value = String(colDef.valueFormatter(option, row, colDef, {
|
|
30
|
+
current: api
|
|
31
|
+
}));
|
|
31
32
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
} else {
|
|
34
|
+
value = typeof option === 'object' ? option.label : option;
|
|
35
|
+
}
|
|
36
|
+
callback(value, i);
|
|
36
37
|
}
|
|
37
|
-
return valueOptionsFormatted.map(option => typeof option === 'object' ? option.label : option);
|
|
38
38
|
};
|
|
39
|
+
const commaRegex = /,/g;
|
|
40
|
+
const commaReplacement = 'CHAR(44)';
|
|
41
|
+
|
|
39
42
|
/**
|
|
40
43
|
* FIXME: This function mutates the colspan info, but colspan info assumes that the columns
|
|
41
44
|
* passed to it are always consistent. In this case, the exported columns may differ from the
|
|
@@ -43,11 +46,15 @@ const getFormattedValueOptions = (colDef, row, valueOptions, api) => {
|
|
|
43
46
|
* The caller of this function MUST call `resetColSpan()` before and after usage.
|
|
44
47
|
*/
|
|
45
48
|
const serializeRowUnsafe = (id, columns, apiRef, defaultValueOptionsFormulae, options) => {
|
|
46
|
-
const
|
|
49
|
+
const serializedRow = {};
|
|
47
50
|
const dataValidation = {};
|
|
48
51
|
const mergedCells = [];
|
|
49
|
-
const
|
|
50
|
-
const
|
|
52
|
+
const row = apiRef.current.getRow(id);
|
|
53
|
+
const rowNode = apiRef.current.getRowNode(id);
|
|
54
|
+
if (!row || !rowNode) {
|
|
55
|
+
throw new Error(`No row with id #${id} found`);
|
|
56
|
+
}
|
|
57
|
+
const outlineLevel = rowNode.depth;
|
|
51
58
|
const hasColSpan = (0, _internals.gridHasColSpanSelector)(apiRef);
|
|
52
59
|
if (hasColSpan) {
|
|
53
60
|
// `colSpan` is only calculated for rendered rows, so we need to calculate it during export for every row
|
|
@@ -69,25 +76,32 @@ const serializeRowUnsafe = (id, columns, apiRef, defaultValueOptionsFormulae, op
|
|
|
69
76
|
rightIndex: colIndex + colSpanInfo.cellProps.colSpan
|
|
70
77
|
});
|
|
71
78
|
}
|
|
72
|
-
const cellParams = apiRef.current.getCellParams(id, column.field);
|
|
73
79
|
let cellValue;
|
|
74
|
-
switch (
|
|
80
|
+
switch (column.type) {
|
|
75
81
|
case 'singleSelect':
|
|
76
82
|
{
|
|
77
|
-
const castColumn =
|
|
83
|
+
const castColumn = column;
|
|
78
84
|
if (typeof castColumn.valueOptions === 'function') {
|
|
79
85
|
// If value option depends on the row, set specific options to the cell
|
|
80
86
|
// This dataValidation is buggy with LibreOffice and does not allow to have coma
|
|
81
87
|
const valueOptions = castColumn.valueOptions({
|
|
82
88
|
id,
|
|
83
89
|
row,
|
|
84
|
-
field:
|
|
90
|
+
field: column.field
|
|
91
|
+
});
|
|
92
|
+
let formulae = '"';
|
|
93
|
+
getFormattedValueOptions(castColumn, row, valueOptions, apiRef.current, (value, index) => {
|
|
94
|
+
const formatted = value.toString().replace(commaRegex, commaReplacement);
|
|
95
|
+
formulae += formatted;
|
|
96
|
+
if (index < valueOptions.length - 1) {
|
|
97
|
+
formulae += ',';
|
|
98
|
+
}
|
|
85
99
|
});
|
|
86
|
-
|
|
100
|
+
formulae += '"';
|
|
87
101
|
dataValidation[castColumn.field] = {
|
|
88
102
|
type: 'list',
|
|
89
103
|
allowBlank: true,
|
|
90
|
-
formulae: [
|
|
104
|
+
formulae: [formulae]
|
|
91
105
|
};
|
|
92
106
|
} else {
|
|
93
107
|
const address = defaultValueOptionsFormulae[column.field].address;
|
|
@@ -99,22 +113,22 @@ const serializeRowUnsafe = (id, columns, apiRef, defaultValueOptionsFormulae, op
|
|
|
99
113
|
formulae: [address]
|
|
100
114
|
};
|
|
101
115
|
}
|
|
102
|
-
const formattedValue = apiRef.current.
|
|
116
|
+
const formattedValue = apiRef.current.getRowFormattedValue(row, castColumn);
|
|
103
117
|
if (process.env.NODE_ENV !== 'production') {
|
|
104
|
-
if (String(
|
|
118
|
+
if (String(formattedValue) === '[object Object]') {
|
|
105
119
|
(0, _warning.warnOnce)(['MUI X: When the value of a field is an object or a `renderCell` is provided, the Excel export might not display the value correctly.', 'You can provide a `valueFormatter` with a string representation to be used.']);
|
|
106
120
|
}
|
|
107
121
|
}
|
|
108
122
|
if ((0, _internals.isObject)(formattedValue)) {
|
|
109
|
-
|
|
123
|
+
serializedRow[castColumn.field] = formattedValue?.label;
|
|
110
124
|
} else {
|
|
111
|
-
|
|
125
|
+
serializedRow[castColumn.field] = formattedValue;
|
|
112
126
|
}
|
|
113
127
|
break;
|
|
114
128
|
}
|
|
115
129
|
case 'boolean':
|
|
116
130
|
case 'number':
|
|
117
|
-
cellValue = apiRef.current.
|
|
131
|
+
cellValue = apiRef.current.getRowValue(row, column);
|
|
118
132
|
break;
|
|
119
133
|
case 'date':
|
|
120
134
|
case 'dateTime':
|
|
@@ -122,21 +136,21 @@ const serializeRowUnsafe = (id, columns, apiRef, defaultValueOptionsFormulae, op
|
|
|
122
136
|
// Excel does not do any timezone conversion, so we create a date using UTC instead of local timezone
|
|
123
137
|
// Solution from: https://github.com/exceljs/exceljs/issues/486#issuecomment-432557582
|
|
124
138
|
// About Date.UTC(): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/UTC#exemples
|
|
125
|
-
const value = apiRef.current.
|
|
139
|
+
const value = apiRef.current.getRowValue(row, column);
|
|
126
140
|
// value may be `undefined` in auto-generated grouping rows
|
|
127
141
|
if (!value) {
|
|
128
142
|
break;
|
|
129
143
|
}
|
|
130
144
|
const utcDate = new Date(Date.UTC(value.getFullYear(), value.getMonth(), value.getDate(), value.getHours(), value.getMinutes(), value.getSeconds()));
|
|
131
|
-
|
|
145
|
+
serializedRow[column.field] = utcDate;
|
|
132
146
|
break;
|
|
133
147
|
}
|
|
134
148
|
case 'actions':
|
|
135
149
|
break;
|
|
136
150
|
default:
|
|
137
|
-
cellValue = apiRef.current.
|
|
151
|
+
cellValue = apiRef.current.getRowFormattedValue(row, column);
|
|
138
152
|
if (process.env.NODE_ENV !== 'production') {
|
|
139
|
-
if (String(
|
|
153
|
+
if (String(cellValue) === '[object Object]') {
|
|
140
154
|
(0, _warning.warnOnce)(['MUI X: When the value of a field is an object or a `renderCell` is provided, the Excel export might not display the value correctly.', 'You can provide a `valueFormatter` with a string representation to be used.']);
|
|
141
155
|
}
|
|
142
156
|
}
|
|
@@ -149,11 +163,11 @@ const serializeRowUnsafe = (id, columns, apiRef, defaultValueOptionsFormulae, op
|
|
|
149
163
|
}
|
|
150
164
|
}
|
|
151
165
|
if (typeof cellValue !== 'undefined') {
|
|
152
|
-
|
|
166
|
+
serializedRow[column.field] = cellValue;
|
|
153
167
|
}
|
|
154
168
|
});
|
|
155
169
|
return {
|
|
156
|
-
row,
|
|
170
|
+
row: serializedRow,
|
|
157
171
|
dataValidation,
|
|
158
172
|
outlineLevel,
|
|
159
173
|
mergedCells
|
|
@@ -184,120 +198,39 @@ const serializeColumn = (column, columnsStyles) => {
|
|
|
184
198
|
};
|
|
185
199
|
};
|
|
186
200
|
exports.serializeColumn = serializeColumn;
|
|
187
|
-
const addColumnGroupingHeaders = (worksheet, columns, columnGroupPaths, columnGroupDetails) => {
|
|
188
|
-
const maxDepth = Math.max(...columns.map(({
|
|
189
|
-
key
|
|
190
|
-
}) => columnGroupPaths[key]?.length ?? 0));
|
|
191
|
-
if (maxDepth === 0) {
|
|
192
|
-
return;
|
|
193
|
-
}
|
|
194
|
-
for (let rowIndex = 0; rowIndex < maxDepth; rowIndex += 1) {
|
|
195
|
-
const row = columns.map(({
|
|
196
|
-
key
|
|
197
|
-
}) => {
|
|
198
|
-
const groupingPath = columnGroupPaths[key];
|
|
199
|
-
if (groupingPath.length <= rowIndex) {
|
|
200
|
-
return {
|
|
201
|
-
groupId: null,
|
|
202
|
-
parents: groupingPath
|
|
203
|
-
};
|
|
204
|
-
}
|
|
205
|
-
return (0, _extends2.default)({}, columnGroupDetails[groupingPath[rowIndex]], {
|
|
206
|
-
parents: groupingPath.slice(0, rowIndex)
|
|
207
|
-
});
|
|
208
|
-
});
|
|
209
|
-
const newRow = worksheet.addRow(row.map(group => group.groupId === null ? null : group?.headerName ?? group.groupId));
|
|
210
|
-
|
|
211
|
-
// use `rowCount`, since worksheet can have additional rows added in `exceljsPreProcess`
|
|
212
|
-
const lastRowIndex = newRow.worksheet.rowCount;
|
|
213
|
-
let leftIndex = 0;
|
|
214
|
-
let rightIndex = 1;
|
|
215
|
-
while (rightIndex < columns.length) {
|
|
216
|
-
const {
|
|
217
|
-
groupId: leftGroupId,
|
|
218
|
-
parents: leftParents
|
|
219
|
-
} = row[leftIndex];
|
|
220
|
-
const {
|
|
221
|
-
groupId: rightGroupId,
|
|
222
|
-
parents: rightParents
|
|
223
|
-
} = row[rightIndex];
|
|
224
|
-
const areInSameGroup = leftGroupId === rightGroupId && leftParents.length === rightParents.length && leftParents.every((leftParent, index) => rightParents[index] === leftParent);
|
|
225
|
-
if (areInSameGroup) {
|
|
226
|
-
rightIndex += 1;
|
|
227
|
-
} else {
|
|
228
|
-
if (rightIndex - leftIndex > 1) {
|
|
229
|
-
worksheet.mergeCells(lastRowIndex, leftIndex + 1, lastRowIndex, rightIndex);
|
|
230
|
-
}
|
|
231
|
-
leftIndex = rightIndex;
|
|
232
|
-
rightIndex += 1;
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
if (rightIndex - leftIndex > 1) {
|
|
236
|
-
worksheet.mergeCells(lastRowIndex, leftIndex + 1, lastRowIndex, rightIndex);
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
};
|
|
240
201
|
function serializeColumns(columns, styles) {
|
|
241
202
|
return columns.map(column => serializeColumn(column, styles));
|
|
242
203
|
}
|
|
243
204
|
async function getDataForValueOptionsSheet(columns, valueOptionsSheetName, api) {
|
|
244
|
-
const candidateColumns = columns.filter(column => (0, _internals.isSingleSelectColDef)(column) && Array.isArray(column.valueOptions));
|
|
245
|
-
|
|
246
205
|
// Creates a temp worksheet to obtain the column letters
|
|
247
|
-
const excelJS = await getExcelJs();
|
|
206
|
+
const excelJS = await (0, _utils.getExcelJs)();
|
|
248
207
|
const workbook = new excelJS.Workbook();
|
|
249
208
|
const worksheet = workbook.addWorksheet('Sheet1');
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
const
|
|
255
|
-
|
|
209
|
+
const record = {};
|
|
210
|
+
const worksheetColumns = [];
|
|
211
|
+
for (let i = 0; i < columns.length; i += 1) {
|
|
212
|
+
const column = columns[i];
|
|
213
|
+
const isCandidateColumn = (0, _internals.isSingleSelectColDef)(column) && Array.isArray(column.valueOptions);
|
|
214
|
+
if (!isCandidateColumn) {
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
worksheetColumns.push({
|
|
218
|
+
key: column.field
|
|
219
|
+
});
|
|
220
|
+
worksheet.columns = worksheetColumns;
|
|
256
221
|
const header = column.headerName ?? column.field;
|
|
257
|
-
const values = [header
|
|
222
|
+
const values = [header];
|
|
223
|
+
getFormattedValueOptions(column, {}, column.valueOptions, api, value => {
|
|
224
|
+
values.push(value);
|
|
225
|
+
});
|
|
258
226
|
const letter = worksheet.getColumn(column.field).letter;
|
|
259
227
|
const address = `${valueOptionsSheetName}!$${letter}$2:$${letter}$${values.length}`;
|
|
260
|
-
|
|
228
|
+
record[column.field] = {
|
|
261
229
|
values,
|
|
262
230
|
address
|
|
263
231
|
};
|
|
264
|
-
return acc;
|
|
265
|
-
}, {});
|
|
266
|
-
}
|
|
267
|
-
function addSerializedRowToWorksheet(serializedRow, worksheet) {
|
|
268
|
-
const {
|
|
269
|
-
row,
|
|
270
|
-
dataValidation,
|
|
271
|
-
outlineLevel,
|
|
272
|
-
mergedCells
|
|
273
|
-
} = serializedRow;
|
|
274
|
-
const newRow = worksheet.addRow(row);
|
|
275
|
-
Object.keys(dataValidation).forEach(field => {
|
|
276
|
-
newRow.getCell(field).dataValidation = (0, _extends2.default)({}, dataValidation[field]);
|
|
277
|
-
});
|
|
278
|
-
if (outlineLevel) {
|
|
279
|
-
newRow.outlineLevel = outlineLevel;
|
|
280
232
|
}
|
|
281
|
-
|
|
282
|
-
// use `rowCount`, since worksheet can have additional rows added in `exceljsPreProcess`
|
|
283
|
-
const lastRowIndex = newRow.worksheet.rowCount;
|
|
284
|
-
mergedCells.forEach(mergedCell => {
|
|
285
|
-
worksheet.mergeCells(lastRowIndex, mergedCell.leftIndex, lastRowIndex, mergedCell.rightIndex);
|
|
286
|
-
});
|
|
287
|
-
}
|
|
288
|
-
async function createValueOptionsSheetIfNeeded(valueOptionsData, sheetName, workbook) {
|
|
289
|
-
if (Object.keys(valueOptionsData).length === 0) {
|
|
290
|
-
return;
|
|
291
|
-
}
|
|
292
|
-
const valueOptionsWorksheet = workbook.addWorksheet(sheetName);
|
|
293
|
-
valueOptionsWorksheet.columns = Object.keys(valueOptionsData).map(key => ({
|
|
294
|
-
key
|
|
295
|
-
}));
|
|
296
|
-
Object.entries(valueOptionsData).forEach(([field, {
|
|
297
|
-
values
|
|
298
|
-
}]) => {
|
|
299
|
-
valueOptionsWorksheet.getColumn(field).values = values;
|
|
300
|
-
});
|
|
233
|
+
return record;
|
|
301
234
|
}
|
|
302
235
|
async function buildExcel(options, apiRef) {
|
|
303
236
|
const {
|
|
@@ -310,7 +243,7 @@ async function buildExcel(options, apiRef) {
|
|
|
310
243
|
exceljsPostProcess,
|
|
311
244
|
columnsStyles = {}
|
|
312
245
|
} = options;
|
|
313
|
-
const excelJS = await getExcelJs();
|
|
246
|
+
const excelJS = await (0, _utils.getExcelJs)();
|
|
314
247
|
const workbook = new excelJS.Workbook();
|
|
315
248
|
const worksheet = workbook.addWorksheet('Sheet1');
|
|
316
249
|
const serializedColumns = serializeColumns(columns, columnsStyles);
|
|
@@ -326,17 +259,17 @@ async function buildExcel(options, apiRef) {
|
|
|
326
259
|
acc[column.field] = apiRef.current.getColumnGroupPath(column.field);
|
|
327
260
|
return acc;
|
|
328
261
|
}, {});
|
|
329
|
-
addColumnGroupingHeaders(worksheet, serializedColumns, columnGroupPaths, apiRef.current.getAllGroupDetails());
|
|
262
|
+
(0, _utils.addColumnGroupingHeaders)(worksheet, serializedColumns, columnGroupPaths, apiRef.current.getAllGroupDetails());
|
|
330
263
|
}
|
|
331
264
|
if (includeHeaders) {
|
|
332
265
|
worksheet.addRow(columns.map(column => column.headerName ?? column.field));
|
|
333
266
|
}
|
|
334
267
|
const valueOptionsData = await getDataForValueOptionsSheet(columns, valueOptionsSheetName, apiRef.current);
|
|
335
|
-
createValueOptionsSheetIfNeeded(valueOptionsData, valueOptionsSheetName, workbook);
|
|
268
|
+
(0, _utils.createValueOptionsSheetIfNeeded)(valueOptionsData, valueOptionsSheetName, workbook);
|
|
336
269
|
apiRef.current.resetColSpan();
|
|
337
270
|
rowIds.forEach(id => {
|
|
338
271
|
const serializedRow = serializeRowUnsafe(id, columns, apiRef, valueOptionsData, options);
|
|
339
|
-
addSerializedRowToWorksheet(serializedRow, worksheet);
|
|
272
|
+
(0, _utils.addSerializedRowToWorksheet)(serializedRow, worksheet);
|
|
340
273
|
});
|
|
341
274
|
apiRef.current.resetColSpan();
|
|
342
275
|
if (exceljsPostProcess) {
|
|
@@ -346,50 +279,4 @@ async function buildExcel(options, apiRef) {
|
|
|
346
279
|
});
|
|
347
280
|
}
|
|
348
281
|
return workbook;
|
|
349
|
-
}
|
|
350
|
-
function setupExcelExportWebWorker(workerOptions = {}) {
|
|
351
|
-
// eslint-disable-next-line no-restricted-globals
|
|
352
|
-
addEventListener('message', async event => {
|
|
353
|
-
const {
|
|
354
|
-
serializedColumns,
|
|
355
|
-
serializedRows,
|
|
356
|
-
options,
|
|
357
|
-
valueOptionsSheetName,
|
|
358
|
-
valueOptionsData,
|
|
359
|
-
columnGroupDetails,
|
|
360
|
-
columnGroupPaths
|
|
361
|
-
} = event.data;
|
|
362
|
-
const {
|
|
363
|
-
exceljsPostProcess,
|
|
364
|
-
exceljsPreProcess
|
|
365
|
-
} = workerOptions;
|
|
366
|
-
const excelJS = await getExcelJs();
|
|
367
|
-
const workbook = new excelJS.Workbook();
|
|
368
|
-
const worksheet = workbook.addWorksheet('Sheet1');
|
|
369
|
-
worksheet.columns = serializedColumns;
|
|
370
|
-
if (exceljsPreProcess) {
|
|
371
|
-
await exceljsPreProcess({
|
|
372
|
-
workbook,
|
|
373
|
-
worksheet
|
|
374
|
-
});
|
|
375
|
-
}
|
|
376
|
-
if (options.includeColumnGroupsHeaders) {
|
|
377
|
-
addColumnGroupingHeaders(worksheet, serializedColumns, columnGroupPaths, columnGroupDetails);
|
|
378
|
-
}
|
|
379
|
-
const includeHeaders = options.includeHeaders ?? true;
|
|
380
|
-
if (includeHeaders) {
|
|
381
|
-
worksheet.addRow(serializedColumns.map(column => column.headerText));
|
|
382
|
-
}
|
|
383
|
-
createValueOptionsSheetIfNeeded(valueOptionsData, valueOptionsSheetName, workbook);
|
|
384
|
-
serializedRows.forEach(serializedRow => {
|
|
385
|
-
addSerializedRowToWorksheet(serializedRow, worksheet);
|
|
386
|
-
});
|
|
387
|
-
if (exceljsPostProcess) {
|
|
388
|
-
await exceljsPostProcess({
|
|
389
|
-
workbook,
|
|
390
|
-
worksheet
|
|
391
|
-
});
|
|
392
|
-
}
|
|
393
|
-
postMessage(await workbook.xlsx.writeBuffer());
|
|
394
|
-
});
|
|
395
282
|
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.setupExcelExportWebWorker = setupExcelExportWebWorker;
|
|
7
|
+
var _utils = require("./utils");
|
|
8
|
+
function setupExcelExportWebWorker(workerOptions = {}) {
|
|
9
|
+
// eslint-disable-next-line no-restricted-globals
|
|
10
|
+
addEventListener('message', async event => {
|
|
11
|
+
const {
|
|
12
|
+
namespace,
|
|
13
|
+
serializedColumns,
|
|
14
|
+
serializedRows,
|
|
15
|
+
options,
|
|
16
|
+
valueOptionsSheetName,
|
|
17
|
+
valueOptionsData,
|
|
18
|
+
columnGroupDetails,
|
|
19
|
+
columnGroupPaths
|
|
20
|
+
} = event.data;
|
|
21
|
+
|
|
22
|
+
// workers share the pub-sub channel namespace. Use this property to filter out messages.
|
|
23
|
+
if (namespace !== 'mui-x-data-grid-export') {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const {
|
|
27
|
+
exceljsPostProcess,
|
|
28
|
+
exceljsPreProcess
|
|
29
|
+
} = workerOptions;
|
|
30
|
+
const excelJS = await (0, _utils.getExcelJs)();
|
|
31
|
+
const workbook = new excelJS.Workbook();
|
|
32
|
+
const worksheet = workbook.addWorksheet('Sheet1');
|
|
33
|
+
worksheet.columns = serializedColumns;
|
|
34
|
+
if (exceljsPreProcess) {
|
|
35
|
+
await exceljsPreProcess({
|
|
36
|
+
workbook,
|
|
37
|
+
worksheet
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
if (options.includeColumnGroupsHeaders) {
|
|
41
|
+
(0, _utils.addColumnGroupingHeaders)(worksheet, serializedColumns, columnGroupPaths, columnGroupDetails);
|
|
42
|
+
}
|
|
43
|
+
const includeHeaders = options.includeHeaders ?? true;
|
|
44
|
+
if (includeHeaders) {
|
|
45
|
+
worksheet.addRow(serializedColumns.map(column => column.headerText));
|
|
46
|
+
}
|
|
47
|
+
(0, _utils.createValueOptionsSheetIfNeeded)(valueOptionsData, valueOptionsSheetName, workbook);
|
|
48
|
+
serializedRows.forEach(serializedRow => {
|
|
49
|
+
(0, _utils.addSerializedRowToWorksheet)(serializedRow, worksheet);
|
|
50
|
+
});
|
|
51
|
+
if (exceljsPostProcess) {
|
|
52
|
+
await exceljsPostProcess({
|
|
53
|
+
workbook,
|
|
54
|
+
worksheet
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
postMessage(await workbook.xlsx.writeBuffer());
|
|
58
|
+
});
|
|
59
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type * as Excel from 'exceljs';
|
|
2
|
+
import type { GridColumnGroupLookup } from '@mui/x-data-grid/internals';
|
|
3
|
+
import type { GridExcelExportOptions } from '../gridExcelExportInterface';
|
|
4
|
+
export declare const getExcelJs: () => Promise<typeof Excel>;
|
|
5
|
+
export interface SerializedRow {
|
|
6
|
+
row: Record<string, undefined | number | boolean | string | Date>;
|
|
7
|
+
dataValidation: Record<string, Excel.DataValidation>;
|
|
8
|
+
outlineLevel: number;
|
|
9
|
+
mergedCells: {
|
|
10
|
+
leftIndex: number;
|
|
11
|
+
rightIndex: number;
|
|
12
|
+
}[];
|
|
13
|
+
}
|
|
14
|
+
export declare const addColumnGroupingHeaders: (worksheet: Excel.Worksheet, columns: SerializedColumns, columnGroupPaths: Record<string, string[]>, columnGroupDetails: GridColumnGroupLookup) => void;
|
|
15
|
+
export type SerializedColumns = Array<{
|
|
16
|
+
key: string;
|
|
17
|
+
width: number;
|
|
18
|
+
style: Partial<Excel.Style>;
|
|
19
|
+
headerText: string;
|
|
20
|
+
}>;
|
|
21
|
+
export type ValueOptionsData = Record<string, {
|
|
22
|
+
values: (string | number)[];
|
|
23
|
+
address: string;
|
|
24
|
+
}>;
|
|
25
|
+
export declare function addSerializedRowToWorksheet(serializedRow: SerializedRow, worksheet: Excel.Worksheet): void;
|
|
26
|
+
export declare function createValueOptionsSheetIfNeeded(valueOptionsData: ValueOptionsData, sheetName: string, workbook: Excel.Workbook): Promise<void>;
|
|
27
|
+
export interface ExcelExportInitEvent {
|
|
28
|
+
namespace?: string;
|
|
29
|
+
serializedColumns: SerializedColumns;
|
|
30
|
+
serializedRows: SerializedRow[];
|
|
31
|
+
valueOptionsSheetName: string;
|
|
32
|
+
columnGroupPaths: Record<string, string[]>;
|
|
33
|
+
columnGroupDetails: GridColumnGroupLookup;
|
|
34
|
+
valueOptionsData: ValueOptionsData;
|
|
35
|
+
options: Omit<GridExcelExportOptions, 'exceljsPreProcess' | 'exceljsPostProcess' | 'columnsStyles' | 'valueOptionsSheetName'>;
|
|
36
|
+
}
|