@lambo-design/shared 1.0.0-beta.314 → 1.0.0-beta.316
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/package.json +1 -1
- package/styles/image/layout-header-bg-cuiwei.png +0 -0
- package/utils/excel.js +131 -76
package/package.json
CHANGED
|
Binary file
|
package/utils/excel.js
CHANGED
|
@@ -5,6 +5,10 @@ XLSX.set_cptable(cpexcel);
|
|
|
5
5
|
import {deepCopy} from "./assist";
|
|
6
6
|
import XLSXStyle from '@lambo-design/xlsx-style'
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* 表头内容转换规则
|
|
10
|
+
* @type {{'': string, '#': string, 序号: string, 操作: string, 编号: string}}
|
|
11
|
+
*/
|
|
8
12
|
const titleRules = {
|
|
9
13
|
'': '',
|
|
10
14
|
'#': '#',
|
|
@@ -12,6 +16,10 @@ const titleRules = {
|
|
|
12
16
|
'编号': '编号',
|
|
13
17
|
'操作': '操作',
|
|
14
18
|
}
|
|
19
|
+
/**
|
|
20
|
+
* 列类型转换规则
|
|
21
|
+
* @type {{'single-selection': string, select: string, selection: string, checkbox: string, index: string, radio: string}}
|
|
22
|
+
*/
|
|
15
23
|
const typeRules = {
|
|
16
24
|
'index': 'index',
|
|
17
25
|
'select': 'select',
|
|
@@ -21,6 +29,62 @@ const typeRules = {
|
|
|
21
29
|
'radio': 'radio'
|
|
22
30
|
}
|
|
23
31
|
|
|
32
|
+
/**
|
|
33
|
+
* 标题样式
|
|
34
|
+
* @type {{border: {top: {color: {rgb: string}, style: string}, left: {color: {rgb: string}, style: string}, bottom: {color: {rgb: string}, style: string}, right: {color: {rgb: string}, style: string}}, alignment: {horizontal: string, vertical: string}, fill: {fgColor: {rgb: string}, bgColor: {indexed: number}}}}
|
|
35
|
+
*/
|
|
36
|
+
let titleStyle = {
|
|
37
|
+
border: {
|
|
38
|
+
left: {style: 'thin', color: {rgb: "000000"}},
|
|
39
|
+
top: {style: 'thin', color: {rgb: "000000"}},
|
|
40
|
+
right: {style: 'thin', color: {rgb: "000000"}},
|
|
41
|
+
bottom: {style: 'thin', color: {rgb: "000000"}},
|
|
42
|
+
},
|
|
43
|
+
font: { bold: true },
|
|
44
|
+
alignment: {horizontal: "center", vertical: "center"}
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* 表头样式
|
|
48
|
+
* @type {{border: {top: {color: {rgb: string}, style: string}, left: {color: {rgb: string}, style: string}, bottom: {color: {rgb: string}, style: string}, right: {color: {rgb: string}, style: string}}, alignment: {horizontal: string, vertical: string}, fill: {fgColor: {rgb: string}, bgColor: {indexed: number}}}}
|
|
49
|
+
*/
|
|
50
|
+
let headStyle = {
|
|
51
|
+
border: {
|
|
52
|
+
left: {style: 'thin', color: {rgb: "000000"}},
|
|
53
|
+
top: {style: 'thin', color: {rgb: "000000"}},
|
|
54
|
+
right: {style: 'thin', color: {rgb: "000000"}},
|
|
55
|
+
bottom: {style: 'thin', color: {rgb: "000000"}},
|
|
56
|
+
},
|
|
57
|
+
alignment: {horizontal: "center", vertical: "center"},
|
|
58
|
+
fill: {bgColor: {indexed: 64}, fgColor: {rgb: "5A9BD5"}}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* 表格斑马纹样式
|
|
62
|
+
* @type {{border: {top: {color: {rgb: string}, style: string}, left: {color: {rgb: string}, style: string}, bottom: {color: {rgb: string}, style: string}, right: {color: {rgb: string}, style: string}}, alignment: {vertical: string}, fill: {fgColor: {rgb: string}, bgColor: {indexed: number}}}}
|
|
63
|
+
*/
|
|
64
|
+
let bodyPairStyle = {
|
|
65
|
+
border: {
|
|
66
|
+
left: {style: 'thin', color: {rgb: "000000"}},
|
|
67
|
+
top: {style: 'thin', color: {rgb: "000000"}},
|
|
68
|
+
right: {style: 'thin', color: {rgb: "000000"}},
|
|
69
|
+
bottom: {style: 'thin', color: {rgb: "000000"}},
|
|
70
|
+
},
|
|
71
|
+
alignment: {vertical: "center"},
|
|
72
|
+
fill: {bgColor: {indexed: 64}, fgColor: {rgb: "DDEBF7"}}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* 表格普通样式
|
|
76
|
+
* @type {{border: {top: {color: {rgb: string}, style: string}, left: {color: {rgb: string}, style: string}, bottom: {color: {rgb: string}, style: string}, right: {color: {rgb: string}, style: string}}, alignment: {vertical: string}}}
|
|
77
|
+
*/
|
|
78
|
+
let bodyStyle = {
|
|
79
|
+
border: {
|
|
80
|
+
left: {style: 'thin', color: {rgb: "000000"}},
|
|
81
|
+
top: {style: 'thin', color: {rgb: "000000"}},
|
|
82
|
+
right: {style: 'thin', color: {rgb: "000000"}},
|
|
83
|
+
bottom: {style: 'thin', color: {rgb: "000000"}},
|
|
84
|
+
},
|
|
85
|
+
alignment: {vertical: "center"}
|
|
86
|
+
}
|
|
87
|
+
|
|
24
88
|
/**
|
|
25
89
|
* 过滤掉filterData中titleRules、typeRules相关的列
|
|
26
90
|
* @param filterData
|
|
@@ -266,30 +330,32 @@ function auto_width(ws, data) {
|
|
|
266
330
|
ws['!cols'] = result;
|
|
267
331
|
}
|
|
268
332
|
|
|
269
|
-
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
function merge_cell({ws,data,startRow}) {
|
|
270
336
|
let mergeData = [];
|
|
271
337
|
|
|
272
|
-
for (let i = 0; i <
|
|
273
|
-
for (let j = 0; j <
|
|
274
|
-
let currentCellValue =
|
|
275
|
-
let merge = { s: { r: i, c: j }, e: { r: i, c: j } };
|
|
338
|
+
for (let i = 0; i < data.length; i++) {
|
|
339
|
+
for (let j = 0; j < data[i].length; j++) {
|
|
340
|
+
let currentCellValue = data[i][j];
|
|
341
|
+
let merge = { s: { r: i + startRow, c: j }, e: { r: i + startRow, c: j } };
|
|
276
342
|
|
|
277
343
|
// Check horizontal direction for merges
|
|
278
344
|
while (
|
|
279
|
-
j + 1 <
|
|
280
|
-
|
|
281
|
-
!isCellMerged(mergeData, { r: i, c: j + 1 })
|
|
345
|
+
j + 1 < data[i].length &&
|
|
346
|
+
data[i][j + 1] === currentCellValue &&
|
|
347
|
+
!isCellMerged(mergeData, { r: i + startRow, c: j + 1 })
|
|
282
348
|
) {
|
|
283
349
|
merge.e.c = j + 1;
|
|
284
350
|
j++;
|
|
285
351
|
}
|
|
286
352
|
|
|
287
353
|
// Check vertical direction for merges
|
|
288
|
-
let originalRow = i;
|
|
354
|
+
let originalRow = i + startRow;
|
|
289
355
|
while (
|
|
290
|
-
i + 1 <
|
|
291
|
-
|
|
292
|
-
!isCellMerged(mergeData, { r: i + 1, c: j })
|
|
356
|
+
i + 1 < data.length &&
|
|
357
|
+
data[i + 1][j] === currentCellValue &&
|
|
358
|
+
!isCellMerged(mergeData, { r: i + startRow + 1, c: j })
|
|
293
359
|
) {
|
|
294
360
|
i++;
|
|
295
361
|
|
|
@@ -321,23 +387,23 @@ function merge_title(ws,title) {
|
|
|
321
387
|
ws['!merges'] = mergeData;
|
|
322
388
|
}
|
|
323
389
|
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
390
|
+
}
|
|
391
|
+
// Helper function to check if a cell is already part of a merge range
|
|
392
|
+
function isCellMerged(mergeData, cell) {
|
|
393
|
+
for (let merge of mergeData) {
|
|
394
|
+
if (
|
|
395
|
+
cell.r >= merge.s.r &&
|
|
396
|
+
cell.r <= merge.e.r &&
|
|
397
|
+
cell.c >= merge.s.c &&
|
|
398
|
+
cell.c <= merge.e.c
|
|
399
|
+
) {
|
|
400
|
+
return true;
|
|
335
401
|
}
|
|
336
|
-
return false;
|
|
337
402
|
}
|
|
403
|
+
return false;
|
|
338
404
|
}
|
|
339
405
|
|
|
340
|
-
function merge_content(ws, tableData, spanColumnKeys,
|
|
406
|
+
function merge_content({ws, tableData, spanColumnKeys, startRow}) {
|
|
341
407
|
if (spanColumnKeys == null || spanColumnKeys.length === 0) {
|
|
342
408
|
return null;
|
|
343
409
|
}
|
|
@@ -352,7 +418,7 @@ function merge_content(ws, tableData, spanColumnKeys, titleLen) {
|
|
|
352
418
|
}
|
|
353
419
|
for (let i = 0; i < dLen; i++) {
|
|
354
420
|
for (let j = 0; j < kLen; j++) {
|
|
355
|
-
let merge = {s: {r: i +
|
|
421
|
+
let merge = {s: {r: i + startRow, c: j}, e: {r: i + startRow, c: j}}
|
|
356
422
|
flag = false
|
|
357
423
|
//如果单元格和右侧内容相同则合并
|
|
358
424
|
let n = 1;
|
|
@@ -372,7 +438,7 @@ function merge_content(ws, tableData, spanColumnKeys, titleLen) {
|
|
|
372
438
|
break
|
|
373
439
|
}
|
|
374
440
|
params[i + m][j].disable = true
|
|
375
|
-
merge.e.r = i +
|
|
441
|
+
merge.e.r = i + startRow + m
|
|
376
442
|
flag = true
|
|
377
443
|
m++;
|
|
378
444
|
}
|
|
@@ -385,7 +451,7 @@ function merge_content(ws, tableData, spanColumnKeys, titleLen) {
|
|
|
385
451
|
ws['!merges'] = ws['!merges'].concat(mergeData)
|
|
386
452
|
}
|
|
387
453
|
|
|
388
|
-
function add_style(ws, title) {
|
|
454
|
+
function add_style({ws, title, startRow}) {
|
|
389
455
|
|
|
390
456
|
// 补充空白数据
|
|
391
457
|
let rangs = ws['!ref'].split(":");
|
|
@@ -408,55 +474,35 @@ function add_style(ws, title) {
|
|
|
408
474
|
}
|
|
409
475
|
})
|
|
410
476
|
|
|
411
|
-
let
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
right: {style: 'thin', color: {rgb: "000000"}},
|
|
416
|
-
bottom: {style: 'thin', color: {rgb: "000000"}},
|
|
417
|
-
},
|
|
418
|
-
alignment: {horizontal: "center", vertical: "center"},
|
|
419
|
-
fill: {bgColor: {indexed: 64}, fgColor: {rgb: "5A9BD5"}}
|
|
420
|
-
}
|
|
421
|
-
let bodyPairStyle = {
|
|
422
|
-
border: {
|
|
423
|
-
left: {style: 'thin', color: {rgb: "000000"}},
|
|
424
|
-
top: {style: 'thin', color: {rgb: "000000"}},
|
|
425
|
-
right: {style: 'thin', color: {rgb: "000000"}},
|
|
426
|
-
bottom: {style: 'thin', color: {rgb: "000000"}},
|
|
427
|
-
},
|
|
428
|
-
alignment: {vertical: "center"},
|
|
429
|
-
fill: {bgColor: {indexed: 64}, fgColor: {rgb: "DDEBF7"}}
|
|
430
|
-
}
|
|
431
|
-
let bodyStyle = {
|
|
432
|
-
border: {
|
|
433
|
-
left: {style: 'thin', color: {rgb: "000000"}},
|
|
434
|
-
top: {style: 'thin', color: {rgb: "000000"}},
|
|
435
|
-
right: {style: 'thin', color: {rgb: "000000"}},
|
|
436
|
-
bottom: {style: 'thin', color: {rgb: "000000"}},
|
|
437
|
-
},
|
|
438
|
-
alignment: {vertical: "center"}
|
|
439
|
-
}
|
|
477
|
+
let titleReg = new RegExp("^[A-Z]1$", "im");
|
|
478
|
+
let titleExtReg = new RegExp("^[A-Z][2-" + parseInt(startRow>0?startRow:2) + "]$", "im");
|
|
479
|
+
let headReg = new RegExp("^[A-Z]+[" + parseInt(startRow + 1) + "-" + parseInt(startRow + title.length) + "]$", "im");
|
|
480
|
+
let bodyReg = new RegExp("^[A-Z]+([" + parseInt(startRow + title.length) + "-9]|[1-9]\\d+)$", "im");
|
|
440
481
|
Object.keys(ws).forEach(item => {
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
var reg = new RegExp("^[A-Z]+[1 -" + title.length + "]$", "gim");
|
|
446
|
-
if (reg.test(item)) {
|
|
482
|
+
if(titleReg.test(item)&&startRow>0){
|
|
483
|
+
/**
|
|
484
|
+
* 加载标题样式:加粗,水平垂直居中,边框
|
|
485
|
+
*/
|
|
447
486
|
ws[item].s = titleStyle
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
if (
|
|
487
|
+
}else if(titleExtReg.test(item)&&startRow>0){
|
|
488
|
+
/**
|
|
489
|
+
* 加载标题扩展信息样式:加粗,水平垂直居中,边框
|
|
490
|
+
*/
|
|
491
|
+
ws[item].s = bodyStyle
|
|
492
|
+
} else if (headReg.test(item)) {
|
|
493
|
+
/**
|
|
494
|
+
* 加载表头样式:蓝色背景,水平垂直居中,边框
|
|
495
|
+
*/
|
|
496
|
+
ws[item].s = headStyle
|
|
497
|
+
} else if (bodyReg.test(item)) {
|
|
498
|
+
/**
|
|
499
|
+
* 表体样式: 垂直居中,边框
|
|
500
|
+
*/
|
|
454
501
|
if (parseInt(item.replace(/[^0-9]/ig, "")) % 2 === 0) {
|
|
455
502
|
ws[item].s = bodyStyle
|
|
456
503
|
} else {
|
|
457
504
|
ws[item].s = bodyPairStyle
|
|
458
505
|
}
|
|
459
|
-
|
|
460
506
|
}
|
|
461
507
|
})
|
|
462
508
|
/* ws.B2 = {
|
|
@@ -495,17 +541,24 @@ export const export_json_to_excel = ({data, key, title, filename, spanColumns, a
|
|
|
495
541
|
const arr = json_to_array(key, data);
|
|
496
542
|
auto_width(ws, arr);
|
|
497
543
|
}
|
|
498
|
-
merge_content(ws, data, spanColumns)
|
|
544
|
+
merge_content(ws, data, spanColumns, title.length)
|
|
499
545
|
XLSX.utils.book_append_sheet(wb, ws, '');
|
|
500
546
|
XLSX.writeFile(wb, filename + '.' + format);
|
|
501
547
|
}
|
|
502
548
|
|
|
503
|
-
export const export_array_to_excel = ({key, data, title, filename, spanColumns, autoWidth, format}) => {
|
|
549
|
+
export const export_array_to_excel = ({key, data, title, header = [], footer = [], filename, spanColumns, autoWidth, format}) => {
|
|
504
550
|
const wb = XLSX.utils.book_new();
|
|
505
|
-
|
|
551
|
+
let arr = json_to_array(key, data);
|
|
506
552
|
for (var i = title.length; i > 0; i--) {
|
|
507
553
|
arr.unshift(title[i - 1])
|
|
508
554
|
}
|
|
555
|
+
if(header){
|
|
556
|
+
arr = [...header,...arr]
|
|
557
|
+
}
|
|
558
|
+
if(footer){
|
|
559
|
+
arr = [...arr,...footer]
|
|
560
|
+
}
|
|
561
|
+
|
|
509
562
|
const ws = XLSX.utils.aoa_to_sheet(arr);
|
|
510
563
|
if (autoWidth) {
|
|
511
564
|
auto_width(ws, arr);
|
|
@@ -513,10 +566,12 @@ export const export_array_to_excel = ({key, data, title, filename, spanColumns,
|
|
|
513
566
|
// 合并表头
|
|
514
567
|
if (!ws['!merges']) ws['!merges'] = [];
|
|
515
568
|
if (title.length > 1) {
|
|
516
|
-
|
|
569
|
+
merge_cell({ws, data:title, startRow: header.length})
|
|
517
570
|
}
|
|
518
|
-
|
|
519
|
-
|
|
571
|
+
merge_cell({ws,data:header,startRow: 0 })
|
|
572
|
+
console.log(data)
|
|
573
|
+
merge_content(ws, data, spanColumns, title.length + header.length)
|
|
574
|
+
add_style({ws, title, startRow: header.length})
|
|
520
575
|
XLSX.utils.book_append_sheet(wb, ws, '');
|
|
521
576
|
if(format === 'csv'){
|
|
522
577
|
XLSX.writeFile(wb, filename + '.' + format,{
|