sh-view 2.8.1 → 2.8.3

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 (91) hide show
  1. package/.eslintrc.js +25 -20
  2. package/other.js +8 -8
  3. package/package.json +9 -6
  4. package/packages/components/index.js +91 -91
  5. package/packages/components/sh-alert/alert.ts +30 -0
  6. package/packages/components/sh-alert/index.vue +143 -168
  7. package/packages/components/sh-badge/index.vue +242 -242
  8. package/packages/components/sh-calendar/index.vue +650 -650
  9. package/packages/components/sh-card/index.vue +148 -148
  10. package/packages/components/sh-code-editor/index.vue +19 -19
  11. package/packages/components/sh-col/index.vue +92 -92
  12. package/packages/components/sh-corner/index.vue +230 -230
  13. package/packages/components/sh-count-to/index.vue +131 -131
  14. package/packages/components/sh-date/index.vue +301 -301
  15. package/packages/components/sh-drawer/index.vue +579 -579
  16. package/packages/components/sh-drawer/scrollbar.js +78 -78
  17. package/packages/components/sh-empty/index.vue +42 -42
  18. package/packages/components/sh-form/js/props.js +76 -76
  19. package/packages/components/sh-form/js/useForm.js +229 -229
  20. package/packages/components/sh-header/index.vue +261 -260
  21. package/packages/components/sh-icon/css/default/ionicons.svg +869 -869
  22. package/packages/components/sh-icon/css/font/iconfont.json +247 -247
  23. package/packages/components/sh-icon/index.vue +41 -41
  24. package/packages/components/sh-image/index.vue +133 -133
  25. package/packages/components/sh-list/index.vue +146 -146
  26. package/packages/components/sh-loading/index.vue +53 -53
  27. package/packages/components/sh-modal/index.vue +188 -188
  28. package/packages/components/sh-noticebar/index.vue +215 -215
  29. package/packages/components/sh-poptip/index.vue +597 -597
  30. package/packages/components/sh-progress/index.vue +276 -276
  31. package/packages/components/sh-pull-refresh/index.vue +289 -289
  32. package/packages/components/sh-result/index.vue +114 -114
  33. package/packages/components/sh-row/index.vue +66 -66
  34. package/packages/components/sh-split/components/trigger.vue +33 -33
  35. package/packages/components/sh-split/index.vue +342 -342
  36. package/packages/components/sh-table/components/importModal.vue +363 -363
  37. package/packages/components/sh-table/components/sh-column.vue +68 -68
  38. package/packages/components/sh-table/js/excel_to_json.js +313 -313
  39. package/packages/components/sh-table/js/props.js +305 -305
  40. package/packages/components/sh-table/js/tableMethods.js +167 -167
  41. package/packages/components/sh-table/js/useTable.js +636 -636
  42. package/packages/components/sh-table/table.vue +217 -217
  43. package/packages/components/sh-tabs/index.vue +426 -426
  44. package/packages/components/sh-tag/index.vue +168 -168
  45. package/packages/components/sh-toolbar/index.vue +182 -182
  46. package/packages/components/sh-tree/components/table-tree.vue +289 -289
  47. package/packages/components/sh-tree/mixin/treeProps.js +122 -122
  48. package/packages/components/sh-upload/index.vue +535 -535
  49. package/packages/components/sh-water-fall/index.vue +80 -80
  50. package/packages/components/sh-water-mark/index.vue +96 -96
  51. package/packages/css/index.js +4 -4
  52. package/packages/directive/index.js +19 -19
  53. package/packages/directive/module/click-out.js +14 -14
  54. package/packages/directive/module/draggable.js +42 -42
  55. package/packages/directive/module/line-clamp.js +22 -22
  56. package/packages/directive/module/prevent-click.js +18 -18
  57. package/packages/directive/module/resize.js +14 -14
  58. package/packages/directive/module/ripple.js +166 -166
  59. package/packages/index.js +39 -39
  60. package/packages/mixin/index.js +86 -86
  61. package/packages/other/sh-cron-modal/components/cron-content.vue +294 -294
  62. package/packages/other/sh-cron-modal/index.vue +81 -81
  63. package/packages/other/sh-cron-modal/mixin/cron-emits.js +1 -1
  64. package/packages/other/sh-cron-modal/mixin/cron-props.js +9 -9
  65. package/packages/other/sh-cron-modal/tabs/cron-week-box.vue +126 -126
  66. package/packages/other/sh-menu/index.vue +326 -326
  67. package/packages/other/sh-menu/menu-group-content.vue +136 -136
  68. package/packages/other/sh-menu/menu-item-content.vue +71 -71
  69. package/packages/other/sh-menu-card/index.vue +250 -250
  70. package/packages/other/sh-menu-card/menu-box.vue +87 -87
  71. package/packages/other/sh-preview/components/sh-excel.vue +163 -163
  72. package/packages/other/sh-preview/js/data-hook.js +41 -41
  73. package/packages/other/sh-preview/js/data-props.js +15 -15
  74. package/packages/other/sh-system-tip/index.vue +115 -115
  75. package/packages/utils/resize.js +69 -70
  76. package/packages/utils/transfer-queue.js +12 -12
  77. package/packages/vxeTable/index.js +193 -184
  78. package/packages/vxeTable/plugins/export.js +450 -450
  79. package/packages/vxeTable/render/cell/vxe-render-img.vue +27 -27
  80. package/packages/vxeTable/render/cell/vxe-render-table.vue +51 -51
  81. package/packages/vxeTable/render/cell/vxe-render-time.vue +44 -44
  82. package/packages/vxeTable/render/cell/vxe-render-tree.vue +70 -70
  83. package/packages/vxeTable/render/filters/vxe-filter-input.vue +26 -26
  84. package/packages/vxeTable/render/filters/vxe-filter-time.vue +26 -26
  85. package/packages/vxeTable/render/globalRenders.jsx +514 -514
  86. package/packages/vxeTable/render/mixin/cell-hooks.js +198 -198
  87. package/packages/vxeTable/render/mixin/cell-props.js +23 -23
  88. package/packages/vxeTable/render/mixin/filter-hooks.js +46 -46
  89. package/tsconfig.json +25 -0
  90. package/types/component.d.ts +1 -0
  91. package/types/index.ts +0 -0
@@ -1,450 +1,450 @@
1
- import XEUtils from 'xe-utils'
2
- import ExcelJS from 'exceljs'
3
-
4
- let vxetable = null
5
-
6
- const defaultHeaderBackgroundColor = '80c1ff'
7
- const defaultCellFontColor = '606266'
8
- const defaultCellBorderStyle = 'thin'
9
- const defaultCellBorderColor = 'e7f1ff'
10
-
11
- function getCellLabel(column, cellValue) {
12
- if (cellValue) {
13
- if (column.type === 'seq') {
14
- return XEUtils.toValueString(cellValue)
15
- }
16
- switch (column.cellType) {
17
- case 'string':
18
- return XEUtils.toValueString(cellValue)
19
- case 'number':
20
- if (!isNaN(cellValue)) {
21
- return Number(cellValue)
22
- }
23
- break
24
- default:
25
- if (cellValue.length < 12 && !isNaN(cellValue)) {
26
- return Number(cellValue)
27
- }
28
- break
29
- }
30
- }
31
- return cellValue
32
- }
33
-
34
- function getFooterData(opts, footerData) {
35
- const { footerFilterMethod } = opts
36
- return footerFilterMethod ? footerData.filter((items, index) => footerFilterMethod({ items, $rowIndex: index })) : footerData
37
- }
38
-
39
- function getFooterCellValue($table, opts, rows, column) {
40
- return getCellLabel(column, rows[$table.getVMColumnIndex(column)])
41
- }
42
-
43
- function getValidColumn(column) {
44
- const { childNodes } = column
45
- const isColGroup = childNodes && childNodes.length
46
- if (isColGroup) {
47
- return getValidColumn(childNodes[0])
48
- }
49
- return column
50
- }
51
-
52
- function setExcelRowHeight(excelRow, height) {
53
- if (height) {
54
- excelRow.height = XEUtils.floor(height * 0.75, 12)
55
- }
56
- }
57
-
58
- function setExcelCellStyle(excelCell, align) {
59
- excelCell.protection = {
60
- locked: false
61
- }
62
- excelCell.alignment = {
63
- vertical: 'middle',
64
- horizontal: align || 'left'
65
- }
66
- }
67
-
68
- function getDefaultBorderStyle() {
69
- return {
70
- top: {
71
- style: defaultCellBorderStyle,
72
- color: {
73
- argb: defaultCellBorderColor
74
- }
75
- },
76
- left: {
77
- style: defaultCellBorderStyle,
78
- color: {
79
- argb: defaultCellBorderColor
80
- }
81
- },
82
- bottom: {
83
- style: defaultCellBorderStyle,
84
- color: {
85
- argb: defaultCellBorderColor
86
- }
87
- },
88
- right: {
89
- style: defaultCellBorderStyle,
90
- color: {
91
- argb: defaultCellBorderColor
92
- }
93
- }
94
- }
95
- }
96
-
97
- function exportXLSX(params) {
98
- const msgKey = 'xlsx'
99
- const { modal, t } = vxetable
100
- const { $table, options, columns, colgroups, datas } = params
101
- const { props, reactData } = $table
102
- const { headerAlign: allHeaderAlign, align: allAlign, footerAlign: allFooterAlign } = props
103
- const { rowHeight } = reactData
104
- const { message, sheetName, isHeader, isFooter, isMerge, isColgroup, original, useStyle, sheetMethod } = options
105
- const showMsg = message !== false
106
- const mergeCells = $table.getMergeCells()
107
- const colList = []
108
- const footList = []
109
- const sheetCols = []
110
- const sheetMerges = []
111
- let beforeRowCount = 0
112
- let headerRowCount = 0
113
- const colHead = {}
114
- columns.forEach(column => {
115
- const { id, field, renderWidth, headerExportMethod } = column
116
- colHead[id] = headerExportMethod ? headerExportMethod({ column, $table }) : original ? field : column.getTitle()
117
- sheetCols.push({
118
- key: id,
119
- width: XEUtils.ceil(renderWidth / 8, 1)
120
- })
121
- })
122
- // 处理表头
123
- if (isHeader) {
124
- // 处理分组
125
- if (isColgroup && colgroups) {
126
- colgroups.forEach((cols, rIndex) => {
127
- const groupHead = {}
128
- columns.forEach(column => {
129
- groupHead[column.id] = null
130
- })
131
- cols.forEach(column => {
132
- const { _colSpan, _rowSpan, headerExportMethod } = column
133
- const validColumn = getValidColumn(column)
134
- const columnIndex = columns.indexOf(validColumn)
135
- groupHead[validColumn.id] = headerExportMethod ? headerExportMethod({ column, $table }) : original ? validColumn.field : column.getTitle()
136
- if (_colSpan > 1 || _rowSpan > 1) {
137
- sheetMerges.push({
138
- s: { r: rIndex, c: columnIndex },
139
- e: { r: rIndex + _rowSpan - 1, c: columnIndex + _colSpan - 1 }
140
- })
141
- }
142
- })
143
- colList.push(groupHead)
144
- })
145
- } else {
146
- colList.push(colHead)
147
- }
148
- headerRowCount = colList.length
149
- beforeRowCount += headerRowCount
150
- }
151
- // 处理合并
152
- if (isMerge) {
153
- mergeCells.forEach(mergeItem => {
154
- const { row: mergeRowIndex, rowspan: mergeRowspan, col: mergeColIndex, colspan: mergeColspan } = mergeItem
155
- sheetMerges.push({
156
- s: { r: mergeRowIndex + beforeRowCount, c: mergeColIndex },
157
- e: { r: mergeRowIndex + beforeRowCount + mergeRowspan - 1, c: mergeColIndex + mergeColspan - 1 }
158
- })
159
- })
160
- }
161
- const rowList = datas.map(item => {
162
- const rest = {}
163
- columns.forEach(column => {
164
- rest[column.id] = getCellLabel(column, item[column.id])
165
- })
166
- return rest
167
- })
168
- beforeRowCount += rowList.length
169
- // 处理表尾
170
- if (isFooter) {
171
- const { footerData } = $table.getTableData()
172
- const footers = getFooterData(options, footerData)
173
- const mergeFooterItems = $table.getMergeFooterItems()
174
- // 处理合并
175
- if (isMerge) {
176
- mergeFooterItems.forEach(mergeItem => {
177
- const { row: mergeRowIndex, rowspan: mergeRowspan, col: mergeColIndex, colspan: mergeColspan } = mergeItem
178
- sheetMerges.push({
179
- s: { r: mergeRowIndex + beforeRowCount, c: mergeColIndex },
180
- e: { r: mergeRowIndex + beforeRowCount + mergeRowspan - 1, c: mergeColIndex + mergeColspan - 1 }
181
- })
182
- })
183
- }
184
- footers.forEach(rows => {
185
- const item = {}
186
- columns.forEach(column => {
187
- item[column.id] = getFooterCellValue($table, options, rows, column)
188
- })
189
- footList.push(item)
190
- })
191
- }
192
- const exportMethod = () => {
193
- const workbook = new ExcelJS.Workbook()
194
- const sheet = workbook.addWorksheet(sheetName, { views: [{ state: 'frozen', xSplit: 0, ySplit: headerRowCount }] })
195
- workbook.creator = 'vxe-table'
196
- sheet.columns = sheetCols
197
- if (isHeader) {
198
- sheet.addRows(colList).forEach(excelRow => {
199
- if (useStyle) {
200
- setExcelRowHeight(excelRow, rowHeight)
201
- }
202
- excelRow.eachCell(excelCell => {
203
- const excelCol = sheet.getColumn(excelCell.col)
204
- const column = $table.getColumnById(excelCol.key)
205
- const { headerAlign, align } = column
206
- setExcelCellStyle(excelCell, headerAlign || align || allHeaderAlign || allAlign)
207
- Object.assign(excelCell, {
208
- font: {
209
- bold: true,
210
- color: {
211
- argb: defaultCellFontColor
212
- }
213
- },
214
- fill: {
215
- type: 'pattern',
216
- pattern: 'solid',
217
- fgColor: {
218
- argb: defaultHeaderBackgroundColor
219
- }
220
- },
221
- border: getDefaultBorderStyle()
222
- })
223
- })
224
- })
225
- }
226
- sheet.addRows(rowList).forEach(excelRow => {
227
- if (useStyle) {
228
- setExcelRowHeight(excelRow, rowHeight)
229
- }
230
- excelRow.eachCell(excelCell => {
231
- const excelCol = sheet.getColumn(excelCell.col)
232
- const column = $table.getColumnById(excelCol.key)
233
- if (column) {
234
- const { align } = column
235
- setExcelCellStyle(excelCell, align || allAlign)
236
- if (useStyle) {
237
- Object.assign(excelCell, {
238
- font: {
239
- color: {
240
- argb: defaultCellFontColor
241
- }
242
- },
243
- border: getDefaultBorderStyle()
244
- })
245
- }
246
- }
247
- })
248
- })
249
- if (isFooter) {
250
- sheet.addRows(footList).forEach(excelRow => {
251
- if (useStyle) {
252
- setExcelRowHeight(excelRow, rowHeight)
253
- }
254
- excelRow.eachCell(excelCell => {
255
- const excelCol = sheet.getColumn(excelCell.col)
256
- const column = $table.getColumnById(excelCol.key)
257
- if (column) {
258
- const { footerAlign, align } = column
259
- setExcelCellStyle(excelCell, footerAlign || align || allFooterAlign || allAlign)
260
- if (useStyle) {
261
- Object.assign(excelCell, {
262
- font: {
263
- color: {
264
- argb: defaultCellFontColor
265
- }
266
- },
267
- border: getDefaultBorderStyle()
268
- })
269
- }
270
- }
271
- })
272
- })
273
- }
274
- if (useStyle && sheetMethod) {
275
- sheetMethod({ options: options, workbook, worksheet: sheet, columns, colgroups, datas, $table })
276
- }
277
- sheetMerges.forEach(({ s, e }) => {
278
- sheet.mergeCells(s.r + 1, s.c + 1, e.r + 1, e.c + 1)
279
- })
280
- workbook.xlsx.writeBuffer().then(buffer => {
281
- const blob = new Blob([buffer], { type: 'application/octet-stream' })
282
- // 导出 xlsx
283
- downloadFile(params, blob, options)
284
- if (showMsg && modal) {
285
- modal.close(msgKey)
286
- modal.message({ content: t('vxe.table.expSuccess'), status: 'success' })
287
- }
288
- })
289
- }
290
- if (showMsg && modal) {
291
- modal.message({ id: msgKey, content: t('vxe.table.expLoading'), status: 'loading', duration: -1 })
292
- setTimeout(exportMethod, 1500)
293
- } else {
294
- exportMethod()
295
- }
296
- }
297
-
298
- function downloadFile(params, blob, options) {
299
- const { modal, t } = vxetable
300
- const { message, filename, type } = options
301
- const showMsg = message !== false
302
- if (window.Blob) {
303
- if (navigator.msSaveBlob) {
304
- navigator.msSaveBlob(blob, `${filename}.${type}`)
305
- } else {
306
- const linkElem = document.createElement('a')
307
- linkElem.target = '_blank'
308
- linkElem.download = `${filename}.${type}`
309
- linkElem.href = URL.createObjectURL(blob)
310
- document.body.appendChild(linkElem)
311
- linkElem.click()
312
- document.body.removeChild(linkElem)
313
- }
314
- } else {
315
- if (showMsg && modal) {
316
- modal.alert({ content: t('vxe.error.notExp'), status: 'error' })
317
- }
318
- }
319
- }
320
-
321
- function checkImportData(tableFields, fields) {
322
- return fields.some(field => tableFields.indexOf(field) > -1)
323
- }
324
-
325
- function importError(params) {
326
- const { modal, t } = vxetable
327
- const { $table, options } = params
328
- const { internalData } = $table
329
- const { _importReject } = internalData
330
- const showMsg = options.message !== false
331
- if (showMsg && modal) {
332
- modal.message({ content: t('vxe.error.impFields'), status: 'error' })
333
- }
334
- if (_importReject) {
335
- _importReject({ status: false })
336
- }
337
- }
338
-
339
- function importXLSX(params) {
340
- const { modal, t } = vxetable
341
- const { $table, columns, options, file } = params
342
- const { internalData } = $table
343
- const { _importResolve } = internalData
344
- const showMsg = options.message !== false
345
- const fileReader = new FileReader()
346
- fileReader.onerror = () => {
347
- importError(params)
348
- }
349
- fileReader.onload = evnt => {
350
- const tableFields = []
351
- columns.forEach(column => {
352
- const field = column.field
353
- if (field) {
354
- tableFields.push(field)
355
- }
356
- })
357
- const workbook = new ExcelJS.Workbook()
358
- const readerTarget = evnt.target
359
- if (readerTarget) {
360
- workbook.xlsx.load(readerTarget.result).then(wb => {
361
- const firstSheet = wb.worksheets[0]
362
- if (firstSheet) {
363
- const sheetValues = firstSheet.getSheetValues()
364
- const fieldIndex = XEUtils.findIndexOf(sheetValues, list => list && list.length > 0)
365
- const fields = sheetValues[fieldIndex]
366
- const status = checkImportData(tableFields, fields)
367
- if (status) {
368
- const records = sheetValues.slice(fieldIndex).map(list => {
369
- const item = {}
370
- list.forEach((cellValue, cIndex) => {
371
- item[fields[cIndex]] = cellValue
372
- })
373
- const record = {}
374
- tableFields.forEach(field => {
375
- record[field] = XEUtils.isUndefined(item[field]) ? null : item[field]
376
- })
377
- return record
378
- })
379
- $table.createData(records).then(data => {
380
- let loadRest = null
381
- if (options.mode === 'insert') {
382
- loadRest = $table.insertAt(data, -1)
383
- } else {
384
- loadRest = $table.reloadData(data)
385
- }
386
- return loadRest.then(() => {
387
- if (_importResolve) {
388
- _importResolve({ status: true })
389
- }
390
- })
391
- })
392
- if (showMsg && modal) {
393
- modal.message({ content: t('vxe.table.impSuccess', [records.length]), status: 'success' })
394
- }
395
- } else {
396
- importError(params)
397
- }
398
- } else {
399
- importError(params)
400
- }
401
- })
402
- } else {
403
- importError(params)
404
- }
405
- }
406
- fileReader.readAsArrayBuffer(file)
407
- }
408
-
409
- function handleImportEvent(params) {
410
- if (params.options.type === 'xlsx') {
411
- importXLSX(params)
412
- return false
413
- }
414
- }
415
-
416
- function handleExportEvent(params) {
417
- if (params.options.type === 'xlsx') {
418
- exportXLSX(params)
419
- return false
420
- }
421
- }
422
-
423
- /**
424
- * 基于 vxe-table 表格的增强插件,支持导出 xlsx 格式
425
- */
426
- export const VXETablePluginExportXLSX = {
427
- install(vxetablecore) {
428
- const { setup, interceptor } = vxetablecore
429
-
430
- vxetable = vxetablecore
431
-
432
- setup({
433
- export: {
434
- types: {
435
- xlsx: 0
436
- }
437
- }
438
- })
439
- interceptor.mixin({
440
- 'event.import': handleImportEvent,
441
- 'event.export': handleExportEvent
442
- })
443
- }
444
- }
445
-
446
- if (typeof window !== 'undefined' && window.VXETable && window.VXETable.use) {
447
- window.VXETable.use(VXETablePluginExportXLSX)
448
- }
449
-
450
- export default VXETablePluginExportXLSX
1
+ import XEUtils from 'xe-utils'
2
+ import ExcelJS from 'exceljs'
3
+
4
+ let vxetable = null
5
+
6
+ const defaultHeaderBackgroundColor = '80c1ff'
7
+ const defaultCellFontColor = '606266'
8
+ const defaultCellBorderStyle = 'thin'
9
+ const defaultCellBorderColor = 'e7f1ff'
10
+
11
+ function getCellLabel(column, cellValue) {
12
+ if (cellValue) {
13
+ if (column.type === 'seq') {
14
+ return XEUtils.toValueString(cellValue)
15
+ }
16
+ switch (column.cellType) {
17
+ case 'string':
18
+ return XEUtils.toValueString(cellValue)
19
+ case 'number':
20
+ if (!isNaN(cellValue)) {
21
+ return Number(cellValue)
22
+ }
23
+ break
24
+ default:
25
+ if (cellValue.length < 12 && !isNaN(cellValue)) {
26
+ return Number(cellValue)
27
+ }
28
+ break
29
+ }
30
+ }
31
+ return cellValue
32
+ }
33
+
34
+ function getFooterData(opts, footerData) {
35
+ const { footerFilterMethod } = opts
36
+ return footerFilterMethod ? footerData.filter((items, index) => footerFilterMethod({ items, $rowIndex: index })) : footerData
37
+ }
38
+
39
+ function getFooterCellValue($table, opts, rows, column) {
40
+ return getCellLabel(column, rows[$table.getVMColumnIndex(column)])
41
+ }
42
+
43
+ function getValidColumn(column) {
44
+ const { childNodes } = column
45
+ const isColGroup = childNodes && childNodes.length
46
+ if (isColGroup) {
47
+ return getValidColumn(childNodes[0])
48
+ }
49
+ return column
50
+ }
51
+
52
+ function setExcelRowHeight(excelRow, height) {
53
+ if (height) {
54
+ excelRow.height = XEUtils.floor(height * 0.75, 12)
55
+ }
56
+ }
57
+
58
+ function setExcelCellStyle(excelCell, align) {
59
+ excelCell.protection = {
60
+ locked: false
61
+ }
62
+ excelCell.alignment = {
63
+ vertical: 'middle',
64
+ horizontal: align || 'left'
65
+ }
66
+ }
67
+
68
+ function getDefaultBorderStyle() {
69
+ return {
70
+ top: {
71
+ style: defaultCellBorderStyle,
72
+ color: {
73
+ argb: defaultCellBorderColor
74
+ }
75
+ },
76
+ left: {
77
+ style: defaultCellBorderStyle,
78
+ color: {
79
+ argb: defaultCellBorderColor
80
+ }
81
+ },
82
+ bottom: {
83
+ style: defaultCellBorderStyle,
84
+ color: {
85
+ argb: defaultCellBorderColor
86
+ }
87
+ },
88
+ right: {
89
+ style: defaultCellBorderStyle,
90
+ color: {
91
+ argb: defaultCellBorderColor
92
+ }
93
+ }
94
+ }
95
+ }
96
+
97
+ function exportXLSX(params) {
98
+ const msgKey = 'xlsx'
99
+ const { modal, t } = vxetable
100
+ const { $table, options, columns, colgroups, datas } = params
101
+ const { props, reactData } = $table
102
+ const { headerAlign: allHeaderAlign, align: allAlign, footerAlign: allFooterAlign } = props
103
+ const { rowHeight } = reactData
104
+ const { message, sheetName, isHeader, isFooter, isMerge, isColgroup, original, useStyle, sheetMethod } = options
105
+ const showMsg = message !== false
106
+ const mergeCells = $table.getMergeCells()
107
+ const colList = []
108
+ const footList = []
109
+ const sheetCols = []
110
+ const sheetMerges = []
111
+ let beforeRowCount = 0
112
+ let headerRowCount = 0
113
+ const colHead = {}
114
+ columns.forEach(column => {
115
+ const { id, field, renderWidth, headerExportMethod } = column
116
+ colHead[id] = headerExportMethod ? headerExportMethod({ column, $table }) : original ? field : column.getTitle()
117
+ sheetCols.push({
118
+ key: id,
119
+ width: XEUtils.ceil(renderWidth / 8, 1)
120
+ })
121
+ })
122
+ // 处理表头
123
+ if (isHeader) {
124
+ // 处理分组
125
+ if (isColgroup && colgroups) {
126
+ colgroups.forEach((cols, rIndex) => {
127
+ const groupHead = {}
128
+ columns.forEach(column => {
129
+ groupHead[column.id] = null
130
+ })
131
+ cols.forEach(column => {
132
+ const { _colSpan, _rowSpan, headerExportMethod } = column
133
+ const validColumn = getValidColumn(column)
134
+ const columnIndex = columns.indexOf(validColumn)
135
+ groupHead[validColumn.id] = headerExportMethod ? headerExportMethod({ column, $table }) : original ? validColumn.field : column.getTitle()
136
+ if (_colSpan > 1 || _rowSpan > 1) {
137
+ sheetMerges.push({
138
+ s: { r: rIndex, c: columnIndex },
139
+ e: { r: rIndex + _rowSpan - 1, c: columnIndex + _colSpan - 1 }
140
+ })
141
+ }
142
+ })
143
+ colList.push(groupHead)
144
+ })
145
+ } else {
146
+ colList.push(colHead)
147
+ }
148
+ headerRowCount = colList.length
149
+ beforeRowCount += headerRowCount
150
+ }
151
+ // 处理合并
152
+ if (isMerge) {
153
+ mergeCells.forEach(mergeItem => {
154
+ const { row: mergeRowIndex, rowspan: mergeRowspan, col: mergeColIndex, colspan: mergeColspan } = mergeItem
155
+ sheetMerges.push({
156
+ s: { r: mergeRowIndex + beforeRowCount, c: mergeColIndex },
157
+ e: { r: mergeRowIndex + beforeRowCount + mergeRowspan - 1, c: mergeColIndex + mergeColspan - 1 }
158
+ })
159
+ })
160
+ }
161
+ const rowList = datas.map(item => {
162
+ const rest = {}
163
+ columns.forEach(column => {
164
+ rest[column.id] = getCellLabel(column, item[column.id])
165
+ })
166
+ return rest
167
+ })
168
+ beforeRowCount += rowList.length
169
+ // 处理表尾
170
+ if (isFooter) {
171
+ const { footerData } = $table.getTableData()
172
+ const footers = getFooterData(options, footerData)
173
+ const mergeFooterItems = $table.getMergeFooterItems()
174
+ // 处理合并
175
+ if (isMerge) {
176
+ mergeFooterItems.forEach(mergeItem => {
177
+ const { row: mergeRowIndex, rowspan: mergeRowspan, col: mergeColIndex, colspan: mergeColspan } = mergeItem
178
+ sheetMerges.push({
179
+ s: { r: mergeRowIndex + beforeRowCount, c: mergeColIndex },
180
+ e: { r: mergeRowIndex + beforeRowCount + mergeRowspan - 1, c: mergeColIndex + mergeColspan - 1 }
181
+ })
182
+ })
183
+ }
184
+ footers.forEach(rows => {
185
+ const item = {}
186
+ columns.forEach(column => {
187
+ item[column.id] = getFooterCellValue($table, options, rows, column)
188
+ })
189
+ footList.push(item)
190
+ })
191
+ }
192
+ const exportMethod = () => {
193
+ const workbook = new ExcelJS.Workbook()
194
+ const sheet = workbook.addWorksheet(sheetName, { views: [{ state: 'frozen', xSplit: 0, ySplit: headerRowCount }] })
195
+ workbook.creator = 'vxe-table'
196
+ sheet.columns = sheetCols
197
+ if (isHeader) {
198
+ sheet.addRows(colList).forEach(excelRow => {
199
+ if (useStyle) {
200
+ setExcelRowHeight(excelRow, rowHeight)
201
+ }
202
+ excelRow.eachCell(excelCell => {
203
+ const excelCol = sheet.getColumn(excelCell.col)
204
+ const column = $table.getColumnById(excelCol.key)
205
+ const { headerAlign, align } = column
206
+ setExcelCellStyle(excelCell, headerAlign || align || allHeaderAlign || allAlign)
207
+ Object.assign(excelCell, {
208
+ font: {
209
+ bold: true,
210
+ color: {
211
+ argb: defaultCellFontColor
212
+ }
213
+ },
214
+ fill: {
215
+ type: 'pattern',
216
+ pattern: 'solid',
217
+ fgColor: {
218
+ argb: defaultHeaderBackgroundColor
219
+ }
220
+ },
221
+ border: getDefaultBorderStyle()
222
+ })
223
+ })
224
+ })
225
+ }
226
+ sheet.addRows(rowList).forEach(excelRow => {
227
+ if (useStyle) {
228
+ setExcelRowHeight(excelRow, rowHeight)
229
+ }
230
+ excelRow.eachCell(excelCell => {
231
+ const excelCol = sheet.getColumn(excelCell.col)
232
+ const column = $table.getColumnById(excelCol.key)
233
+ if (column) {
234
+ const { align } = column
235
+ setExcelCellStyle(excelCell, align || allAlign)
236
+ if (useStyle) {
237
+ Object.assign(excelCell, {
238
+ font: {
239
+ color: {
240
+ argb: defaultCellFontColor
241
+ }
242
+ },
243
+ border: getDefaultBorderStyle()
244
+ })
245
+ }
246
+ }
247
+ })
248
+ })
249
+ if (isFooter) {
250
+ sheet.addRows(footList).forEach(excelRow => {
251
+ if (useStyle) {
252
+ setExcelRowHeight(excelRow, rowHeight)
253
+ }
254
+ excelRow.eachCell(excelCell => {
255
+ const excelCol = sheet.getColumn(excelCell.col)
256
+ const column = $table.getColumnById(excelCol.key)
257
+ if (column) {
258
+ const { footerAlign, align } = column
259
+ setExcelCellStyle(excelCell, footerAlign || align || allFooterAlign || allAlign)
260
+ if (useStyle) {
261
+ Object.assign(excelCell, {
262
+ font: {
263
+ color: {
264
+ argb: defaultCellFontColor
265
+ }
266
+ },
267
+ border: getDefaultBorderStyle()
268
+ })
269
+ }
270
+ }
271
+ })
272
+ })
273
+ }
274
+ if (useStyle && sheetMethod) {
275
+ sheetMethod({ options: options, workbook, worksheet: sheet, columns, colgroups, datas, $table })
276
+ }
277
+ sheetMerges.forEach(({ s, e }) => {
278
+ sheet.mergeCells(s.r + 1, s.c + 1, e.r + 1, e.c + 1)
279
+ })
280
+ workbook.xlsx.writeBuffer().then(buffer => {
281
+ const blob = new Blob([buffer], { type: 'application/octet-stream' })
282
+ // 导出 xlsx
283
+ downloadFile(params, blob, options)
284
+ if (showMsg && modal) {
285
+ modal.close(msgKey)
286
+ modal.message({ content: t('vxe.table.expSuccess'), status: 'success' })
287
+ }
288
+ })
289
+ }
290
+ if (showMsg && modal) {
291
+ modal.message({ id: msgKey, content: t('vxe.table.expLoading'), status: 'loading', duration: -1 })
292
+ setTimeout(exportMethod, 1500)
293
+ } else {
294
+ exportMethod()
295
+ }
296
+ }
297
+
298
+ function downloadFile(params, blob, options) {
299
+ const { modal, t } = vxetable
300
+ const { message, filename, type } = options
301
+ const showMsg = message !== false
302
+ if (window.Blob) {
303
+ if (navigator.msSaveBlob) {
304
+ navigator.msSaveBlob(blob, `${filename}.${type}`)
305
+ } else {
306
+ const linkElem = document.createElement('a')
307
+ linkElem.target = '_blank'
308
+ linkElem.download = `${filename}.${type}`
309
+ linkElem.href = URL.createObjectURL(blob)
310
+ document.body.appendChild(linkElem)
311
+ linkElem.click()
312
+ document.body.removeChild(linkElem)
313
+ }
314
+ } else {
315
+ if (showMsg && modal) {
316
+ modal.alert({ content: t('vxe.error.notExp'), status: 'error' })
317
+ }
318
+ }
319
+ }
320
+
321
+ function checkImportData(tableFields, fields) {
322
+ return fields.some(field => tableFields.indexOf(field) > -1)
323
+ }
324
+
325
+ function importError(params) {
326
+ const { modal, t } = vxetable
327
+ const { $table, options } = params
328
+ const { internalData } = $table
329
+ const { _importReject } = internalData
330
+ const showMsg = options.message !== false
331
+ if (showMsg && modal) {
332
+ modal.message({ content: t('vxe.error.impFields'), status: 'error' })
333
+ }
334
+ if (_importReject) {
335
+ _importReject({ status: false })
336
+ }
337
+ }
338
+
339
+ function importXLSX(params) {
340
+ const { modal, t } = vxetable
341
+ const { $table, columns, options, file } = params
342
+ const { internalData } = $table
343
+ const { _importResolve } = internalData
344
+ const showMsg = options.message !== false
345
+ const fileReader = new FileReader()
346
+ fileReader.onerror = () => {
347
+ importError(params)
348
+ }
349
+ fileReader.onload = evnt => {
350
+ const tableFields = []
351
+ columns.forEach(column => {
352
+ const field = column.field
353
+ if (field) {
354
+ tableFields.push(field)
355
+ }
356
+ })
357
+ const workbook = new ExcelJS.Workbook()
358
+ const readerTarget = evnt.target
359
+ if (readerTarget) {
360
+ workbook.xlsx.load(readerTarget.result).then(wb => {
361
+ const firstSheet = wb.worksheets[0]
362
+ if (firstSheet) {
363
+ const sheetValues = firstSheet.getSheetValues()
364
+ const fieldIndex = XEUtils.findIndexOf(sheetValues, list => list && list.length > 0)
365
+ const fields = sheetValues[fieldIndex]
366
+ const status = checkImportData(tableFields, fields)
367
+ if (status) {
368
+ const records = sheetValues.slice(fieldIndex).map(list => {
369
+ const item = {}
370
+ list.forEach((cellValue, cIndex) => {
371
+ item[fields[cIndex]] = cellValue
372
+ })
373
+ const record = {}
374
+ tableFields.forEach(field => {
375
+ record[field] = XEUtils.isUndefined(item[field]) ? null : item[field]
376
+ })
377
+ return record
378
+ })
379
+ $table.createData(records).then(data => {
380
+ let loadRest = null
381
+ if (options.mode === 'insert') {
382
+ loadRest = $table.insertAt(data, -1)
383
+ } else {
384
+ loadRest = $table.reloadData(data)
385
+ }
386
+ return loadRest.then(() => {
387
+ if (_importResolve) {
388
+ _importResolve({ status: true })
389
+ }
390
+ })
391
+ })
392
+ if (showMsg && modal) {
393
+ modal.message({ content: t('vxe.table.impSuccess', [records.length]), status: 'success' })
394
+ }
395
+ } else {
396
+ importError(params)
397
+ }
398
+ } else {
399
+ importError(params)
400
+ }
401
+ })
402
+ } else {
403
+ importError(params)
404
+ }
405
+ }
406
+ fileReader.readAsArrayBuffer(file)
407
+ }
408
+
409
+ function handleImportEvent(params) {
410
+ if (params.options.type === 'xlsx') {
411
+ importXLSX(params)
412
+ return false
413
+ }
414
+ }
415
+
416
+ function handleExportEvent(params) {
417
+ if (params.options.type === 'xlsx') {
418
+ exportXLSX(params)
419
+ return false
420
+ }
421
+ }
422
+
423
+ /**
424
+ * 基于 vxe-table 表格的增强插件,支持导出 xlsx 格式
425
+ */
426
+ export const VXETablePluginExportXLSX = {
427
+ install(vxetablecore) {
428
+ const { setup, interceptor } = vxetablecore
429
+
430
+ vxetable = vxetablecore
431
+
432
+ setup({
433
+ export: {
434
+ types: {
435
+ xlsx: 0
436
+ }
437
+ }
438
+ })
439
+ interceptor.mixin({
440
+ 'event.import': handleImportEvent,
441
+ 'event.export': handleExportEvent
442
+ })
443
+ }
444
+ }
445
+
446
+ if (typeof window !== 'undefined' && window.VXETable && window.VXETable.use) {
447
+ window.VXETable.use(VXETablePluginExportXLSX)
448
+ }
449
+
450
+ export default VXETablePluginExportXLSX