export-to-exceljs-util 1.0.6 → 1.0.7

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 (3) hide show
  1. package/index.js +8 -210
  2. package/package.json +1 -1
  3. package/utils/index.js +198 -0
package/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import { saveAs } from "file-saver";
2
- import { retainTitleAndKey } from './utils/index.js'
3
2
  import DefaultExport from "./defaultExport.js";
3
+ import { workerUrl, retainTitleAndKey } from "./utils/index";
4
4
 
5
- class ExcelExporter {
5
+ class ExcelExporter1 {
6
6
  constructor(columns, data, filename = "导出数据.xlsx", describe = []) {
7
7
  this.columns = columns;
8
8
  this.data = data;
@@ -22,217 +22,15 @@ class ExcelExporter {
22
22
  }
23
23
  }
24
24
 
25
- // Web Worker 脚本代码存储在变量 workerScript 中
26
25
  async exportLargeDataSet() {
27
- const workerScript = `
28
- importScripts("https://cdn.bootcdn.net/ajax/libs/exceljs/4.4.0/exceljs.min.js");
29
- const fontStyle = {
30
- name: "Arial",
31
- size: 10,
32
- bold: true, // 设置文字加粗
33
- color: { argb: "FF000000" },
34
- };
35
- const alignmentStyle = (vertical = "middle", horizontal = "center") => {
36
- return {
37
- vertical,
38
- horizontal,
39
- };
40
- };
41
-
42
- const borderStyle = {
43
- top: { style: "thin" },
44
- left: { style: "thin" },
45
- bottom: { style: "thin" },
46
- right: { style: "thin" },
47
- };
48
-
49
- function generateHeaders(
50
- worksheet,
51
- columns,
52
- rowIndex = 1,
53
- colIndexStart = 1,
54
- maxDepth = null
55
- ) {
56
- let maxRowIndex = rowIndex;
57
- let colIndex = colIndexStart;
58
-
59
- // 计算整个表头的最大深度(用于单级表头行合并)
60
- if (maxDepth === null) {
61
- maxDepth = getMaxDepth(columns);
62
- }
63
-
64
- columns.forEach((column) => {
65
- const currentRowIndex = rowIndex;
66
- const currentColIndex = colIndex;
67
-
68
- // 计算列的跨度和行的跨度
69
- const colSpan = getColSpan(column);
70
- const rowSpan = getRowSpan(column, maxDepth - rowIndex + 1);
71
-
72
- // 设置表头单元格值并应用样式
73
- const cell = worksheet.getCell(currentRowIndex, currentColIndex);
74
- cell.value = column.title;
75
- cell.alignment = alignmentStyle();
76
- cell.border = borderStyle;
77
- cell.font = fontStyle;
78
- cell.fill = {
79
- type: "pattern",
80
- pattern: "solid",
81
- fgColor: { argb: "87CEEB" },
82
- };
83
-
84
- // 合并单元格处理
85
- if (colSpan > 1) {
86
- worksheet.mergeCells(
87
- currentRowIndex,
88
- currentColIndex,
89
- currentRowIndex,
90
- currentColIndex + colSpan - 1
91
- );
92
- }
93
-
94
- // 处理跨行合并的情况
95
- if (rowSpan > 1) {
96
- worksheet.mergeCells(
97
- currentRowIndex,
98
- currentColIndex,
99
- currentRowIndex + rowSpan - 1,
100
- currentColIndex
101
- );
102
- }
103
-
104
- // 处理子列
105
- if (column.children && column.children.length > 0) {
106
- const childMaxRowIndex = generateHeaders(
107
- worksheet,
108
- column.children,
109
- currentRowIndex + 1,
110
- currentColIndex,
111
- maxDepth
112
- );
113
- maxRowIndex = Math.max(maxRowIndex, childMaxRowIndex);
114
- } else {
115
- maxRowIndex = Math.max(maxRowIndex, currentRowIndex + rowSpan - 1);
116
- }
117
-
118
- colIndex += colSpan;
119
- });
120
-
121
- return maxRowIndex;
122
- }
123
-
124
- function getColSpan(column) {
125
- if (!column.children || column.children.length === 0) {
126
- return 1;
127
- }
128
- return column.children.reduce((sum, child) => sum + getColSpan(child), 0);
129
- }
130
-
131
- function getRowSpan(column, remainingDepth) {
132
- if (!column.children || column.children.length === 0) {
133
- return remainingDepth;
134
- }
135
- return 1;
136
- }
137
-
138
- function getMaxDepth(columns) {
139
- return columns.reduce((max, column) => {
140
- const depth = column.children ? 1 + getMaxDepth(column.children) : 1;
141
- return Math.max(max, depth);
142
- }, 1);
143
- }
144
-
145
- function fillData(worksheet, data, columns) {
146
- data.forEach((rowData) => {
147
- const row = worksheet.addRow(
148
- columns.flatMap((col) => extractValues(rowData, col))
149
- );
150
- row.eachCell((cell) => {
151
- cell.alignment = alignmentStyle();
152
- });
153
- });
154
- }
155
-
156
- function autoFitColumns(worksheet) {
157
- worksheet.columns.forEach((column) => {
158
- let maxLength = 0;
159
- column.eachCell({ includeEmpty: true }, (cell) => {
160
- const columnLength = cell.value ? cell.value.toString().length : 10;
161
- if (columnLength > maxLength) {
162
- maxLength = columnLength;
163
- }
164
- });
165
- column.width = maxLength < 10 ? maxLength + 5 : maxLength;
166
- });
167
- }
168
-
169
- function generateDescribe(worksheet, describe, data) {
170
- if (describe) {
171
- console.log('describe',describe);
172
- // 定义开始的位置
173
- const startCell = data.length + 7;
174
- const endCell = startCell + 9;
175
-
176
- // 合并单元格的范围
177
- const mergeStart = 'A' + startCell;
178
- const mergeEnd = 'E' + endCell;
179
- worksheet.mergeCells(mergeStart + ':' + mergeEnd);
180
-
181
- // 在表格底部加上文字解释
182
- let combinedText = describe
183
- const mergedCells = [
184
- 'A' + startCell,
185
- 'B' + startCell,
186
- 'C' + startCell,
187
- 'D' + startCell,
188
- 'E' + startCell,
189
- ];
190
-
191
- // 设置每个合并单元格的自动换行属性
192
- mergedCells.forEach(function(cell) {
193
- const currentCell = worksheet.getCell(cell);
194
- currentCell.value = combinedText;
195
- currentCell.font = fontStyle;
196
- currentCell.alignment = {
197
- vertical: "top",
198
- horizontal: "left",
199
- wrapText: true // 设置自动换行
200
- };
201
- });
202
- worksheet.getCell(mergeStart).border = borderStyle;
203
- }
204
- }
205
-
206
- function extractValues(rowData, column) {
207
- if (column.children && column.children.length > 0) {
208
- return column.children.flatMap((child) => extractValues(rowData, child));
209
- } else {
210
- return [rowData[column.key]];
211
- }
212
- }
213
- self.onmessage = async function (e) {
214
- const { data, columns, describe, filename } = e.data;
215
- const workbook = new ExcelJS.Workbook();
216
- const worksheet = workbook.addWorksheet("Sheet1");
217
- generateHeaders(worksheet, columns);
218
- fillData(worksheet, data, columns);
219
- generateDescribe(worksheet, describe, data);
220
- const buffer = await workbook.xlsx.writeBuffer();
221
- self.postMessage({ buffer, filename });
222
- };`;
223
-
224
- // 创建 Blob 对象
225
- const blob = new Blob([workerScript], { type: "text/javascript" });
226
-
227
- // 创建指向 Blob 的 URL
228
- const workerUrl = URL.createObjectURL(blob);
229
26
 
230
27
  // 创建 Web Worker 实例
231
28
  const writeBufferWorker = new Worker(workerUrl);
232
29
 
233
- // 剩余的代码与代码2相同
234
-
30
+ // 格式化数组数据
235
31
  const formatColumns = retainTitleAndKey(this.columns);
32
+
33
+ // 发送数据到 Web Worker
236
34
  writeBufferWorker.postMessage({
237
35
  columns: formatColumns,
238
36
  data: this.data,
@@ -240,14 +38,14 @@ class ExcelExporter {
240
38
  filename: this.filename,
241
39
  });
242
40
 
41
+ // 监听 Web Worker 的消息
243
42
  writeBufferWorker.onmessage = (e) => {
244
43
  const { buffer, filename } = e.data;
245
44
  const blob = new Blob([buffer], { type: "application/octet-stream" });
45
+ // 下载文件
246
46
  saveAs(blob, filename);
247
-
248
47
  // 释放对象 URL
249
48
  URL.revokeObjectURL(workerUrl);
250
-
251
49
  // 终止 Web Worker
252
50
  writeBufferWorker.terminate();
253
51
  };
@@ -268,4 +66,4 @@ class ExcelExporter {
268
66
  }
269
67
  }
270
68
 
271
- export default ExcelExporter;
69
+ export default ExcelExporter1;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "export-to-exceljs-util",
3
- "version": "1.0.6",
3
+ "version": "1.0.7",
4
4
  "description": "使用exceljs导出excel文件",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/utils/index.js CHANGED
@@ -21,3 +21,201 @@ export function retainTitleAndKey(items) {
21
21
  return item;
22
22
  });
23
23
  }
24
+
25
+ function getworkerUrl() {
26
+ const workerScript = `
27
+ importScripts("https://cdn.bootcdn.net/ajax/libs/exceljs/4.4.0/exceljs.min.js");
28
+ const fontStyle = {
29
+ name: "Arial",
30
+ size: 10,
31
+ bold: true, // 设置文字加粗
32
+ color: { argb: "FF000000" },
33
+ };
34
+ const alignmentStyle = (vertical = "middle", horizontal = "center") => {
35
+ return {
36
+ vertical,
37
+ horizontal,
38
+ };
39
+ };
40
+
41
+ const borderStyle = {
42
+ top: { style: "thin" },
43
+ left: { style: "thin" },
44
+ bottom: { style: "thin" },
45
+ right: { style: "thin" },
46
+ };
47
+
48
+ function generateHeaders(worksheet, columns, rowIndex = 1, colIndexStart = 1, maxDepth = null) {
49
+ let maxRowIndex = rowIndex;
50
+ let colIndex = colIndexStart;
51
+
52
+ // 计算整个表头的最大深度(用于单级表头行合并)
53
+ if (maxDepth === null) {
54
+ maxDepth = getMaxDepth(columns);
55
+ }
56
+
57
+ columns.forEach((column) => {
58
+ const currentRowIndex = rowIndex;
59
+ const currentColIndex = colIndex;
60
+
61
+ // 计算列的跨度和行的跨度
62
+ const colSpan = getColSpan(column);
63
+ const rowSpan = getRowSpan(column, maxDepth - rowIndex + 1);
64
+
65
+ // 设置表头单元格值并应用样式
66
+ const cell = worksheet.getCell(currentRowIndex, currentColIndex);
67
+ cell.value = column.title;
68
+ cell.alignment = alignmentStyle();
69
+ cell.border = borderStyle;
70
+ cell.font = fontStyle;
71
+ cell.fill = {
72
+ type: "pattern",
73
+ pattern: "solid",
74
+ fgColor: { argb: "87CEEB" },
75
+ };
76
+
77
+ // 合并单元格处理
78
+ if (colSpan > 1) {
79
+ worksheet.mergeCells(
80
+ currentRowIndex,
81
+ currentColIndex,
82
+ currentRowIndex,
83
+ currentColIndex + colSpan - 1
84
+ );
85
+ }
86
+
87
+ // 处理跨行合并的情况
88
+ if (rowSpan > 1) {
89
+ worksheet.mergeCells(
90
+ currentRowIndex,
91
+ currentColIndex,
92
+ currentRowIndex + rowSpan - 1,
93
+ currentColIndex
94
+ );
95
+ }
96
+
97
+ // 处理子列
98
+ if (column.children && column.children.length > 0) {
99
+ const childMaxRowIndex = generateHeaders(
100
+ worksheet,
101
+ column.children,
102
+ currentRowIndex + 1,
103
+ currentColIndex,
104
+ maxDepth
105
+ );
106
+ maxRowIndex = Math.max(maxRowIndex, childMaxRowIndex);
107
+ } else {
108
+ maxRowIndex = Math.max(maxRowIndex, currentRowIndex + rowSpan - 1);
109
+ }
110
+
111
+ colIndex += colSpan;
112
+ });
113
+
114
+ return maxRowIndex;
115
+ }
116
+
117
+ function getColSpan(column) {
118
+ if (!column.children || column.children.length === 0) {
119
+ return 1;
120
+ }
121
+ return column.children.reduce((sum, child) => sum + getColSpan(child), 0);
122
+ }
123
+
124
+ function getRowSpan(column, remainingDepth) {
125
+ if (!column.children || column.children.length === 0) {
126
+ return remainingDepth;
127
+ }
128
+ return 1;
129
+ }
130
+
131
+ function getMaxDepth(columns) {
132
+ return columns.reduce((max, column) => {
133
+ const depth = column.children ? 1 + getMaxDepth(column.children) : 1;
134
+ return Math.max(max, depth);
135
+ }, 1);
136
+ }
137
+
138
+ function fillData(worksheet, data, columns) {
139
+ const rows = data.map((rowData) =>
140
+ columns.flatMap((col) => extractValues(rowData, col))
141
+ );
142
+ worksheet.addRows(rows);
143
+ }
144
+
145
+ function autoFitColumns(worksheet) {
146
+ worksheet.columns.forEach((column) => {
147
+ let maxLength = 0;
148
+ column.eachCell({ includeEmpty: true }, (cell) => {
149
+ const columnLength = cell.value ? cell.value.toString().length : 10;
150
+ if (columnLength > maxLength) {
151
+ maxLength = columnLength;
152
+ }
153
+ });
154
+ column.width = maxLength < 10 ? maxLength + 5 : maxLength;
155
+ });
156
+ }
157
+
158
+ function generateDescribe(worksheet, describe, data) {
159
+ if (describe) {
160
+ console.log('describe',describe);
161
+ // 定义开始的位置
162
+ const startCell = data.length + 7;
163
+ const endCell = startCell + 9;
164
+
165
+ // 合并单元格的范围
166
+ const mergeStart = 'A' + startCell;
167
+ const mergeEnd = 'E' + endCell;
168
+ worksheet.mergeCells(mergeStart + ':' + mergeEnd);
169
+
170
+ // 在表格底部加上文字解释
171
+ let combinedText = describe.join('\\n');
172
+ const mergedCells = [
173
+ 'A' + startCell,
174
+ 'B' + startCell,
175
+ 'C' + startCell,
176
+ 'D' + startCell,
177
+ 'E' + startCell,
178
+ ];
179
+
180
+ // 设置每个合并单元格的自动换行属性
181
+ mergedCells.forEach(function(cell) {
182
+ const currentCell = worksheet.getCell(cell);
183
+ currentCell.value = combinedText;
184
+ currentCell.font = fontStyle;
185
+ currentCell.alignment = {
186
+ vertical: "top",
187
+ horizontal: "left",
188
+ wrapText: true // 设置自动换行
189
+ };
190
+ });
191
+ worksheet.getCell(mergeStart).border = borderStyle;
192
+ }
193
+ }
194
+
195
+ function extractValues(rowData, column) {
196
+ if (column.children && column.children.length > 0) {
197
+ return column.children.flatMap((child) => extractValues(rowData, child));
198
+ } else {
199
+ return [rowData[column.key]];
200
+ }
201
+ }
202
+ self.onmessage = async function (e) {
203
+ const { data, columns, describe, filename } = e.data;
204
+ const workbook = new ExcelJS.Workbook();
205
+ const worksheet = workbook.addWorksheet("Sheet1");
206
+ generateHeaders(worksheet, columns);
207
+ fillData(worksheet, data, columns);
208
+ generateDescribe(worksheet, describe, data);
209
+ const buffer = await workbook.xlsx.writeBuffer();
210
+ self.postMessage({ buffer, filename });
211
+ const endTime = performance.now();
212
+ };`;
213
+
214
+ // 创建 Blob 对象
215
+ const blob = new Blob([workerScript], { type: "text/javascript" });
216
+
217
+ // 创建指向 Blob 的 URL
218
+ return URL.createObjectURL(blob);
219
+ }
220
+
221
+ export const workerUrl = getworkerUrl();