sh-view 2.6.2 → 2.6.4

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 (40) hide show
  1. package/package.json +1 -1
  2. package/packages/components/global-components/sh-form/form.vue +110 -108
  3. package/packages/components/global-components/sh-form/js/useForm.js +3 -0
  4. package/packages/components/global-components/sh-form/query.vue +70 -68
  5. package/packages/components/global-components/sh-table/components/sh-column.vue +69 -69
  6. package/packages/components/global-components/sh-table/grid.vue +160 -159
  7. package/packages/components/global-components/sh-table/js/useTable.js +12 -6
  8. package/packages/components/global-components/sh-table/table.vue +218 -217
  9. package/packages/components/other-components/sh-cron-modal/mixin/cron-hooks.js +179 -177
  10. package/packages/components/other-components/sh-cron-modal/tabs/cron-day-box.vue +101 -99
  11. package/packages/components/other-components/sh-cron-modal/tabs/cron-hour-box.vue +68 -66
  12. package/packages/components/other-components/sh-cron-modal/tabs/cron-minute-box.vue +68 -66
  13. package/packages/components/other-components/sh-cron-modal/tabs/cron-month-box.vue +68 -66
  14. package/packages/components/other-components/sh-cron-modal/tabs/cron-second-box.vue +68 -66
  15. package/packages/components/other-components/sh-cron-modal/tabs/cron-week-box.vue +126 -125
  16. package/packages/components/other-components/sh-cron-modal/tabs/cron-year-box.vue +59 -57
  17. package/packages/components/other-components/sh-preview/components/sh-excel.vue +929 -927
  18. package/packages/components/other-components/sh-preview/components/sh-word.vue +78 -76
  19. package/packages/vxeTable/render/cell/vxe-render-checkbox.vue +28 -26
  20. package/packages/vxeTable/render/cell/vxe-render-checkgroup.vue +43 -42
  21. package/packages/vxeTable/render/cell/vxe-render-code.vue +36 -34
  22. package/packages/vxeTable/render/cell/vxe-render-goption.vue +104 -103
  23. package/packages/vxeTable/render/cell/vxe-render-href.vue +21 -19
  24. package/packages/vxeTable/render/cell/vxe-render-input.vue +53 -52
  25. package/packages/vxeTable/render/cell/vxe-render-money.vue +33 -31
  26. package/packages/vxeTable/render/cell/vxe-render-progress.vue +28 -26
  27. package/packages/vxeTable/render/cell/vxe-render-radio.vue +28 -26
  28. package/packages/vxeTable/render/cell/vxe-render-radiogroup.vue +43 -42
  29. package/packages/vxeTable/render/cell/vxe-render-select.vue +52 -51
  30. package/packages/vxeTable/render/cell/vxe-render-switch.vue +28 -26
  31. package/packages/vxeTable/render/cell/vxe-render-table.vue +51 -50
  32. package/packages/vxeTable/render/cell/vxe-render-textarea.vue +28 -26
  33. package/packages/vxeTable/render/cell/vxe-render-time.vue +44 -41
  34. package/packages/vxeTable/render/cell/vxe-render-tree.vue +63 -60
  35. package/packages/vxeTable/render/cell/vxe-render-upload.vue +28 -26
  36. package/packages/vxeTable/render/filters/vxe-filter-input.vue +25 -23
  37. package/packages/vxeTable/render/footer/vxe-footer-input.vue +23 -21
  38. package/packages/vxeTable/render/footer/vxe-footer-money.vue +30 -28
  39. package/packages/vxeTable/render/header/vxe-header-money.vue +31 -29
  40. package/packages/vxeTable/render/mixin/cell-hooks.js +4 -1
@@ -1,927 +1,929 @@
1
- <script>
2
- import { defineComponent, computed, getCurrentInstance } from 'vue'
3
- import dataHook from '../js/data-hook'
4
- import dataProps from '../js/data-props'
5
- // import Spreadsheet from 'x-data-spreadsheet'
6
- import ExcelJS from 'exceljs'
7
- export default defineComponent({
8
- name: 'ShExcel',
9
- props: dataProps,
10
- emits: ['rendered', 'error'],
11
- setup(props, { emit }) {
12
- const { proxy } = getCurrentInstance()
13
- const { $vUtils } = proxy
14
-
15
- let defaultOption = {
16
- mode: 'read',
17
- showToolbar: false
18
- }
19
-
20
- const excelOptions = computed(() => {
21
- return Object.assign({}, defaultOption, props.options)
22
- })
23
-
24
- const domRender = async (data, container) => {
25
- if (!data) {
26
- container.innerHTML = ''
27
- return Promise.resolve()
28
- }
29
- const wb = new ExcelJS.Workbook()
30
- // 微软的 Excel ColorIndex 一个索引数字对应一个颜色
31
- let workbook = await wb.xlsx.load(data)
32
- let workbookData = []
33
- workbook.eachSheet(sheet => {
34
- // 构造x-data-spreadsheet 的 sheet 数据源结构
35
- let sheetData = { name: sheet.name, styles: [], rows: {}, merges: [] }
36
- // 收集合并单元格信息
37
- let mergeAddressData = []
38
- for (let mergeRange in sheet._merges) {
39
- sheetData.merges.push(sheet._merges[mergeRange].shortRange)
40
- let mergeAddress = {}
41
- // 合并单元格起始地址
42
- mergeAddress.startAddress = sheet._merges[mergeRange].tl
43
- // 合并单元格终止地址
44
- mergeAddress.endAddress = sheet._merges[mergeRange].br
45
- // Y轴方向跨度
46
- mergeAddress.YRange = sheet._merges[mergeRange].model.bottom - sheet._merges[mergeRange].model.top
47
- // X轴方向跨度
48
- mergeAddress.XRange = sheet._merges[mergeRange].model.right - sheet._merges[mergeRange].model.left
49
- mergeAddressData.push(mergeAddress)
50
- }
51
- sheetData.cols = {}
52
- for (let i = 0; i < sheet.columns.length; i++) {
53
- sheetData.cols[i.toString()] = {}
54
- if (sheet.columns[i].width) {
55
- // 不知道为什么从 exceljs 读取的宽度显示到 x-data-spreadsheet 特别小, 这里乘以8
56
- sheetData.cols[i.toString()].width = sheet.columns[i].width * 8
57
- } else {
58
- // 默认列宽
59
- sheetData.cols[i.toString()].width = 100
60
- }
61
- }
62
-
63
- // 遍历行
64
- sheet.eachRow((row, rowIndex) => {
65
- sheetData.rows[(rowIndex - 1).toString()] = { cells: {} }
66
- //includeEmpty = false 不包含空白单元格
67
- row.eachCell({ includeEmpty: true }, function (cell, colNumber) {
68
- let cellText = ''
69
- if (cell.value && cell.value.result) {
70
- // Excel 单元格有公式
71
- cellText = cell.value.result
72
- } else if (cell.value && cell.value.richText) {
73
- // Excel 单元格是多行文本
74
- for (let text in cell.value.richText) {
75
- // 多行文本做累加
76
- cellText += cell.value.richText[text].text
77
- }
78
- } else {
79
- // Excel 单元格无公式
80
- cellText = cell.value
81
- }
82
- //解析单元格,包含样式
83
- //*********************单元格存在背景色******************************
84
- // 单元格存在背景色
85
- let backGroundColor = null
86
- if (cell.style.fill && cell.style.fill.fgColor && cell.style.fill.fgColor.argb) {
87
- // 8位字符颜色先转rgb再转16进制颜色
88
- backGroundColor = (val => {
89
- val = val.trim().toLowerCase() //去掉前后空格
90
- let argb = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(val)
91
- let rgb = `rgba(${parseInt(argb[2], 16)}, ${parseInt(argb[3], 16)}, ${parseInt(argb[4], 16)})`
92
- let percent = (parseInt(argb[1], 16) / 255) * 100
93
- return $vUtils.fade(rgb, percent)
94
- })(cell.style.fill.fgColor.argb)
95
- }
96
-
97
- if (backGroundColor) {
98
- cell.style.bgcolor = backGroundColor
99
- }
100
- //*************************************************************************** */
101
-
102
- //*********************字体存在背景色******************************
103
- // 字体颜色
104
- let fontColor = null
105
- if (cell.style.font && cell.style.font.color && cell.style.font.color.argb) {
106
- // 8位字符颜色先转rgb再转16进制颜色
107
- fontColor = (val => {
108
- val = val.trim().toLowerCase() //去掉前后空格
109
- let argb = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(val)
110
- let rgb = `rgba(${parseInt(argb[2], 16)}, ${parseInt(argb[3], 16)}, ${parseInt(argb[4], 16)})`
111
- let percent = (parseInt(argb[1], 16) / 255) * 100
112
- return $vUtils.fade(rgb, percent)
113
- })(cell.style.font.color.argb)
114
- }
115
- if (fontColor) {
116
- cell.style.color = fontColor
117
- }
118
-
119
- // exceljs 对齐的格式转成 x-date-spreedsheet 能识别的对齐格式
120
- if (cell.style.alignment && cell.style.alignment.horizontal) {
121
- cell.style.align = cell.style.alignment.horizontal
122
- cell.style.valign = cell.style.alignment.vertical
123
- }
124
-
125
- //处理合并单元格
126
- let mergeAddress = _.find(mergeAddressData, function (o) {
127
- return o.startAddress === cell._address
128
- })
129
- if (mergeAddress) {
130
- // 遍历的单元格属于合并单元格
131
- if (cell.master.address !== mergeAddress.startAddress) {
132
- // 不是合并单元格中的第一个单元格不需要计入数据源
133
- return
134
- }
135
- // 说明是合并单元格区域的起始单元格
136
- sheetData.rows[(rowIndex - 1).toString()].cells[(colNumber - 1).toString()] = { text: cellText, style: 0, merge: [mergeAddress.YRange, mergeAddress.XRange] }
137
- sheetData.styles.push(cell.style)
138
- //对应的style存放序号
139
- sheetData.rows[(rowIndex - 1).toString()].cells[(colNumber - 1).toString()].style = sheetData.styles.length - 1
140
- } else {
141
- // 非合并单元格
142
- sheetData.rows[(rowIndex - 1).toString()].cells[(colNumber - 1).toString()] = { text: cellText, style: 0 }
143
- //解析单元格,包含样式
144
- sheetData.styles.push(cell.style)
145
- //对应的style存放序号
146
- sheetData.rows[(rowIndex - 1).toString()].cells[(colNumber - 1).toString()].style = sheetData.styles.length - 1
147
- }
148
- })
149
- })
150
- workbookData.push(sheetData)
151
- })
152
- // return new Spreadsheet(rootRef.value, excelOptions).loadData(workbookData)
153
- }
154
-
155
- const useData = dataHook(props, context, proxy, {
156
- domRender
157
- })
158
-
159
- return Object.assign({}, useData)
160
- }
161
- })
162
- </script>
163
-
164
- <template>
165
- <div ref="rootRef" class="sh-office-excel"></div>
166
- </template>
167
-
168
- <style lang="scss" scoped>
169
- .x-spreadsheet {
170
- font-size: 13px;
171
- line-height: normal;
172
- user-select: none;
173
- -moz-user-select: none;
174
- font-family: 'Lato', 'Source Sans Pro', Roboto, Helvetica, Arial, sans-serif;
175
- box-sizing: content-box;
176
- background: #fff;
177
- -webkit-font-smoothing: antialiased;
178
- }
179
- .x-spreadsheet textarea {
180
- font: 400 13px Arial, 'Lato', 'Source Sans Pro', Roboto, Helvetica, sans-serif;
181
- }
182
- .x-spreadsheet-sheet {
183
- position: relative;
184
- overflow: hidden;
185
- }
186
- .x-spreadsheet-table {
187
- vertical-align: bottom;
188
- }
189
- .x-spreadsheet-tooltip {
190
- font-family: inherit;
191
- position: absolute;
192
- padding: 5px 10px;
193
- color: #fff;
194
- border-radius: 1px;
195
- background: #000000;
196
- font-size: 12px;
197
- z-index: 201;
198
- }
199
- .x-spreadsheet-tooltip:before {
200
- pointer-events: none;
201
- position: absolute;
202
- left: calc(50% - 4px);
203
- top: -4px;
204
- content: '';
205
- width: 8px;
206
- height: 8px;
207
- background: inherit;
208
- -webkit-transform: rotate(45deg);
209
- transform: rotate(45deg);
210
- z-index: 1;
211
- box-shadow: 1px 1px 3px -1px rgba(0, 0, 0, 0.3);
212
- }
213
- .x-spreadsheet-color-palette {
214
- padding: 5px;
215
- }
216
- .x-spreadsheet-color-palette table {
217
- margin: 0;
218
- padding: 0;
219
- border-collapse: separate;
220
- background: #fff;
221
- }
222
- .x-spreadsheet-color-palette table td {
223
- margin: 0;
224
- cursor: pointer;
225
- border: 1px solid transparent;
226
- }
227
- .x-spreadsheet-color-palette table td:hover {
228
- border-color: #ddd;
229
- }
230
- .x-spreadsheet-color-palette table td .x-spreadsheet-color-palette-cell {
231
- width: 16px;
232
- height: 16px;
233
- }
234
- .x-spreadsheet-border-palette {
235
- padding: 6px;
236
- }
237
- .x-spreadsheet-border-palette table {
238
- margin: 0;
239
- padding: 0;
240
- border-collapse: separate;
241
- border-spacing: 0;
242
- background: #fff;
243
- table-layout: fixed;
244
- }
245
- .x-spreadsheet-border-palette table td {
246
- margin: 0;
247
- }
248
- .x-spreadsheet-border-palette .x-spreadsheet-border-palette-left {
249
- border-right: 1px solid #eee;
250
- padding-right: 6px;
251
- }
252
- .x-spreadsheet-border-palette .x-spreadsheet-border-palette-left .x-spreadsheet-border-palette-cell {
253
- width: 30px;
254
- height: 30px;
255
- cursor: pointer;
256
- text-align: center;
257
- }
258
- .x-spreadsheet-border-palette .x-spreadsheet-border-palette-left .x-spreadsheet-border-palette-cell:hover {
259
- background-color: #eee;
260
- }
261
- .x-spreadsheet-border-palette .x-spreadsheet-border-palette-right {
262
- padding-left: 6px;
263
- }
264
- .x-spreadsheet-border-palette .x-spreadsheet-border-palette-right .x-spreadsheet-line-type {
265
- position: relative;
266
- left: 0;
267
- top: -3px;
268
- }
269
- .x-spreadsheet-dropdown {
270
- position: relative;
271
- }
272
- .x-spreadsheet-dropdown .x-spreadsheet-dropdown-content {
273
- position: absolute;
274
- z-index: 200;
275
- background: #fff;
276
- box-shadow: 1px 2px 5px 2px rgba(51, 51, 51, 0.15);
277
- }
278
- .x-spreadsheet-dropdown.bottom-left .x-spreadsheet-dropdown-content {
279
- top: calc(100% + 5px);
280
- left: 0;
281
- }
282
- .x-spreadsheet-dropdown.bottom-right .x-spreadsheet-dropdown-content {
283
- top: calc(100% + 5px);
284
- right: 0;
285
- }
286
- .x-spreadsheet-dropdown.top-left .x-spreadsheet-dropdown-content {
287
- bottom: calc(100% + 5px);
288
- left: 0;
289
- }
290
- .x-spreadsheet-dropdown.top-right .x-spreadsheet-dropdown-content {
291
- bottom: calc(100% + 5px);
292
- right: 0;
293
- }
294
- .x-spreadsheet-dropdown .x-spreadsheet-dropdown-title {
295
- padding: 0 5px;
296
- display: inline-block;
297
- }
298
- /* resizer **/
299
- .x-spreadsheet-resizer {
300
- position: absolute;
301
- z-index: 11;
302
- }
303
- .x-spreadsheet-resizer .x-spreadsheet-resizer-hover {
304
- background-color: rgba(75, 137, 255, 0.25);
305
- }
306
- .x-spreadsheet-resizer .x-spreadsheet-resizer-line {
307
- position: absolute;
308
- }
309
- .x-spreadsheet-resizer.horizontal {
310
- cursor: row-resize;
311
- }
312
- .x-spreadsheet-resizer.horizontal .x-spreadsheet-resizer-line {
313
- border-bottom: 2px dashed #4b89ff;
314
- left: 0;
315
- bottom: 0;
316
- }
317
- .x-spreadsheet-resizer.vertical {
318
- cursor: col-resize;
319
- }
320
- .x-spreadsheet-resizer.vertical .x-spreadsheet-resizer-line {
321
- border-right: 2px dashed #4b89ff;
322
- top: 0;
323
- right: 0;
324
- }
325
- /* scrollbar */
326
- .x-spreadsheet-scrollbar {
327
- position: absolute;
328
- bottom: 0;
329
- right: 0;
330
- background-color: #f4f5f8;
331
- opacity: 0.9;
332
- z-index: 12;
333
- }
334
- .x-spreadsheet-scrollbar.horizontal {
335
- right: 15px;
336
- overflow-x: scroll;
337
- overflow-y: hidden;
338
- }
339
- .x-spreadsheet-scrollbar.horizontal > div {
340
- height: 1px;
341
- background: #ddd;
342
- }
343
- .x-spreadsheet-scrollbar.vertical {
344
- bottom: 15px;
345
- overflow-x: hidden;
346
- overflow-y: scroll;
347
- }
348
- .x-spreadsheet-scrollbar.vertical > div {
349
- width: 1px;
350
- background: #ddd;
351
- }
352
- /* @{css-prefix}-overlayer */
353
- .x-spreadsheet-overlayer {
354
- position: absolute;
355
- left: 0;
356
- top: 0;
357
- z-index: 10;
358
- }
359
- .x-spreadsheet-overlayer .x-spreadsheet-overlayer-content {
360
- position: absolute;
361
- overflow: hidden;
362
- pointer-events: none;
363
- width: 100%;
364
- height: 100%;
365
- }
366
- .x-spreadsheet-editor,
367
- .x-spreadsheet-selector {
368
- box-sizing: content-box;
369
- position: absolute;
370
- overflow: hidden;
371
- pointer-events: none;
372
- top: 0;
373
- left: 0;
374
- width: 100%;
375
- height: 100%;
376
- }
377
- /* @{css-prefix}-selector */
378
- .x-spreadsheet-selector .hide-input {
379
- position: absolute;
380
- z-index: 0;
381
- }
382
- .x-spreadsheet-selector .hide-input input {
383
- padding: 0;
384
- width: 0;
385
- border: none !important;
386
- }
387
- .x-spreadsheet-selector .x-spreadsheet-selector-area {
388
- position: absolute;
389
- border: 2px solid #4b89ff;
390
- background: rgba(75, 137, 255, 0.1);
391
- z-index: 5;
392
- }
393
- .x-spreadsheet-selector .x-spreadsheet-selector-clipboard,
394
- .x-spreadsheet-selector .x-spreadsheet-selector-autofill {
395
- position: absolute;
396
- background: transparent;
397
- z-index: 100;
398
- }
399
- .x-spreadsheet-selector .x-spreadsheet-selector-clipboard {
400
- border: 2px dashed #4b89ff;
401
- }
402
- .x-spreadsheet-selector .x-spreadsheet-selector-autofill {
403
- border: 1px dashed rgba(0, 0, 0, 0.45);
404
- }
405
- .x-spreadsheet-selector .x-spreadsheet-selector-corner {
406
- pointer-events: auto;
407
- position: absolute;
408
- cursor: crosshair;
409
- font-size: 0;
410
- height: 5px;
411
- width: 5px;
412
- right: -5px;
413
- bottom: -5px;
414
- border: 2px solid #ffffff;
415
- background: #4b89ff;
416
- }
417
- .x-spreadsheet-editor {
418
- z-index: 20;
419
- }
420
- .x-spreadsheet-editor .x-spreadsheet-editor-area {
421
- position: absolute;
422
- text-align: left;
423
- border: 2px solid #4b89ff;
424
- line-height: 0;
425
- z-index: 100;
426
- pointer-events: auto;
427
- }
428
- .x-spreadsheet-editor .x-spreadsheet-editor-area textarea {
429
- box-sizing: content-box;
430
- border: none;
431
- padding: 0 3px;
432
- outline: none;
433
- resize: none;
434
- text-align: start;
435
- overflow-y: hidden;
436
- font: 400 13px Arial, 'Lato', 'Source Sans Pro', Roboto, Helvetica, sans-serif;
437
- color: inherit;
438
- white-space: normal;
439
- word-wrap: break-word;
440
- line-height: 22px;
441
- margin: 0;
442
- }
443
- .x-spreadsheet-editor .x-spreadsheet-editor-area .textline {
444
- overflow: hidden;
445
- visibility: hidden;
446
- position: fixed;
447
- top: 0;
448
- left: 0;
449
- }
450
- .x-spreadsheet-item {
451
- user-select: none;
452
- background: 0;
453
- border: 1px solid transparent;
454
- outline: none;
455
- height: 26px;
456
- color: rgba(0, 0, 0, 0.9);
457
- line-height: 26px;
458
- list-style: none;
459
- padding: 2px 10px;
460
- cursor: default;
461
- text-align: left;
462
- overflow: hidden;
463
- }
464
- .x-spreadsheet-item.disabled {
465
- pointer-events: none;
466
- opacity: 0.5;
467
- }
468
- .x-spreadsheet-item:hover,
469
- .x-spreadsheet-item.active {
470
- background: rgba(0, 0, 0, 0.05);
471
- }
472
- .x-spreadsheet-item.divider {
473
- height: 0;
474
- padding: 0;
475
- margin: 5px 0;
476
- border: none;
477
- border-bottom: 1px solid rgba(0, 0, 0, 0.1);
478
- }
479
- .x-spreadsheet-item .label {
480
- float: right;
481
- opacity: 0.65;
482
- font-size: 1em;
483
- }
484
- .x-spreadsheet-item.state,
485
- .x-spreadsheet-header.state {
486
- padding-left: 35px !important;
487
- position: relative;
488
- }
489
- .x-spreadsheet-item.state:before,
490
- .x-spreadsheet-header.state:before {
491
- content: '';
492
- position: absolute;
493
- width: 10px;
494
- height: 10px;
495
- left: 12px;
496
- top: calc(50% - 5px);
497
- background: rgba(0, 0, 0, 0.08);
498
- border-radius: 2px;
499
- }
500
- .x-spreadsheet-item.state.checked:before,
501
- .x-spreadsheet-header.state.checked:before {
502
- background: #4b89ff;
503
- }
504
- .x-spreadsheet-checkbox {
505
- position: relative;
506
- display: inline-block;
507
- backface-visibility: hidden;
508
- outline: 0;
509
- vertical-align: baseline;
510
- font-style: normal;
511
- font-size: 1rem;
512
- line-height: 1em;
513
- }
514
- .x-spreadsheet-checkbox > input {
515
- position: absolute;
516
- top: 0;
517
- left: 0;
518
- opacity: 0 !important;
519
- outline: 0;
520
- z-index: -1;
521
- }
522
- .x-spreadsheet-suggest,
523
- .x-spreadsheet-contextmenu,
524
- .x-spreadsheet-sort-filter {
525
- position: absolute;
526
- box-shadow: 1px 2px 5px 2px rgba(51, 51, 51, 0.15);
527
- background: #fff;
528
- z-index: 100;
529
- width: 260px;
530
- pointer-events: auto;
531
- overflow: auto;
532
- }
533
- .x-spreadsheet-suggest {
534
- width: 200px;
535
- }
536
- .x-spreadsheet-filter {
537
- border: 1px solid #e9e9e9;
538
- font-size: 12px;
539
- margin: 10px;
540
- }
541
- .x-spreadsheet-filter .x-spreadsheet-header {
542
- padding: 0.5em 0.75em;
543
- background: #f8f8f9;
544
- border-bottom: 1px solid #e9e9e9;
545
- border-left: 1px solid transparent;
546
- }
547
- .x-spreadsheet-filter .x-spreadsheet-body {
548
- height: 200px;
549
- overflow-y: auto;
550
- }
551
- .x-spreadsheet-filter .x-spreadsheet-body .x-spreadsheet-item {
552
- height: 20px;
553
- line-height: 20px;
554
- }
555
- .x-spreadsheet-sort-filter .x-spreadsheet-buttons {
556
- margin: 10px;
557
- }
558
- .x-spreadsheet-bottombar {
559
- height: 40px;
560
- padding: 0 30px;
561
- text-align: left;
562
- background: #f5f6f7;
563
- display: flex;
564
- }
565
- .x-spreadsheet-bottombar {
566
- position: relative;
567
- border-top: 1px solid #e0e2e4;
568
- }
569
- .x-spreadsheet-bottombar .x-spreadsheet-menu > li {
570
- line-height: 40px;
571
- height: 40px;
572
- padding-top: 0;
573
- padding-bottom: 0;
574
- vertical-align: middle;
575
- border-right: 1px solid #e8eaed;
576
- }
577
- .x-spreadsheet-menu {
578
- list-style: none;
579
- margin: 0;
580
- padding: 0;
581
- user-select: none;
582
- }
583
- .x-spreadsheet-menu > li {
584
- float: left;
585
- line-height: 1.25em;
586
- padding: 0.785em 1em;
587
- margin: 0;
588
- vertical-align: middle;
589
- text-align: left;
590
- color: #80868b;
591
- white-space: nowrap;
592
- cursor: pointer;
593
- transition: all 0.3s;
594
- font-weight: bold;
595
- }
596
- .x-spreadsheet-menu > li.active {
597
- background-color: #fff;
598
- color: rgba(0, 0, 0, 0.65);
599
- }
600
- .x-spreadsheet-menu > li .x-spreadsheet-dropdown {
601
- display: inline-block;
602
- }
603
- .x-spreadsheet-print {
604
- position: absolute;
605
- left: 0;
606
- top: 0;
607
- z-index: 100;
608
- width: 100%;
609
- height: 100%;
610
- display: flex;
611
- flex-direction: column;
612
- }
613
- .x-spreadsheet-print-bar {
614
- background: #424242;
615
- height: 60px;
616
- line-height: 60px;
617
- padding: 0 30px;
618
- }
619
- .x-spreadsheet-print-bar .-title {
620
- color: #fff;
621
- font-weight: bold;
622
- font-size: 1.2em;
623
- float: left;
624
- }
625
- .x-spreadsheet-print-bar .-right {
626
- float: right;
627
- margin-top: 12px;
628
- }
629
- .x-spreadsheet-print-content {
630
- display: flex;
631
- flex: auto;
632
- flex-direction: row;
633
- background: #d0d0d0;
634
- height: calc(100% - 60px);
635
- }
636
- .x-spreadsheet-print-content .-sider {
637
- flex: 0 0 300px;
638
- width: 300px;
639
- border-left: 2px solid #ccc;
640
- background: #fff;
641
- }
642
- .x-spreadsheet-print-content .-content {
643
- flex: auto;
644
- overflow-x: auto;
645
- overflow-y: scroll;
646
- height: 100%;
647
- }
648
- .x-spreadsheet-canvas-card-wraper {
649
- margin: 40px 20px;
650
- }
651
- .x-spreadsheet-canvas-card {
652
- background: #fff;
653
- margin: auto;
654
- page-break-before: auto;
655
- page-break-after: always;
656
- box-shadow: 0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 3px rgba(0, 0, 0, 0.12), 0 4px 5px 0 rgba(0, 0, 0, 0.2);
657
- }
658
- .x-spreadsheet-calendar {
659
- color: rgba(0, 0, 0, 0.65);
660
- background: #ffffff;
661
- user-select: none;
662
- }
663
- .x-spreadsheet-calendar .calendar-header {
664
- font-weight: 700;
665
- line-height: 30px;
666
- text-align: center;
667
- width: 100%;
668
- float: left;
669
- background: #f9fafb;
670
- }
671
- .x-spreadsheet-calendar .calendar-header .calendar-header-left {
672
- padding-left: 5px;
673
- float: left;
674
- }
675
- .x-spreadsheet-calendar .calendar-header .calendar-header-right {
676
- float: right;
677
- }
678
- .x-spreadsheet-calendar .calendar-header .calendar-header-right a {
679
- padding: 3px 0;
680
- margin-right: 2px;
681
- border-radius: 2px;
682
- }
683
- .x-spreadsheet-calendar .calendar-header .calendar-header-right a:hover {
684
- background: rgba(0, 0, 0, 0.08);
685
- }
686
- .x-spreadsheet-calendar .calendar-body {
687
- border-collapse: collapse;
688
- border-spacing: 0;
689
- }
690
- .x-spreadsheet-calendar .calendar-body th,
691
- .x-spreadsheet-calendar .calendar-body td {
692
- width: 14.28571429%;
693
- min-width: 32px;
694
- text-align: center;
695
- font-weight: 700;
696
- line-height: 30px;
697
- padding: 0;
698
- }
699
- .x-spreadsheet-calendar .calendar-body td > .cell:hover {
700
- background: #ecf6fd;
701
- }
702
- .x-spreadsheet-calendar .calendar-body td > .cell.active,
703
- .x-spreadsheet-calendar .calendar-body td > .cell.active:hover {
704
- background: #ecf6fd;
705
- color: #2185d0;
706
- }
707
- .x-spreadsheet-calendar .calendar-body td > .cell.disabled {
708
- pointer-events: none;
709
- opacity: 0.5;
710
- }
711
- .x-spreadsheet-datepicker {
712
- box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.2);
713
- position: absolute;
714
- left: 0;
715
- top: calc(100% + 5px);
716
- z-index: 10;
717
- width: auto;
718
- }
719
- .x-spreadsheet-buttons {
720
- display: flex;
721
- justify-content: flex-end;
722
- }
723
- .x-spreadsheet-buttons .x-spreadsheet-button {
724
- margin-left: 8px;
725
- }
726
- .x-spreadsheet-button {
727
- display: inline-block;
728
- border-radius: 3px;
729
- line-height: 1em;
730
- min-height: 1em;
731
- white-space: nowrap;
732
- text-align: center;
733
- cursor: pointer;
734
- font-size: 1em;
735
- font-weight: 700;
736
- padding: 0.75em 1em;
737
- color: rgba(0, 0, 0, 0.6);
738
- background: #e0e1e2;
739
- text-decoration: none;
740
- font-family: 'Lato', 'proxima-nova', 'Helvetica Neue', Arial, sans-serif;
741
- outline: none;
742
- vertical-align: baseline;
743
- zoom: 1;
744
- user-select: none;
745
- transition: all 0.1s linear;
746
- }
747
- .x-spreadsheet-button.active,
748
- .x-spreadsheet-button:hover {
749
- background-color: #c0c1c2;
750
- color: rgba(0, 0, 0, 0.8);
751
- }
752
- .x-spreadsheet-button.primary {
753
- color: #fff;
754
- background-color: #2185d0;
755
- }
756
- .x-spreadsheet-button.primary:hover,
757
- .x-spreadsheet-button.primary.active {
758
- color: #fff;
759
- background-color: #1678c2;
760
- }
761
- .x-spreadsheet-form-input {
762
- font-size: 1em;
763
- position: relative;
764
- font-weight: 400;
765
- display: inline-flex;
766
- color: rgba(0, 0, 0, 0.87);
767
- }
768
- .x-spreadsheet-form-input input {
769
- z-index: 1;
770
- margin: 0;
771
- max-width: 100%;
772
- flex: 1 0 auto;
773
- outline: 0;
774
- -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
775
- text-align: left;
776
- line-height: 30px;
777
- height: 30px;
778
- padding: 0 8px;
779
- background: #fff;
780
- border: 1px solid #e9e9e9;
781
- border-radius: 3px;
782
- transition: box-shadow 0.1s ease, border-color 0.1s ease;
783
- box-shadow: inset 0 1px 2px hsla(0, 0%, 4%, 0.06);
784
- }
785
- .x-spreadsheet-form-input input:focus {
786
- border-color: #4b89ff;
787
- box-shadow: inset 0 1px 2px rgba(75, 137, 255, 0.2);
788
- }
789
- .x-spreadsheet-form-select {
790
- position: relative;
791
- display: inline-block;
792
- background: #fff;
793
- border: 1px solid #e9e9e9;
794
- border-radius: 2px;
795
- cursor: pointer;
796
- color: rgba(0, 0, 0, 0.87);
797
- user-select: none;
798
- box-shadow: inset 0 1px 2px hsla(0, 0%, 4%, 0.06);
799
- }
800
- .x-spreadsheet-form-select .input-text {
801
- text-overflow: ellipsis;
802
- white-space: nowrap;
803
- min-width: 60px;
804
- width: auto;
805
- height: 30px;
806
- line-height: 30px;
807
- padding: 0 8px;
808
- }
809
- .x-spreadsheet-form-fields {
810
- display: flex;
811
- flex-direction: row;
812
- flex-wrap: wrap;
813
- }
814
- .x-spreadsheet-form-fields .x-spreadsheet-form-field {
815
- flex: 0 1 auto;
816
- }
817
- .x-spreadsheet-form-fields .x-spreadsheet-form-field .label {
818
- display: inline-block;
819
- margin: 0 10px 0 0;
820
- }
821
- .x-spreadsheet-form-field {
822
- display: block;
823
- vertical-align: middle;
824
- margin-left: 10px;
825
- margin-bottom: 10px;
826
- }
827
- .x-spreadsheet-form-field:first-child {
828
- margin-left: 0;
829
- }
830
- .x-spreadsheet-form-field.error .x-spreadsheet-form-select,
831
- .x-spreadsheet-form-field.error input {
832
- border-color: #f04134;
833
- }
834
- .x-spreadsheet-form-field .tip {
835
- color: #f04134;
836
- font-size: 0.9em;
837
- }
838
- .x-spreadsheet-dimmer {
839
- display: none;
840
- position: absolute;
841
- top: 0 !important;
842
- left: 0 !important;
843
- width: 100%;
844
- height: 100%;
845
- text-align: center;
846
- vertical-align: middle;
847
- background-color: rgba(0, 0, 0, 0.6);
848
- opacity: 0;
849
- -webkit-animation-fill-mode: both;
850
- animation-fill-mode: both;
851
- -webkit-animation-duration: 0.5s;
852
- animation-duration: 0.5s;
853
- transition: background-color 0.5s linear;
854
- user-select: none;
855
- z-index: 1000;
856
- }
857
- .x-spreadsheet-dimmer.active {
858
- display: block;
859
- opacity: 1;
860
- }
861
- .x-spreadsheet-modal,
862
- .x-spreadsheet-toast {
863
- font-size: 13px;
864
- position: fixed;
865
- z-index: 1001;
866
- text-align: left;
867
- line-height: 1.25em;
868
- min-width: 360px;
869
- color: rgba(0, 0, 0, 0.87);
870
- font-family: 'Lato', 'Source Sans Pro', Roboto, Helvetica, Arial, sans-serif;
871
- border-radius: 4px;
872
- border: 1px solid rgba(0, 0, 0, 0.1);
873
- background-color: #fff;
874
- background-clip: padding-box;
875
- box-shadow: rgba(0, 0, 0, 0.2) 0px 2px 8px;
876
- }
877
- .x-spreadsheet-toast {
878
- background-color: rgba(255, 255, 255, 0.85);
879
- }
880
- .x-spreadsheet-modal-header,
881
- .x-spreadsheet-toast-header {
882
- font-weight: 600;
883
- background-clip: padding-box;
884
- background-color: rgba(255, 255, 255, 0.85);
885
- border-bottom: 1px solid rgba(0, 0, 0, 0.05);
886
- border-radius: 4px 4px 0 0;
887
- }
888
-
889
- .x-spreadsheet-toast-header {
890
- color: #f2711c;
891
- }
892
- .x-spreadsheet-modal-header {
893
- border-bottom: 1px solid #e0e2e4;
894
- background: rgba(0, 0, 0, 0.08);
895
- font-size: 1.0785em;
896
- }
897
- .x-spreadsheet-modal-header,
898
- .x-spreadsheet-modal-content,
899
- .x-spreadsheet-toast-header,
900
- .x-spreadsheet-toast-content {
901
- padding: 0.75em 1em;
902
- }
903
-
904
- .x-spreadsheet-menu li:first-child {
905
- display: none;
906
- }
907
- .sh-office-excel {
908
- form fieldset {
909
- border: none;
910
- }
911
- form fieldset label {
912
- display: block;
913
- margin-bottom: 0.5em;
914
- font-size: 1em;
915
- color: #666;
916
- }
917
- form fieldset select {
918
- font-size: 1.1em;
919
- width: 100%;
920
- background-color: #fff;
921
- border: none;
922
- border-bottom: 2px solid #ddd;
923
- padding: 0.5em 0.85em;
924
- border-radius: 2px;
925
- }
926
- }
927
- </style>
1
+ <script>
2
+ import { defineComponent, computed, getCurrentInstance } from 'vue'
3
+ import dataHook from '../js/data-hook'
4
+ import dataProps from '../js/data-props'
5
+ // import Spreadsheet from 'x-data-spreadsheet'
6
+ import ExcelJS from 'exceljs'
7
+ export default defineComponent({
8
+ name: 'ShExcel',
9
+ props: dataProps,
10
+ emits: ['rendered', 'error'],
11
+ setup(props, { emit }) {
12
+ const { proxy } = getCurrentInstance()
13
+ const { $vUtils } = proxy
14
+
15
+ let defaultOption = {
16
+ mode: 'read',
17
+ showToolbar: false
18
+ }
19
+
20
+ const excelOptions = computed(() => {
21
+ return Object.assign({}, defaultOption, props.options)
22
+ })
23
+
24
+ const domRender = async (data, container) => {
25
+ if (!data) {
26
+ container.innerHTML = ''
27
+ return Promise.resolve()
28
+ }
29
+ const wb = new ExcelJS.Workbook()
30
+ // 微软的 Excel ColorIndex 一个索引数字对应一个颜色
31
+ let workbook = await wb.xlsx.load(data)
32
+ let workbookData = []
33
+ workbook.eachSheet(sheet => {
34
+ // 构造x-data-spreadsheet 的 sheet 数据源结构
35
+ let sheetData = { name: sheet.name, styles: [], rows: {}, merges: [] }
36
+ // 收集合并单元格信息
37
+ let mergeAddressData = []
38
+ for (let mergeRange in sheet._merges) {
39
+ sheetData.merges.push(sheet._merges[mergeRange].shortRange)
40
+ let mergeAddress = {}
41
+ // 合并单元格起始地址
42
+ mergeAddress.startAddress = sheet._merges[mergeRange].tl
43
+ // 合并单元格终止地址
44
+ mergeAddress.endAddress = sheet._merges[mergeRange].br
45
+ // Y轴方向跨度
46
+ mergeAddress.YRange = sheet._merges[mergeRange].model.bottom - sheet._merges[mergeRange].model.top
47
+ // X轴方向跨度
48
+ mergeAddress.XRange = sheet._merges[mergeRange].model.right - sheet._merges[mergeRange].model.left
49
+ mergeAddressData.push(mergeAddress)
50
+ }
51
+ sheetData.cols = {}
52
+ for (let i = 0; i < sheet.columns.length; i++) {
53
+ sheetData.cols[i.toString()] = {}
54
+ if (sheet.columns[i].width) {
55
+ // 不知道为什么从 exceljs 读取的宽度显示到 x-data-spreadsheet 特别小, 这里乘以8
56
+ sheetData.cols[i.toString()].width = sheet.columns[i].width * 8
57
+ } else {
58
+ // 默认列宽
59
+ sheetData.cols[i.toString()].width = 100
60
+ }
61
+ }
62
+
63
+ // 遍历行
64
+ sheet.eachRow((row, rowIndex) => {
65
+ sheetData.rows[(rowIndex - 1).toString()] = { cells: {} }
66
+ //includeEmpty = false 不包含空白单元格
67
+ row.eachCell({ includeEmpty: true }, function (cell, colNumber) {
68
+ let cellText = ''
69
+ if (cell.value && cell.value.result) {
70
+ // Excel 单元格有公式
71
+ cellText = cell.value.result
72
+ } else if (cell.value && cell.value.richText) {
73
+ // Excel 单元格是多行文本
74
+ for (let text in cell.value.richText) {
75
+ // 多行文本做累加
76
+ cellText += cell.value.richText[text].text
77
+ }
78
+ } else {
79
+ // Excel 单元格无公式
80
+ cellText = cell.value
81
+ }
82
+ //解析单元格,包含样式
83
+ //*********************单元格存在背景色******************************
84
+ // 单元格存在背景色
85
+ let backGroundColor = null
86
+ if (cell.style.fill && cell.style.fill.fgColor && cell.style.fill.fgColor.argb) {
87
+ // 8位字符颜色先转rgb再转16进制颜色
88
+ backGroundColor = (val => {
89
+ val = val.trim().toLowerCase() //去掉前后空格
90
+ let argb = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(val)
91
+ let rgb = `rgba(${parseInt(argb[2], 16)}, ${parseInt(argb[3], 16)}, ${parseInt(argb[4], 16)})`
92
+ let percent = (parseInt(argb[1], 16) / 255) * 100
93
+ return $vUtils.fade(rgb, percent)
94
+ })(cell.style.fill.fgColor.argb)
95
+ }
96
+
97
+ if (backGroundColor) {
98
+ cell.style.bgcolor = backGroundColor
99
+ }
100
+ //*************************************************************************** */
101
+
102
+ //*********************字体存在背景色******************************
103
+ // 字体颜色
104
+ let fontColor = null
105
+ if (cell.style.font && cell.style.font.color && cell.style.font.color.argb) {
106
+ // 8位字符颜色先转rgb再转16进制颜色
107
+ fontColor = (val => {
108
+ val = val.trim().toLowerCase() //去掉前后空格
109
+ let argb = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(val)
110
+ let rgb = `rgba(${parseInt(argb[2], 16)}, ${parseInt(argb[3], 16)}, ${parseInt(argb[4], 16)})`
111
+ let percent = (parseInt(argb[1], 16) / 255) * 100
112
+ return $vUtils.fade(rgb, percent)
113
+ })(cell.style.font.color.argb)
114
+ }
115
+ if (fontColor) {
116
+ cell.style.color = fontColor
117
+ }
118
+
119
+ // exceljs 对齐的格式转成 x-date-spreedsheet 能识别的对齐格式
120
+ if (cell.style.alignment && cell.style.alignment.horizontal) {
121
+ cell.style.align = cell.style.alignment.horizontal
122
+ cell.style.valign = cell.style.alignment.vertical
123
+ }
124
+
125
+ //处理合并单元格
126
+ let mergeAddress = _.find(mergeAddressData, function (o) {
127
+ return o.startAddress === cell._address
128
+ })
129
+ if (mergeAddress) {
130
+ // 遍历的单元格属于合并单元格
131
+ if (cell.master.address !== mergeAddress.startAddress) {
132
+ // 不是合并单元格中的第一个单元格不需要计入数据源
133
+ return
134
+ }
135
+ // 说明是合并单元格区域的起始单元格
136
+ sheetData.rows[(rowIndex - 1).toString()].cells[(colNumber - 1).toString()] = { text: cellText, style: 0, merge: [mergeAddress.YRange, mergeAddress.XRange] }
137
+ sheetData.styles.push(cell.style)
138
+ //对应的style存放序号
139
+ sheetData.rows[(rowIndex - 1).toString()].cells[(colNumber - 1).toString()].style = sheetData.styles.length - 1
140
+ } else {
141
+ // 非合并单元格
142
+ sheetData.rows[(rowIndex - 1).toString()].cells[(colNumber - 1).toString()] = { text: cellText, style: 0 }
143
+ //解析单元格,包含样式
144
+ sheetData.styles.push(cell.style)
145
+ //对应的style存放序号
146
+ sheetData.rows[(rowIndex - 1).toString()].cells[(colNumber - 1).toString()].style = sheetData.styles.length - 1
147
+ }
148
+ })
149
+ })
150
+ workbookData.push(sheetData)
151
+ })
152
+ // return new Spreadsheet(rootRef.value, excelOptions).loadData(workbookData)
153
+ }
154
+
155
+ const useData = dataHook(props, context, proxy, {
156
+ domRender
157
+ })
158
+
159
+ return {
160
+ ...useData
161
+ }
162
+ }
163
+ })
164
+ </script>
165
+
166
+ <template>
167
+ <div ref="rootRef" class="sh-office-excel"></div>
168
+ </template>
169
+
170
+ <style lang="scss" scoped>
171
+ .x-spreadsheet {
172
+ font-size: 13px;
173
+ line-height: normal;
174
+ user-select: none;
175
+ -moz-user-select: none;
176
+ font-family: 'Lato', 'Source Sans Pro', Roboto, Helvetica, Arial, sans-serif;
177
+ box-sizing: content-box;
178
+ background: #fff;
179
+ -webkit-font-smoothing: antialiased;
180
+ }
181
+ .x-spreadsheet textarea {
182
+ font: 400 13px Arial, 'Lato', 'Source Sans Pro', Roboto, Helvetica, sans-serif;
183
+ }
184
+ .x-spreadsheet-sheet {
185
+ position: relative;
186
+ overflow: hidden;
187
+ }
188
+ .x-spreadsheet-table {
189
+ vertical-align: bottom;
190
+ }
191
+ .x-spreadsheet-tooltip {
192
+ font-family: inherit;
193
+ position: absolute;
194
+ padding: 5px 10px;
195
+ color: #fff;
196
+ border-radius: 1px;
197
+ background: #000000;
198
+ font-size: 12px;
199
+ z-index: 201;
200
+ }
201
+ .x-spreadsheet-tooltip:before {
202
+ pointer-events: none;
203
+ position: absolute;
204
+ left: calc(50% - 4px);
205
+ top: -4px;
206
+ content: '';
207
+ width: 8px;
208
+ height: 8px;
209
+ background: inherit;
210
+ -webkit-transform: rotate(45deg);
211
+ transform: rotate(45deg);
212
+ z-index: 1;
213
+ box-shadow: 1px 1px 3px -1px rgba(0, 0, 0, 0.3);
214
+ }
215
+ .x-spreadsheet-color-palette {
216
+ padding: 5px;
217
+ }
218
+ .x-spreadsheet-color-palette table {
219
+ margin: 0;
220
+ padding: 0;
221
+ border-collapse: separate;
222
+ background: #fff;
223
+ }
224
+ .x-spreadsheet-color-palette table td {
225
+ margin: 0;
226
+ cursor: pointer;
227
+ border: 1px solid transparent;
228
+ }
229
+ .x-spreadsheet-color-palette table td:hover {
230
+ border-color: #ddd;
231
+ }
232
+ .x-spreadsheet-color-palette table td .x-spreadsheet-color-palette-cell {
233
+ width: 16px;
234
+ height: 16px;
235
+ }
236
+ .x-spreadsheet-border-palette {
237
+ padding: 6px;
238
+ }
239
+ .x-spreadsheet-border-palette table {
240
+ margin: 0;
241
+ padding: 0;
242
+ border-collapse: separate;
243
+ border-spacing: 0;
244
+ background: #fff;
245
+ table-layout: fixed;
246
+ }
247
+ .x-spreadsheet-border-palette table td {
248
+ margin: 0;
249
+ }
250
+ .x-spreadsheet-border-palette .x-spreadsheet-border-palette-left {
251
+ border-right: 1px solid #eee;
252
+ padding-right: 6px;
253
+ }
254
+ .x-spreadsheet-border-palette .x-spreadsheet-border-palette-left .x-spreadsheet-border-palette-cell {
255
+ width: 30px;
256
+ height: 30px;
257
+ cursor: pointer;
258
+ text-align: center;
259
+ }
260
+ .x-spreadsheet-border-palette .x-spreadsheet-border-palette-left .x-spreadsheet-border-palette-cell:hover {
261
+ background-color: #eee;
262
+ }
263
+ .x-spreadsheet-border-palette .x-spreadsheet-border-palette-right {
264
+ padding-left: 6px;
265
+ }
266
+ .x-spreadsheet-border-palette .x-spreadsheet-border-palette-right .x-spreadsheet-line-type {
267
+ position: relative;
268
+ left: 0;
269
+ top: -3px;
270
+ }
271
+ .x-spreadsheet-dropdown {
272
+ position: relative;
273
+ }
274
+ .x-spreadsheet-dropdown .x-spreadsheet-dropdown-content {
275
+ position: absolute;
276
+ z-index: 200;
277
+ background: #fff;
278
+ box-shadow: 1px 2px 5px 2px rgba(51, 51, 51, 0.15);
279
+ }
280
+ .x-spreadsheet-dropdown.bottom-left .x-spreadsheet-dropdown-content {
281
+ top: calc(100% + 5px);
282
+ left: 0;
283
+ }
284
+ .x-spreadsheet-dropdown.bottom-right .x-spreadsheet-dropdown-content {
285
+ top: calc(100% + 5px);
286
+ right: 0;
287
+ }
288
+ .x-spreadsheet-dropdown.top-left .x-spreadsheet-dropdown-content {
289
+ bottom: calc(100% + 5px);
290
+ left: 0;
291
+ }
292
+ .x-spreadsheet-dropdown.top-right .x-spreadsheet-dropdown-content {
293
+ bottom: calc(100% + 5px);
294
+ right: 0;
295
+ }
296
+ .x-spreadsheet-dropdown .x-spreadsheet-dropdown-title {
297
+ padding: 0 5px;
298
+ display: inline-block;
299
+ }
300
+ /* resizer **/
301
+ .x-spreadsheet-resizer {
302
+ position: absolute;
303
+ z-index: 11;
304
+ }
305
+ .x-spreadsheet-resizer .x-spreadsheet-resizer-hover {
306
+ background-color: rgba(75, 137, 255, 0.25);
307
+ }
308
+ .x-spreadsheet-resizer .x-spreadsheet-resizer-line {
309
+ position: absolute;
310
+ }
311
+ .x-spreadsheet-resizer.horizontal {
312
+ cursor: row-resize;
313
+ }
314
+ .x-spreadsheet-resizer.horizontal .x-spreadsheet-resizer-line {
315
+ border-bottom: 2px dashed #4b89ff;
316
+ left: 0;
317
+ bottom: 0;
318
+ }
319
+ .x-spreadsheet-resizer.vertical {
320
+ cursor: col-resize;
321
+ }
322
+ .x-spreadsheet-resizer.vertical .x-spreadsheet-resizer-line {
323
+ border-right: 2px dashed #4b89ff;
324
+ top: 0;
325
+ right: 0;
326
+ }
327
+ /* scrollbar */
328
+ .x-spreadsheet-scrollbar {
329
+ position: absolute;
330
+ bottom: 0;
331
+ right: 0;
332
+ background-color: #f4f5f8;
333
+ opacity: 0.9;
334
+ z-index: 12;
335
+ }
336
+ .x-spreadsheet-scrollbar.horizontal {
337
+ right: 15px;
338
+ overflow-x: scroll;
339
+ overflow-y: hidden;
340
+ }
341
+ .x-spreadsheet-scrollbar.horizontal > div {
342
+ height: 1px;
343
+ background: #ddd;
344
+ }
345
+ .x-spreadsheet-scrollbar.vertical {
346
+ bottom: 15px;
347
+ overflow-x: hidden;
348
+ overflow-y: scroll;
349
+ }
350
+ .x-spreadsheet-scrollbar.vertical > div {
351
+ width: 1px;
352
+ background: #ddd;
353
+ }
354
+ /* @{css-prefix}-overlayer */
355
+ .x-spreadsheet-overlayer {
356
+ position: absolute;
357
+ left: 0;
358
+ top: 0;
359
+ z-index: 10;
360
+ }
361
+ .x-spreadsheet-overlayer .x-spreadsheet-overlayer-content {
362
+ position: absolute;
363
+ overflow: hidden;
364
+ pointer-events: none;
365
+ width: 100%;
366
+ height: 100%;
367
+ }
368
+ .x-spreadsheet-editor,
369
+ .x-spreadsheet-selector {
370
+ box-sizing: content-box;
371
+ position: absolute;
372
+ overflow: hidden;
373
+ pointer-events: none;
374
+ top: 0;
375
+ left: 0;
376
+ width: 100%;
377
+ height: 100%;
378
+ }
379
+ /* @{css-prefix}-selector */
380
+ .x-spreadsheet-selector .hide-input {
381
+ position: absolute;
382
+ z-index: 0;
383
+ }
384
+ .x-spreadsheet-selector .hide-input input {
385
+ padding: 0;
386
+ width: 0;
387
+ border: none !important;
388
+ }
389
+ .x-spreadsheet-selector .x-spreadsheet-selector-area {
390
+ position: absolute;
391
+ border: 2px solid #4b89ff;
392
+ background: rgba(75, 137, 255, 0.1);
393
+ z-index: 5;
394
+ }
395
+ .x-spreadsheet-selector .x-spreadsheet-selector-clipboard,
396
+ .x-spreadsheet-selector .x-spreadsheet-selector-autofill {
397
+ position: absolute;
398
+ background: transparent;
399
+ z-index: 100;
400
+ }
401
+ .x-spreadsheet-selector .x-spreadsheet-selector-clipboard {
402
+ border: 2px dashed #4b89ff;
403
+ }
404
+ .x-spreadsheet-selector .x-spreadsheet-selector-autofill {
405
+ border: 1px dashed rgba(0, 0, 0, 0.45);
406
+ }
407
+ .x-spreadsheet-selector .x-spreadsheet-selector-corner {
408
+ pointer-events: auto;
409
+ position: absolute;
410
+ cursor: crosshair;
411
+ font-size: 0;
412
+ height: 5px;
413
+ width: 5px;
414
+ right: -5px;
415
+ bottom: -5px;
416
+ border: 2px solid #ffffff;
417
+ background: #4b89ff;
418
+ }
419
+ .x-spreadsheet-editor {
420
+ z-index: 20;
421
+ }
422
+ .x-spreadsheet-editor .x-spreadsheet-editor-area {
423
+ position: absolute;
424
+ text-align: left;
425
+ border: 2px solid #4b89ff;
426
+ line-height: 0;
427
+ z-index: 100;
428
+ pointer-events: auto;
429
+ }
430
+ .x-spreadsheet-editor .x-spreadsheet-editor-area textarea {
431
+ box-sizing: content-box;
432
+ border: none;
433
+ padding: 0 3px;
434
+ outline: none;
435
+ resize: none;
436
+ text-align: start;
437
+ overflow-y: hidden;
438
+ font: 400 13px Arial, 'Lato', 'Source Sans Pro', Roboto, Helvetica, sans-serif;
439
+ color: inherit;
440
+ white-space: normal;
441
+ word-wrap: break-word;
442
+ line-height: 22px;
443
+ margin: 0;
444
+ }
445
+ .x-spreadsheet-editor .x-spreadsheet-editor-area .textline {
446
+ overflow: hidden;
447
+ visibility: hidden;
448
+ position: fixed;
449
+ top: 0;
450
+ left: 0;
451
+ }
452
+ .x-spreadsheet-item {
453
+ user-select: none;
454
+ background: 0;
455
+ border: 1px solid transparent;
456
+ outline: none;
457
+ height: 26px;
458
+ color: rgba(0, 0, 0, 0.9);
459
+ line-height: 26px;
460
+ list-style: none;
461
+ padding: 2px 10px;
462
+ cursor: default;
463
+ text-align: left;
464
+ overflow: hidden;
465
+ }
466
+ .x-spreadsheet-item.disabled {
467
+ pointer-events: none;
468
+ opacity: 0.5;
469
+ }
470
+ .x-spreadsheet-item:hover,
471
+ .x-spreadsheet-item.active {
472
+ background: rgba(0, 0, 0, 0.05);
473
+ }
474
+ .x-spreadsheet-item.divider {
475
+ height: 0;
476
+ padding: 0;
477
+ margin: 5px 0;
478
+ border: none;
479
+ border-bottom: 1px solid rgba(0, 0, 0, 0.1);
480
+ }
481
+ .x-spreadsheet-item .label {
482
+ float: right;
483
+ opacity: 0.65;
484
+ font-size: 1em;
485
+ }
486
+ .x-spreadsheet-item.state,
487
+ .x-spreadsheet-header.state {
488
+ padding-left: 35px !important;
489
+ position: relative;
490
+ }
491
+ .x-spreadsheet-item.state:before,
492
+ .x-spreadsheet-header.state:before {
493
+ content: '';
494
+ position: absolute;
495
+ width: 10px;
496
+ height: 10px;
497
+ left: 12px;
498
+ top: calc(50% - 5px);
499
+ background: rgba(0, 0, 0, 0.08);
500
+ border-radius: 2px;
501
+ }
502
+ .x-spreadsheet-item.state.checked:before,
503
+ .x-spreadsheet-header.state.checked:before {
504
+ background: #4b89ff;
505
+ }
506
+ .x-spreadsheet-checkbox {
507
+ position: relative;
508
+ display: inline-block;
509
+ backface-visibility: hidden;
510
+ outline: 0;
511
+ vertical-align: baseline;
512
+ font-style: normal;
513
+ font-size: 1rem;
514
+ line-height: 1em;
515
+ }
516
+ .x-spreadsheet-checkbox > input {
517
+ position: absolute;
518
+ top: 0;
519
+ left: 0;
520
+ opacity: 0 !important;
521
+ outline: 0;
522
+ z-index: -1;
523
+ }
524
+ .x-spreadsheet-suggest,
525
+ .x-spreadsheet-contextmenu,
526
+ .x-spreadsheet-sort-filter {
527
+ position: absolute;
528
+ box-shadow: 1px 2px 5px 2px rgba(51, 51, 51, 0.15);
529
+ background: #fff;
530
+ z-index: 100;
531
+ width: 260px;
532
+ pointer-events: auto;
533
+ overflow: auto;
534
+ }
535
+ .x-spreadsheet-suggest {
536
+ width: 200px;
537
+ }
538
+ .x-spreadsheet-filter {
539
+ border: 1px solid #e9e9e9;
540
+ font-size: 12px;
541
+ margin: 10px;
542
+ }
543
+ .x-spreadsheet-filter .x-spreadsheet-header {
544
+ padding: 0.5em 0.75em;
545
+ background: #f8f8f9;
546
+ border-bottom: 1px solid #e9e9e9;
547
+ border-left: 1px solid transparent;
548
+ }
549
+ .x-spreadsheet-filter .x-spreadsheet-body {
550
+ height: 200px;
551
+ overflow-y: auto;
552
+ }
553
+ .x-spreadsheet-filter .x-spreadsheet-body .x-spreadsheet-item {
554
+ height: 20px;
555
+ line-height: 20px;
556
+ }
557
+ .x-spreadsheet-sort-filter .x-spreadsheet-buttons {
558
+ margin: 10px;
559
+ }
560
+ .x-spreadsheet-bottombar {
561
+ height: 40px;
562
+ padding: 0 30px;
563
+ text-align: left;
564
+ background: #f5f6f7;
565
+ display: flex;
566
+ }
567
+ .x-spreadsheet-bottombar {
568
+ position: relative;
569
+ border-top: 1px solid #e0e2e4;
570
+ }
571
+ .x-spreadsheet-bottombar .x-spreadsheet-menu > li {
572
+ line-height: 40px;
573
+ height: 40px;
574
+ padding-top: 0;
575
+ padding-bottom: 0;
576
+ vertical-align: middle;
577
+ border-right: 1px solid #e8eaed;
578
+ }
579
+ .x-spreadsheet-menu {
580
+ list-style: none;
581
+ margin: 0;
582
+ padding: 0;
583
+ user-select: none;
584
+ }
585
+ .x-spreadsheet-menu > li {
586
+ float: left;
587
+ line-height: 1.25em;
588
+ padding: 0.785em 1em;
589
+ margin: 0;
590
+ vertical-align: middle;
591
+ text-align: left;
592
+ color: #80868b;
593
+ white-space: nowrap;
594
+ cursor: pointer;
595
+ transition: all 0.3s;
596
+ font-weight: bold;
597
+ }
598
+ .x-spreadsheet-menu > li.active {
599
+ background-color: #fff;
600
+ color: rgba(0, 0, 0, 0.65);
601
+ }
602
+ .x-spreadsheet-menu > li .x-spreadsheet-dropdown {
603
+ display: inline-block;
604
+ }
605
+ .x-spreadsheet-print {
606
+ position: absolute;
607
+ left: 0;
608
+ top: 0;
609
+ z-index: 100;
610
+ width: 100%;
611
+ height: 100%;
612
+ display: flex;
613
+ flex-direction: column;
614
+ }
615
+ .x-spreadsheet-print-bar {
616
+ background: #424242;
617
+ height: 60px;
618
+ line-height: 60px;
619
+ padding: 0 30px;
620
+ }
621
+ .x-spreadsheet-print-bar .-title {
622
+ color: #fff;
623
+ font-weight: bold;
624
+ font-size: 1.2em;
625
+ float: left;
626
+ }
627
+ .x-spreadsheet-print-bar .-right {
628
+ float: right;
629
+ margin-top: 12px;
630
+ }
631
+ .x-spreadsheet-print-content {
632
+ display: flex;
633
+ flex: auto;
634
+ flex-direction: row;
635
+ background: #d0d0d0;
636
+ height: calc(100% - 60px);
637
+ }
638
+ .x-spreadsheet-print-content .-sider {
639
+ flex: 0 0 300px;
640
+ width: 300px;
641
+ border-left: 2px solid #ccc;
642
+ background: #fff;
643
+ }
644
+ .x-spreadsheet-print-content .-content {
645
+ flex: auto;
646
+ overflow-x: auto;
647
+ overflow-y: scroll;
648
+ height: 100%;
649
+ }
650
+ .x-spreadsheet-canvas-card-wraper {
651
+ margin: 40px 20px;
652
+ }
653
+ .x-spreadsheet-canvas-card {
654
+ background: #fff;
655
+ margin: auto;
656
+ page-break-before: auto;
657
+ page-break-after: always;
658
+ box-shadow: 0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 3px rgba(0, 0, 0, 0.12), 0 4px 5px 0 rgba(0, 0, 0, 0.2);
659
+ }
660
+ .x-spreadsheet-calendar {
661
+ color: rgba(0, 0, 0, 0.65);
662
+ background: #ffffff;
663
+ user-select: none;
664
+ }
665
+ .x-spreadsheet-calendar .calendar-header {
666
+ font-weight: 700;
667
+ line-height: 30px;
668
+ text-align: center;
669
+ width: 100%;
670
+ float: left;
671
+ background: #f9fafb;
672
+ }
673
+ .x-spreadsheet-calendar .calendar-header .calendar-header-left {
674
+ padding-left: 5px;
675
+ float: left;
676
+ }
677
+ .x-spreadsheet-calendar .calendar-header .calendar-header-right {
678
+ float: right;
679
+ }
680
+ .x-spreadsheet-calendar .calendar-header .calendar-header-right a {
681
+ padding: 3px 0;
682
+ margin-right: 2px;
683
+ border-radius: 2px;
684
+ }
685
+ .x-spreadsheet-calendar .calendar-header .calendar-header-right a:hover {
686
+ background: rgba(0, 0, 0, 0.08);
687
+ }
688
+ .x-spreadsheet-calendar .calendar-body {
689
+ border-collapse: collapse;
690
+ border-spacing: 0;
691
+ }
692
+ .x-spreadsheet-calendar .calendar-body th,
693
+ .x-spreadsheet-calendar .calendar-body td {
694
+ width: 14.28571429%;
695
+ min-width: 32px;
696
+ text-align: center;
697
+ font-weight: 700;
698
+ line-height: 30px;
699
+ padding: 0;
700
+ }
701
+ .x-spreadsheet-calendar .calendar-body td > .cell:hover {
702
+ background: #ecf6fd;
703
+ }
704
+ .x-spreadsheet-calendar .calendar-body td > .cell.active,
705
+ .x-spreadsheet-calendar .calendar-body td > .cell.active:hover {
706
+ background: #ecf6fd;
707
+ color: #2185d0;
708
+ }
709
+ .x-spreadsheet-calendar .calendar-body td > .cell.disabled {
710
+ pointer-events: none;
711
+ opacity: 0.5;
712
+ }
713
+ .x-spreadsheet-datepicker {
714
+ box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.2);
715
+ position: absolute;
716
+ left: 0;
717
+ top: calc(100% + 5px);
718
+ z-index: 10;
719
+ width: auto;
720
+ }
721
+ .x-spreadsheet-buttons {
722
+ display: flex;
723
+ justify-content: flex-end;
724
+ }
725
+ .x-spreadsheet-buttons .x-spreadsheet-button {
726
+ margin-left: 8px;
727
+ }
728
+ .x-spreadsheet-button {
729
+ display: inline-block;
730
+ border-radius: 3px;
731
+ line-height: 1em;
732
+ min-height: 1em;
733
+ white-space: nowrap;
734
+ text-align: center;
735
+ cursor: pointer;
736
+ font-size: 1em;
737
+ font-weight: 700;
738
+ padding: 0.75em 1em;
739
+ color: rgba(0, 0, 0, 0.6);
740
+ background: #e0e1e2;
741
+ text-decoration: none;
742
+ font-family: 'Lato', 'proxima-nova', 'Helvetica Neue', Arial, sans-serif;
743
+ outline: none;
744
+ vertical-align: baseline;
745
+ zoom: 1;
746
+ user-select: none;
747
+ transition: all 0.1s linear;
748
+ }
749
+ .x-spreadsheet-button.active,
750
+ .x-spreadsheet-button:hover {
751
+ background-color: #c0c1c2;
752
+ color: rgba(0, 0, 0, 0.8);
753
+ }
754
+ .x-spreadsheet-button.primary {
755
+ color: #fff;
756
+ background-color: #2185d0;
757
+ }
758
+ .x-spreadsheet-button.primary:hover,
759
+ .x-spreadsheet-button.primary.active {
760
+ color: #fff;
761
+ background-color: #1678c2;
762
+ }
763
+ .x-spreadsheet-form-input {
764
+ font-size: 1em;
765
+ position: relative;
766
+ font-weight: 400;
767
+ display: inline-flex;
768
+ color: rgba(0, 0, 0, 0.87);
769
+ }
770
+ .x-spreadsheet-form-input input {
771
+ z-index: 1;
772
+ margin: 0;
773
+ max-width: 100%;
774
+ flex: 1 0 auto;
775
+ outline: 0;
776
+ -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
777
+ text-align: left;
778
+ line-height: 30px;
779
+ height: 30px;
780
+ padding: 0 8px;
781
+ background: #fff;
782
+ border: 1px solid #e9e9e9;
783
+ border-radius: 3px;
784
+ transition: box-shadow 0.1s ease, border-color 0.1s ease;
785
+ box-shadow: inset 0 1px 2px hsla(0, 0%, 4%, 0.06);
786
+ }
787
+ .x-spreadsheet-form-input input:focus {
788
+ border-color: #4b89ff;
789
+ box-shadow: inset 0 1px 2px rgba(75, 137, 255, 0.2);
790
+ }
791
+ .x-spreadsheet-form-select {
792
+ position: relative;
793
+ display: inline-block;
794
+ background: #fff;
795
+ border: 1px solid #e9e9e9;
796
+ border-radius: 2px;
797
+ cursor: pointer;
798
+ color: rgba(0, 0, 0, 0.87);
799
+ user-select: none;
800
+ box-shadow: inset 0 1px 2px hsla(0, 0%, 4%, 0.06);
801
+ }
802
+ .x-spreadsheet-form-select .input-text {
803
+ text-overflow: ellipsis;
804
+ white-space: nowrap;
805
+ min-width: 60px;
806
+ width: auto;
807
+ height: 30px;
808
+ line-height: 30px;
809
+ padding: 0 8px;
810
+ }
811
+ .x-spreadsheet-form-fields {
812
+ display: flex;
813
+ flex-direction: row;
814
+ flex-wrap: wrap;
815
+ }
816
+ .x-spreadsheet-form-fields .x-spreadsheet-form-field {
817
+ flex: 0 1 auto;
818
+ }
819
+ .x-spreadsheet-form-fields .x-spreadsheet-form-field .label {
820
+ display: inline-block;
821
+ margin: 0 10px 0 0;
822
+ }
823
+ .x-spreadsheet-form-field {
824
+ display: block;
825
+ vertical-align: middle;
826
+ margin-left: 10px;
827
+ margin-bottom: 10px;
828
+ }
829
+ .x-spreadsheet-form-field:first-child {
830
+ margin-left: 0;
831
+ }
832
+ .x-spreadsheet-form-field.error .x-spreadsheet-form-select,
833
+ .x-spreadsheet-form-field.error input {
834
+ border-color: #f04134;
835
+ }
836
+ .x-spreadsheet-form-field .tip {
837
+ color: #f04134;
838
+ font-size: 0.9em;
839
+ }
840
+ .x-spreadsheet-dimmer {
841
+ display: none;
842
+ position: absolute;
843
+ top: 0 !important;
844
+ left: 0 !important;
845
+ width: 100%;
846
+ height: 100%;
847
+ text-align: center;
848
+ vertical-align: middle;
849
+ background-color: rgba(0, 0, 0, 0.6);
850
+ opacity: 0;
851
+ -webkit-animation-fill-mode: both;
852
+ animation-fill-mode: both;
853
+ -webkit-animation-duration: 0.5s;
854
+ animation-duration: 0.5s;
855
+ transition: background-color 0.5s linear;
856
+ user-select: none;
857
+ z-index: 1000;
858
+ }
859
+ .x-spreadsheet-dimmer.active {
860
+ display: block;
861
+ opacity: 1;
862
+ }
863
+ .x-spreadsheet-modal,
864
+ .x-spreadsheet-toast {
865
+ font-size: 13px;
866
+ position: fixed;
867
+ z-index: 1001;
868
+ text-align: left;
869
+ line-height: 1.25em;
870
+ min-width: 360px;
871
+ color: rgba(0, 0, 0, 0.87);
872
+ font-family: 'Lato', 'Source Sans Pro', Roboto, Helvetica, Arial, sans-serif;
873
+ border-radius: 4px;
874
+ border: 1px solid rgba(0, 0, 0, 0.1);
875
+ background-color: #fff;
876
+ background-clip: padding-box;
877
+ box-shadow: rgba(0, 0, 0, 0.2) 0px 2px 8px;
878
+ }
879
+ .x-spreadsheet-toast {
880
+ background-color: rgba(255, 255, 255, 0.85);
881
+ }
882
+ .x-spreadsheet-modal-header,
883
+ .x-spreadsheet-toast-header {
884
+ font-weight: 600;
885
+ background-clip: padding-box;
886
+ background-color: rgba(255, 255, 255, 0.85);
887
+ border-bottom: 1px solid rgba(0, 0, 0, 0.05);
888
+ border-radius: 4px 4px 0 0;
889
+ }
890
+
891
+ .x-spreadsheet-toast-header {
892
+ color: #f2711c;
893
+ }
894
+ .x-spreadsheet-modal-header {
895
+ border-bottom: 1px solid #e0e2e4;
896
+ background: rgba(0, 0, 0, 0.08);
897
+ font-size: 1.0785em;
898
+ }
899
+ .x-spreadsheet-modal-header,
900
+ .x-spreadsheet-modal-content,
901
+ .x-spreadsheet-toast-header,
902
+ .x-spreadsheet-toast-content {
903
+ padding: 0.75em 1em;
904
+ }
905
+
906
+ .x-spreadsheet-menu li:first-child {
907
+ display: none;
908
+ }
909
+ .sh-office-excel {
910
+ form fieldset {
911
+ border: none;
912
+ }
913
+ form fieldset label {
914
+ display: block;
915
+ margin-bottom: 0.5em;
916
+ font-size: 1em;
917
+ color: #666;
918
+ }
919
+ form fieldset select {
920
+ font-size: 1.1em;
921
+ width: 100%;
922
+ background-color: #fff;
923
+ border: none;
924
+ border-bottom: 2px solid #ddd;
925
+ padding: 0.5em 0.85em;
926
+ border-radius: 2px;
927
+ }
928
+ }
929
+ </style>