@mui/x-data-grid-premium 7.25.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.
Files changed (49) hide show
  1. package/CHANGELOG.md +133 -0
  2. package/DataGridPremium/DataGridPremium.js +11 -4
  3. package/DataGridPremium/useDataGridPremiumComponent.js +3 -3
  4. package/esm/DataGridPremium/DataGridPremium.js +11 -4
  5. package/esm/DataGridPremium/useDataGridPremiumComponent.js +3 -3
  6. package/esm/hooks/features/aggregation/gridAggregationUtils.js +1 -1
  7. package/esm/hooks/features/aggregation/useGridAggregation.js +0 -2
  8. package/esm/hooks/features/cellSelection/useGridCellSelection.js +13 -10
  9. package/esm/hooks/features/clipboard/useGridClipboardImport.js +2 -2
  10. package/esm/hooks/features/export/index.js +1 -1
  11. package/esm/hooks/features/export/serializer/excelSerializer.js +69 -180
  12. package/esm/hooks/features/export/serializer/setupExcelExportWebWorker.js +53 -0
  13. package/esm/hooks/features/export/serializer/utils.js +93 -0
  14. package/esm/hooks/features/export/useGridExcelExport.js +11 -5
  15. package/esm/setupExcelExportWebWorker.js +1 -0
  16. package/esm/utils/releaseInfo.js +1 -1
  17. package/hooks/features/aggregation/gridAggregationUtils.js +1 -1
  18. package/hooks/features/aggregation/useGridAggregation.js +0 -2
  19. package/hooks/features/cellSelection/useGridCellSelection.js +11 -8
  20. package/hooks/features/clipboard/useGridClipboardImport.js +2 -2
  21. package/hooks/features/export/index.d.ts +1 -1
  22. package/hooks/features/export/index.js +2 -2
  23. package/hooks/features/export/serializer/excelSerializer.d.ts +3 -31
  24. package/hooks/features/export/serializer/excelSerializer.js +74 -187
  25. package/hooks/features/export/serializer/setupExcelExportWebWorker.d.ts +2 -0
  26. package/hooks/features/export/serializer/setupExcelExportWebWorker.js +59 -0
  27. package/hooks/features/export/serializer/utils.d.ts +36 -0
  28. package/hooks/features/export/serializer/utils.js +106 -0
  29. package/hooks/features/export/useGridExcelExport.js +10 -3
  30. package/hooks/utils/useGridApiContext.d.ts +3 -1
  31. package/index.js +1 -1
  32. package/modern/DataGridPremium/DataGridPremium.js +11 -4
  33. package/modern/DataGridPremium/useDataGridPremiumComponent.js +3 -3
  34. package/modern/hooks/features/aggregation/gridAggregationUtils.js +1 -1
  35. package/modern/hooks/features/aggregation/useGridAggregation.js +0 -2
  36. package/modern/hooks/features/cellSelection/useGridCellSelection.js +13 -10
  37. package/modern/hooks/features/clipboard/useGridClipboardImport.js +2 -2
  38. package/modern/hooks/features/export/index.js +1 -1
  39. package/modern/hooks/features/export/serializer/excelSerializer.js +69 -180
  40. package/modern/hooks/features/export/serializer/setupExcelExportWebWorker.js +53 -0
  41. package/modern/hooks/features/export/serializer/utils.js +93 -0
  42. package/modern/hooks/features/export/useGridExcelExport.js +11 -5
  43. package/modern/index.js +1 -1
  44. package/modern/setupExcelExportWebWorker.js +1 -0
  45. package/modern/utils/releaseInfo.js +1 -1
  46. package/package.json +5 -5
  47. package/setupExcelExportWebWorker.d.ts +1 -0
  48. package/setupExcelExportWebWorker.js +12 -0
  49. package/utils/releaseInfo.js +1 -1
@@ -2,27 +2,32 @@ import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import { GRID_DATE_COL_DEF, GRID_DATETIME_COL_DEF } from '@mui/x-data-grid-pro';
3
3
  import { isObject, isSingleSelectColDef, gridHasColSpanSelector } from '@mui/x-data-grid/internals';
4
4
  import { warnOnce } from '@mui/x-internals/warning';
5
- const getExcelJs = async () => {
6
- const excelJsModule = await import('exceljs');
7
- return excelJsModule.default ?? excelJsModule;
8
- };
9
- const getFormattedValueOptions = (colDef, row, valueOptions, api) => {
5
+ import { addColumnGroupingHeaders, addSerializedRowToWorksheet, createValueOptionsSheetIfNeeded, getExcelJs } from "./utils.js";
6
+ const getFormattedValueOptions = (colDef, row, valueOptions, api, callback) => {
10
7
  if (!colDef.valueOptions) {
11
- return [];
8
+ return;
12
9
  }
13
- let valueOptionsFormatted = valueOptions;
14
- if (colDef.valueFormatter) {
15
- valueOptionsFormatted = valueOptionsFormatted.map(option => {
10
+ const valueFormatter = colDef.valueFormatter;
11
+ for (let i = 0; i < valueOptions.length; i += 1) {
12
+ const option = valueOptions[i];
13
+ let value;
14
+ if (valueFormatter) {
16
15
  if (typeof option === 'object') {
17
- return option;
16
+ value = option.label;
17
+ } else {
18
+ value = String(colDef.valueFormatter(option, row, colDef, {
19
+ current: api
20
+ }));
18
21
  }
19
- return String(colDef.valueFormatter(option, row, colDef, {
20
- current: api
21
- }));
22
- });
22
+ } else {
23
+ value = typeof option === 'object' ? option.label : option;
24
+ }
25
+ callback(value, i);
23
26
  }
24
- return valueOptionsFormatted.map(option => typeof option === 'object' ? option.label : option);
25
27
  };
28
+ const commaRegex = /,/g;
29
+ const commaReplacement = 'CHAR(44)';
30
+
26
31
  /**
27
32
  * FIXME: This function mutates the colspan info, but colspan info assumes that the columns
28
33
  * passed to it are always consistent. In this case, the exported columns may differ from the
@@ -30,11 +35,15 @@ const getFormattedValueOptions = (colDef, row, valueOptions, api) => {
30
35
  * The caller of this function MUST call `resetColSpan()` before and after usage.
31
36
  */
32
37
  export const serializeRowUnsafe = (id, columns, apiRef, defaultValueOptionsFormulae, options) => {
33
- const row = {};
38
+ const serializedRow = {};
34
39
  const dataValidation = {};
35
40
  const mergedCells = [];
36
- const firstCellParams = apiRef.current.getCellParams(id, columns[0].field);
37
- const outlineLevel = firstCellParams.rowNode.depth;
41
+ const row = apiRef.current.getRow(id);
42
+ const rowNode = apiRef.current.getRowNode(id);
43
+ if (!row || !rowNode) {
44
+ throw new Error(`No row with id #${id} found`);
45
+ }
46
+ const outlineLevel = rowNode.depth;
38
47
  const hasColSpan = gridHasColSpanSelector(apiRef);
39
48
  if (hasColSpan) {
40
49
  // `colSpan` is only calculated for rendered rows, so we need to calculate it during export for every row
@@ -56,25 +65,32 @@ export const serializeRowUnsafe = (id, columns, apiRef, defaultValueOptionsFormu
56
65
  rightIndex: colIndex + colSpanInfo.cellProps.colSpan
57
66
  });
58
67
  }
59
- const cellParams = apiRef.current.getCellParams(id, column.field);
60
68
  let cellValue;
61
- switch (cellParams.colDef.type) {
69
+ switch (column.type) {
62
70
  case 'singleSelect':
63
71
  {
64
- const castColumn = cellParams.colDef;
72
+ const castColumn = column;
65
73
  if (typeof castColumn.valueOptions === 'function') {
66
74
  // If value option depends on the row, set specific options to the cell
67
75
  // This dataValidation is buggy with LibreOffice and does not allow to have coma
68
76
  const valueOptions = castColumn.valueOptions({
69
77
  id,
70
78
  row,
71
- field: cellParams.field
79
+ field: column.field
80
+ });
81
+ let formulae = '"';
82
+ getFormattedValueOptions(castColumn, row, valueOptions, apiRef.current, (value, index) => {
83
+ const formatted = value.toString().replace(commaRegex, commaReplacement);
84
+ formulae += formatted;
85
+ if (index < valueOptions.length - 1) {
86
+ formulae += ',';
87
+ }
72
88
  });
73
- const formattedValueOptions = getFormattedValueOptions(castColumn, row, valueOptions, apiRef.current);
89
+ formulae += '"';
74
90
  dataValidation[castColumn.field] = {
75
91
  type: 'list',
76
92
  allowBlank: true,
77
- formulae: [`"${formattedValueOptions.map(x => x.toString().replaceAll(',', 'CHAR(44)')).join(',')}"`]
93
+ formulae: [formulae]
78
94
  };
79
95
  } else {
80
96
  const address = defaultValueOptionsFormulae[column.field].address;
@@ -86,22 +102,22 @@ export const serializeRowUnsafe = (id, columns, apiRef, defaultValueOptionsFormu
86
102
  formulae: [address]
87
103
  };
88
104
  }
89
- const formattedValue = apiRef.current.getCellParams(id, castColumn.field).formattedValue;
105
+ const formattedValue = apiRef.current.getRowFormattedValue(row, castColumn);
90
106
  if (process.env.NODE_ENV !== 'production') {
91
- if (String(cellParams.formattedValue) === '[object Object]') {
107
+ if (String(formattedValue) === '[object Object]') {
92
108
  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.']);
93
109
  }
94
110
  }
95
111
  if (isObject(formattedValue)) {
96
- row[castColumn.field] = formattedValue?.label;
112
+ serializedRow[castColumn.field] = formattedValue?.label;
97
113
  } else {
98
- row[castColumn.field] = formattedValue;
114
+ serializedRow[castColumn.field] = formattedValue;
99
115
  }
100
116
  break;
101
117
  }
102
118
  case 'boolean':
103
119
  case 'number':
104
- cellValue = apiRef.current.getCellParams(id, column.field).value;
120
+ cellValue = apiRef.current.getRowValue(row, column);
105
121
  break;
106
122
  case 'date':
107
123
  case 'dateTime':
@@ -109,21 +125,21 @@ export const serializeRowUnsafe = (id, columns, apiRef, defaultValueOptionsFormu
109
125
  // Excel does not do any timezone conversion, so we create a date using UTC instead of local timezone
110
126
  // Solution from: https://github.com/exceljs/exceljs/issues/486#issuecomment-432557582
111
127
  // About Date.UTC(): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/UTC#exemples
112
- const value = apiRef.current.getCellParams(id, column.field).value;
128
+ const value = apiRef.current.getRowValue(row, column);
113
129
  // value may be `undefined` in auto-generated grouping rows
114
130
  if (!value) {
115
131
  break;
116
132
  }
117
133
  const utcDate = new Date(Date.UTC(value.getFullYear(), value.getMonth(), value.getDate(), value.getHours(), value.getMinutes(), value.getSeconds()));
118
- row[column.field] = utcDate;
134
+ serializedRow[column.field] = utcDate;
119
135
  break;
120
136
  }
121
137
  case 'actions':
122
138
  break;
123
139
  default:
124
- cellValue = apiRef.current.getCellParams(id, column.field).formattedValue;
140
+ cellValue = apiRef.current.getRowFormattedValue(row, column);
125
141
  if (process.env.NODE_ENV !== 'production') {
126
- if (String(cellParams.formattedValue) === '[object Object]') {
142
+ if (String(cellValue) === '[object Object]') {
127
143
  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.']);
128
144
  }
129
145
  }
@@ -136,11 +152,11 @@ export const serializeRowUnsafe = (id, columns, apiRef, defaultValueOptionsFormu
136
152
  }
137
153
  }
138
154
  if (typeof cellValue !== 'undefined') {
139
- row[column.field] = cellValue;
155
+ serializedRow[column.field] = cellValue;
140
156
  }
141
157
  });
142
158
  return {
143
- row,
159
+ row: serializedRow,
144
160
  dataValidation,
145
161
  outlineLevel,
146
162
  mergedCells
@@ -169,120 +185,39 @@ export const serializeColumn = (column, columnsStyles) => {
169
185
  style: _extends({}, type && defaultColumnsStyles?.[type], columnsStyles?.[field])
170
186
  };
171
187
  };
172
- const addColumnGroupingHeaders = (worksheet, columns, columnGroupPaths, columnGroupDetails) => {
173
- const maxDepth = Math.max(...columns.map(({
174
- key
175
- }) => columnGroupPaths[key]?.length ?? 0));
176
- if (maxDepth === 0) {
177
- return;
178
- }
179
- for (let rowIndex = 0; rowIndex < maxDepth; rowIndex += 1) {
180
- const row = columns.map(({
181
- key
182
- }) => {
183
- const groupingPath = columnGroupPaths[key];
184
- if (groupingPath.length <= rowIndex) {
185
- return {
186
- groupId: null,
187
- parents: groupingPath
188
- };
189
- }
190
- return _extends({}, columnGroupDetails[groupingPath[rowIndex]], {
191
- parents: groupingPath.slice(0, rowIndex)
192
- });
193
- });
194
- const newRow = worksheet.addRow(row.map(group => group.groupId === null ? null : group?.headerName ?? group.groupId));
195
-
196
- // use `rowCount`, since worksheet can have additional rows added in `exceljsPreProcess`
197
- const lastRowIndex = newRow.worksheet.rowCount;
198
- let leftIndex = 0;
199
- let rightIndex = 1;
200
- while (rightIndex < columns.length) {
201
- const {
202
- groupId: leftGroupId,
203
- parents: leftParents
204
- } = row[leftIndex];
205
- const {
206
- groupId: rightGroupId,
207
- parents: rightParents
208
- } = row[rightIndex];
209
- const areInSameGroup = leftGroupId === rightGroupId && leftParents.length === rightParents.length && leftParents.every((leftParent, index) => rightParents[index] === leftParent);
210
- if (areInSameGroup) {
211
- rightIndex += 1;
212
- } else {
213
- if (rightIndex - leftIndex > 1) {
214
- worksheet.mergeCells(lastRowIndex, leftIndex + 1, lastRowIndex, rightIndex);
215
- }
216
- leftIndex = rightIndex;
217
- rightIndex += 1;
218
- }
219
- }
220
- if (rightIndex - leftIndex > 1) {
221
- worksheet.mergeCells(lastRowIndex, leftIndex + 1, lastRowIndex, rightIndex);
222
- }
223
- }
224
- };
225
188
  export function serializeColumns(columns, styles) {
226
189
  return columns.map(column => serializeColumn(column, styles));
227
190
  }
228
191
  export async function getDataForValueOptionsSheet(columns, valueOptionsSheetName, api) {
229
- const candidateColumns = columns.filter(column => isSingleSelectColDef(column) && Array.isArray(column.valueOptions));
230
-
231
192
  // Creates a temp worksheet to obtain the column letters
232
193
  const excelJS = await getExcelJs();
233
194
  const workbook = new excelJS.Workbook();
234
195
  const worksheet = workbook.addWorksheet('Sheet1');
235
- worksheet.columns = candidateColumns.map(column => ({
236
- key: column.field
237
- }));
238
- return candidateColumns.reduce((acc, column) => {
239
- const singleSelectColumn = column;
240
- const formattedValueOptions = getFormattedValueOptions(singleSelectColumn, {}, singleSelectColumn.valueOptions, api);
196
+ const record = {};
197
+ const worksheetColumns = [];
198
+ for (let i = 0; i < columns.length; i += 1) {
199
+ const column = columns[i];
200
+ const isCandidateColumn = isSingleSelectColDef(column) && Array.isArray(column.valueOptions);
201
+ if (!isCandidateColumn) {
202
+ continue;
203
+ }
204
+ worksheetColumns.push({
205
+ key: column.field
206
+ });
207
+ worksheet.columns = worksheetColumns;
241
208
  const header = column.headerName ?? column.field;
242
- const values = [header, ...formattedValueOptions];
209
+ const values = [header];
210
+ getFormattedValueOptions(column, {}, column.valueOptions, api, value => {
211
+ values.push(value);
212
+ });
243
213
  const letter = worksheet.getColumn(column.field).letter;
244
214
  const address = `${valueOptionsSheetName}!$${letter}$2:$${letter}$${values.length}`;
245
- acc[column.field] = {
215
+ record[column.field] = {
246
216
  values,
247
217
  address
248
218
  };
249
- return acc;
250
- }, {});
251
- }
252
- function addSerializedRowToWorksheet(serializedRow, worksheet) {
253
- const {
254
- row,
255
- dataValidation,
256
- outlineLevel,
257
- mergedCells
258
- } = serializedRow;
259
- const newRow = worksheet.addRow(row);
260
- Object.keys(dataValidation).forEach(field => {
261
- newRow.getCell(field).dataValidation = _extends({}, dataValidation[field]);
262
- });
263
- if (outlineLevel) {
264
- newRow.outlineLevel = outlineLevel;
265
219
  }
266
-
267
- // use `rowCount`, since worksheet can have additional rows added in `exceljsPreProcess`
268
- const lastRowIndex = newRow.worksheet.rowCount;
269
- mergedCells.forEach(mergedCell => {
270
- worksheet.mergeCells(lastRowIndex, mergedCell.leftIndex, lastRowIndex, mergedCell.rightIndex);
271
- });
272
- }
273
- async function createValueOptionsSheetIfNeeded(valueOptionsData, sheetName, workbook) {
274
- if (Object.keys(valueOptionsData).length === 0) {
275
- return;
276
- }
277
- const valueOptionsWorksheet = workbook.addWorksheet(sheetName);
278
- valueOptionsWorksheet.columns = Object.keys(valueOptionsData).map(key => ({
279
- key
280
- }));
281
- Object.entries(valueOptionsData).forEach(([field, {
282
- values
283
- }]) => {
284
- valueOptionsWorksheet.getColumn(field).values = values;
285
- });
220
+ return record;
286
221
  }
287
222
  export async function buildExcel(options, apiRef) {
288
223
  const {
@@ -331,50 +266,4 @@ export async function buildExcel(options, apiRef) {
331
266
  });
332
267
  }
333
268
  return workbook;
334
- }
335
- export function setupExcelExportWebWorker(workerOptions = {}) {
336
- // eslint-disable-next-line no-restricted-globals
337
- addEventListener('message', async event => {
338
- const {
339
- serializedColumns,
340
- serializedRows,
341
- options,
342
- valueOptionsSheetName,
343
- valueOptionsData,
344
- columnGroupDetails,
345
- columnGroupPaths
346
- } = event.data;
347
- const {
348
- exceljsPostProcess,
349
- exceljsPreProcess
350
- } = workerOptions;
351
- const excelJS = await getExcelJs();
352
- const workbook = new excelJS.Workbook();
353
- const worksheet = workbook.addWorksheet('Sheet1');
354
- worksheet.columns = serializedColumns;
355
- if (exceljsPreProcess) {
356
- await exceljsPreProcess({
357
- workbook,
358
- worksheet
359
- });
360
- }
361
- if (options.includeColumnGroupsHeaders) {
362
- addColumnGroupingHeaders(worksheet, serializedColumns, columnGroupPaths, columnGroupDetails);
363
- }
364
- const includeHeaders = options.includeHeaders ?? true;
365
- if (includeHeaders) {
366
- worksheet.addRow(serializedColumns.map(column => column.headerText));
367
- }
368
- createValueOptionsSheetIfNeeded(valueOptionsData, valueOptionsSheetName, workbook);
369
- serializedRows.forEach(serializedRow => {
370
- addSerializedRowToWorksheet(serializedRow, worksheet);
371
- });
372
- if (exceljsPostProcess) {
373
- await exceljsPostProcess({
374
- workbook,
375
- worksheet
376
- });
377
- }
378
- postMessage(await workbook.xlsx.writeBuffer());
379
- });
380
269
  }
@@ -0,0 +1,53 @@
1
+ import { addColumnGroupingHeaders, addSerializedRowToWorksheet, createValueOptionsSheetIfNeeded, getExcelJs } from "./utils.js";
2
+ export function setupExcelExportWebWorker(workerOptions = {}) {
3
+ // eslint-disable-next-line no-restricted-globals
4
+ addEventListener('message', async event => {
5
+ const {
6
+ namespace,
7
+ serializedColumns,
8
+ serializedRows,
9
+ options,
10
+ valueOptionsSheetName,
11
+ valueOptionsData,
12
+ columnGroupDetails,
13
+ columnGroupPaths
14
+ } = event.data;
15
+
16
+ // workers share the pub-sub channel namespace. Use this property to filter out messages.
17
+ if (namespace !== 'mui-x-data-grid-export') {
18
+ return;
19
+ }
20
+ const {
21
+ exceljsPostProcess,
22
+ exceljsPreProcess
23
+ } = workerOptions;
24
+ const excelJS = await getExcelJs();
25
+ const workbook = new excelJS.Workbook();
26
+ const worksheet = workbook.addWorksheet('Sheet1');
27
+ worksheet.columns = serializedColumns;
28
+ if (exceljsPreProcess) {
29
+ await exceljsPreProcess({
30
+ workbook,
31
+ worksheet
32
+ });
33
+ }
34
+ if (options.includeColumnGroupsHeaders) {
35
+ addColumnGroupingHeaders(worksheet, serializedColumns, columnGroupPaths, columnGroupDetails);
36
+ }
37
+ const includeHeaders = options.includeHeaders ?? true;
38
+ if (includeHeaders) {
39
+ worksheet.addRow(serializedColumns.map(column => column.headerText));
40
+ }
41
+ createValueOptionsSheetIfNeeded(valueOptionsData, valueOptionsSheetName, workbook);
42
+ serializedRows.forEach(serializedRow => {
43
+ addSerializedRowToWorksheet(serializedRow, worksheet);
44
+ });
45
+ if (exceljsPostProcess) {
46
+ await exceljsPostProcess({
47
+ workbook,
48
+ worksheet
49
+ });
50
+ }
51
+ postMessage(await workbook.xlsx.writeBuffer());
52
+ });
53
+ }
@@ -0,0 +1,93 @@
1
+ import _extends from "@babel/runtime/helpers/esm/extends";
2
+ export const getExcelJs = async () => {
3
+ const excelJsModule = await import('exceljs');
4
+ return excelJsModule.default ?? excelJsModule;
5
+ };
6
+ export const addColumnGroupingHeaders = (worksheet, columns, columnGroupPaths, columnGroupDetails) => {
7
+ const maxDepth = Math.max(...columns.map(({
8
+ key
9
+ }) => columnGroupPaths[key]?.length ?? 0));
10
+ if (maxDepth === 0) {
11
+ return;
12
+ }
13
+ for (let rowIndex = 0; rowIndex < maxDepth; rowIndex += 1) {
14
+ const row = columns.map(({
15
+ key
16
+ }) => {
17
+ const groupingPath = columnGroupPaths[key];
18
+ if (groupingPath.length <= rowIndex) {
19
+ return {
20
+ groupId: null,
21
+ parents: groupingPath
22
+ };
23
+ }
24
+ return _extends({}, columnGroupDetails[groupingPath[rowIndex]], {
25
+ parents: groupingPath.slice(0, rowIndex)
26
+ });
27
+ });
28
+ const newRow = worksheet.addRow(row.map(group => group.groupId === null ? null : group?.headerName ?? group.groupId));
29
+
30
+ // use `rowCount`, since worksheet can have additional rows added in `exceljsPreProcess`
31
+ const lastRowIndex = newRow.worksheet.rowCount;
32
+ let leftIndex = 0;
33
+ let rightIndex = 1;
34
+ while (rightIndex < columns.length) {
35
+ const {
36
+ groupId: leftGroupId,
37
+ parents: leftParents
38
+ } = row[leftIndex];
39
+ const {
40
+ groupId: rightGroupId,
41
+ parents: rightParents
42
+ } = row[rightIndex];
43
+ const areInSameGroup = leftGroupId === rightGroupId && leftParents.length === rightParents.length && leftParents.every((leftParent, index) => rightParents[index] === leftParent);
44
+ if (areInSameGroup) {
45
+ rightIndex += 1;
46
+ } else {
47
+ if (rightIndex - leftIndex > 1) {
48
+ worksheet.mergeCells(lastRowIndex, leftIndex + 1, lastRowIndex, rightIndex);
49
+ }
50
+ leftIndex = rightIndex;
51
+ rightIndex += 1;
52
+ }
53
+ }
54
+ if (rightIndex - leftIndex > 1) {
55
+ worksheet.mergeCells(lastRowIndex, leftIndex + 1, lastRowIndex, rightIndex);
56
+ }
57
+ }
58
+ };
59
+ export function addSerializedRowToWorksheet(serializedRow, worksheet) {
60
+ const {
61
+ row,
62
+ dataValidation,
63
+ outlineLevel,
64
+ mergedCells
65
+ } = serializedRow;
66
+ const newRow = worksheet.addRow(row);
67
+ Object.keys(dataValidation).forEach(field => {
68
+ newRow.getCell(field).dataValidation = _extends({}, dataValidation[field]);
69
+ });
70
+ if (outlineLevel) {
71
+ newRow.outlineLevel = outlineLevel;
72
+ }
73
+
74
+ // use `rowCount`, since worksheet can have additional rows added in `exceljsPreProcess`
75
+ const lastRowIndex = newRow.worksheet.rowCount;
76
+ mergedCells.forEach(mergedCell => {
77
+ worksheet.mergeCells(lastRowIndex, mergedCell.leftIndex, lastRowIndex, mergedCell.rightIndex);
78
+ });
79
+ }
80
+ export async function createValueOptionsSheetIfNeeded(valueOptionsData, sheetName, workbook) {
81
+ if (Object.keys(valueOptionsData).length === 0) {
82
+ return;
83
+ }
84
+ const valueOptionsWorksheet = workbook.addWorksheet(sheetName);
85
+ valueOptionsWorksheet.columns = Object.keys(valueOptionsData).map(key => ({
86
+ key
87
+ }));
88
+ Object.entries(valueOptionsData).forEach(([field, {
89
+ values
90
+ }]) => {
91
+ valueOptionsWorksheet.getColumn(field).values = values;
92
+ });
93
+ }
@@ -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 = exportedRowIds.map(id => serializeRowUnsafe(id, exportedColumns, apiRef, valueOptionsData, {
93
- escapeFormulas: options.escapeFormulas ?? true
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,
package/modern/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-data-grid-premium v7.25.0
2
+ * @mui/x-data-grid-premium v7.27.0
3
3
  *
4
4
  * @license MUI X Commercial
5
5
  * This source code is licensed under the commercial license found in the
@@ -0,0 +1 @@
1
+ export { setupExcelExportWebWorker } from "./hooks/features/export/serializer/setupExcelExportWebWorker.js";
@@ -1,6 +1,6 @@
1
1
  import { ponyfillGlobal } from '@mui/utils';
2
2
  export const getReleaseInfo = () => {
3
- const releaseInfo = "MTczODI5OTYwMDAwMA==";
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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mui/x-data-grid-premium",
3
- "version": "7.25.0",
3
+ "version": "7.27.0",
4
4
  "description": "The Premium plan edition of the Data Grid Components (MUI X).",
5
5
  "author": "MUI Team",
6
6
  "main": "./index.js",
@@ -40,10 +40,10 @@
40
40
  "exceljs": "^4.4.0",
41
41
  "prop-types": "^15.8.1",
42
42
  "reselect": "^5.1.1",
43
- "@mui/x-data-grid": "7.25.0",
44
- "@mui/x-license": "7.25.0",
45
- "@mui/x-internals": "7.25.0",
46
- "@mui/x-data-grid-pro": "7.25.0"
43
+ "@mui/x-data-grid": "7.27.0",
44
+ "@mui/x-data-grid-pro": "7.27.0",
45
+ "@mui/x-license": "7.26.0",
46
+ "@mui/x-internals": "7.26.0"
47
47
  },
48
48
  "peerDependencies": {
49
49
  "@emotion/react": "^11.9.0",
@@ -0,0 +1 @@
1
+ export { setupExcelExportWebWorker } from './hooks/features/export/serializer/setupExcelExportWebWorker';
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ Object.defineProperty(exports, "setupExcelExportWebWorker", {
7
+ enumerable: true,
8
+ get: function () {
9
+ return _setupExcelExportWebWorker.setupExcelExportWebWorker;
10
+ }
11
+ });
12
+ var _setupExcelExportWebWorker = require("./hooks/features/export/serializer/setupExcelExportWebWorker");
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.getReleaseInfo = void 0;
7
7
  var _utils = require("@mui/utils");
8
8
  const getReleaseInfo = () => {
9
- const releaseInfo = "MTczODI5OTYwMDAwMA==";
9
+ const releaseInfo = "MTczOTc0NjgwMDAwMA==";
10
10
  if (process.env.NODE_ENV !== 'production') {
11
11
  // A simple hack to set the value in the test environment (has no build step).
12
12
  // eslint-disable-next-line no-useless-concat