@indfnd/utils 0.0.31
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/CHANGELOG.md +247 -0
- package/dist/ind-utils.es.js +10831 -0
- package/dist/ind-utils.umd.cjs +36 -0
- package/global.d.ts +8 -0
- package/package.json +63 -0
- package/src/api/com.ts +8 -0
- package/src/api/index.ts +5 -0
- package/src/api/item.ts +20 -0
- package/src/api/platform/dict.ts +59 -0
- package/src/api/platform/index.ts +4 -0
- package/src/api/platform/menu.ts +44 -0
- package/src/api/platform/oss.ts +8 -0
- package/src/api/platform/user.ts +29 -0
- package/src/api/user.ts +8 -0
- package/src/config/base.config.ts +47 -0
- package/src/config/dev.config.ts +5 -0
- package/src/config/index.ts +11 -0
- package/src/config/prod.config.ts +5 -0
- package/src/index.ts +3 -0
- package/src/utils/cache/dict-cache.ts +11 -0
- package/src/utils/cache/index.ts +3 -0
- package/src/utils/cache/permission-cache.ts +15 -0
- package/src/utils/cache/user-cache.ts +15 -0
- package/src/utils/date.ts +57 -0
- package/src/utils/enum.ts +133 -0
- package/src/utils/event.ts +53 -0
- package/src/utils/excel.js +642 -0
- package/src/utils/half-year.ts +53 -0
- package/src/utils/index.ts +18 -0
- package/src/utils/is-type.ts +164 -0
- package/src/utils/mime-type.ts +67 -0
- package/src/utils/number.ts +144 -0
- package/src/utils/quarter.ts +58 -0
- package/src/utils/request/axios.extends.ts +9 -0
- package/src/utils/request/cache-rules.ts +19 -0
- package/src/utils/request/content-type.ts +16 -0
- package/src/utils/request/index.ts +20 -0
- package/src/utils/request/interceptors.ts +99 -0
- package/src/utils/request/url-params.ts +18 -0
- package/src/utils/sm3/index.ts +29 -0
- package/src/utils/sm3/sm3.ts +238 -0
- package/src/utils/storage.ts +51 -0
- package/src/utils/table.ts +252 -0
- package/src/utils/token.ts +57 -0
- package/src/utils/uuid.ts +10 -0
- package/src/utils/validate.ts +149 -0
- package/types/api/com.d.ts +2 -0
- package/types/api/com.d.ts.map +1 -0
- package/types/api/index.d.ts +5 -0
- package/types/api/index.d.ts.map +1 -0
- package/types/api/item.d.ts +5 -0
- package/types/api/item.d.ts.map +1 -0
- package/types/api/platform/dict.d.ts +4 -0
- package/types/api/platform/dict.d.ts.map +1 -0
- package/types/api/platform/index.d.ts +5 -0
- package/types/api/platform/index.d.ts.map +1 -0
- package/types/api/platform/menu.d.ts +17 -0
- package/types/api/platform/menu.d.ts.map +1 -0
- package/types/api/platform/oss.d.ts +2 -0
- package/types/api/platform/oss.d.ts.map +1 -0
- package/types/api/platform/user.d.ts +17 -0
- package/types/api/platform/user.d.ts.map +1 -0
- package/types/api/user.d.ts +2 -0
- package/types/api/user.d.ts.map +1 -0
- package/types/config/base.config.d.ts +31 -0
- package/types/config/base.config.d.ts.map +1 -0
- package/types/config/dev.config.d.ts +4 -0
- package/types/config/dev.config.d.ts.map +1 -0
- package/types/config/index.d.ts +61 -0
- package/types/config/index.d.ts.map +1 -0
- package/types/config/prod.config.d.ts +4 -0
- package/types/config/prod.config.d.ts.map +1 -0
- package/types/index.d.ts +4 -0
- package/types/index.d.ts.map +1 -0
- package/types/utils/cache/dict-cache.d.ts +3 -0
- package/types/utils/cache/dict-cache.d.ts.map +1 -0
- package/types/utils/cache/index.d.ts +3 -0
- package/types/utils/cache/index.d.ts.map +1 -0
- package/types/utils/cache/permission-cache.d.ts +4 -0
- package/types/utils/cache/permission-cache.d.ts.map +1 -0
- package/types/utils/cache/user-cache.d.ts +4 -0
- package/types/utils/cache/user-cache.d.ts.map +1 -0
- package/types/utils/date.d.ts +4 -0
- package/types/utils/date.d.ts.map +1 -0
- package/types/utils/enum.d.ts +90 -0
- package/types/utils/enum.d.ts.map +1 -0
- package/types/utils/event.d.ts +17 -0
- package/types/utils/event.d.ts.map +1 -0
- package/types/utils/excel.d.ts +48 -0
- package/types/utils/excel.d.ts.map +1 -0
- package/types/utils/half-year.d.ts +6 -0
- package/types/utils/half-year.d.ts.map +1 -0
- package/types/utils/index.d.ts +18 -0
- package/types/utils/index.d.ts.map +1 -0
- package/types/utils/is-type.d.ts +34 -0
- package/types/utils/is-type.d.ts.map +1 -0
- package/types/utils/mime-type.d.ts +68 -0
- package/types/utils/mime-type.d.ts.map +1 -0
- package/types/utils/number.d.ts +20 -0
- package/types/utils/number.d.ts.map +1 -0
- package/types/utils/quarter.d.ts +7 -0
- package/types/utils/quarter.d.ts.map +1 -0
- package/types/utils/request/axios.extends.d.ts +9 -0
- package/types/utils/request/axios.extends.d.ts.map +1 -0
- package/types/utils/request/cache-rules.d.ts +7 -0
- package/types/utils/request/cache-rules.d.ts.map +1 -0
- package/types/utils/request/content-type.d.ts +9 -0
- package/types/utils/request/content-type.d.ts.map +1 -0
- package/types/utils/request/index.d.ts +8 -0
- package/types/utils/request/index.d.ts.map +1 -0
- package/types/utils/request/interceptors.d.ts +4 -0
- package/types/utils/request/interceptors.d.ts.map +1 -0
- package/types/utils/request/url-params.d.ts +8 -0
- package/types/utils/request/url-params.d.ts.map +1 -0
- package/types/utils/sm3/index.d.ts +7 -0
- package/types/utils/sm3/index.d.ts.map +1 -0
- package/types/utils/sm3/sm3.d.ts +3 -0
- package/types/utils/sm3/sm3.d.ts.map +1 -0
- package/types/utils/storage.d.ts +8 -0
- package/types/utils/storage.d.ts.map +1 -0
- package/types/utils/table.d.ts +56 -0
- package/types/utils/table.d.ts.map +1 -0
- package/types/utils/token.d.ts +3 -0
- package/types/utils/token.d.ts.map +1 -0
- package/types/utils/uuid.d.ts +5 -0
- package/types/utils/uuid.d.ts.map +1 -0
- package/types/utils/validate.d.ts +9 -0
- package/types/utils/validate.d.ts.map +1 -0
|
@@ -0,0 +1,642 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
|
|
3
|
+
// const XlsxPopulate = require('xlsx-populate/browser/xlsx-populate')
|
|
4
|
+
import _ from 'lodash'
|
|
5
|
+
|
|
6
|
+
const titleStyle = {
|
|
7
|
+
// title style
|
|
8
|
+
bold: true,
|
|
9
|
+
fontSize: '14',
|
|
10
|
+
horizontalAlignment: 'center',
|
|
11
|
+
verticalAlignment: 'center',
|
|
12
|
+
}
|
|
13
|
+
const paramLeftStyle = {
|
|
14
|
+
fontSize: '10',
|
|
15
|
+
horizontalAlignment: 'left',
|
|
16
|
+
verticalAlignment: 'center',
|
|
17
|
+
topBorder: true,
|
|
18
|
+
bottomBorder: true,
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const paramRightStyle = {
|
|
22
|
+
fontSize: '10',
|
|
23
|
+
horizontalAlignment: 'right',
|
|
24
|
+
verticalAlignment: 'center',
|
|
25
|
+
topBorder: true,
|
|
26
|
+
bottomBorder: true,
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const columnTitleStyle = {
|
|
30
|
+
bold: true,
|
|
31
|
+
fontSize: '10',
|
|
32
|
+
horizontalAlignment: 'center',
|
|
33
|
+
verticalAlignment: 'center',
|
|
34
|
+
fill: 'bdc3c7',
|
|
35
|
+
topBorder: true,
|
|
36
|
+
bottomBorder: true,
|
|
37
|
+
leftBorder: true,
|
|
38
|
+
rightBorder: true,
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const dataCellStyle = {
|
|
42
|
+
fontSize: '10',
|
|
43
|
+
horizontalAlignment: 'center',
|
|
44
|
+
verticalAlignment: 'center',
|
|
45
|
+
topBorder: true,
|
|
46
|
+
bottomBorder: true,
|
|
47
|
+
leftBorder: true,
|
|
48
|
+
rightBorder: true,
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const titleHeight = 27
|
|
52
|
+
|
|
53
|
+
const paramHeight = 18
|
|
54
|
+
|
|
55
|
+
const columnTitleHeight = 18
|
|
56
|
+
|
|
57
|
+
const dataRowHeight = 18
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* 根据agGrid的参数,获取导出Excel所需要的参数
|
|
61
|
+
* @param {*} param0
|
|
62
|
+
*/
|
|
63
|
+
function getAgColumnTitleAndData({ columns, datas }) {
|
|
64
|
+
// columns是个树形结构,要根据他的树形结构计算出表头的数据,然后通过这个表头的数据计算出columnTitle和data
|
|
65
|
+
var columnsClo = _.cloneDeep(columns)
|
|
66
|
+
var datasClo = _.cloneDeep(datas)
|
|
67
|
+
|
|
68
|
+
// 删掉编辑列
|
|
69
|
+
_.remove(columnsClo, (d) => {
|
|
70
|
+
return d.cellClass && d?.cellClass?.indexOf('button') != -1
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
// 增加索引列
|
|
74
|
+
datasClo.forEach((dd, idx) => {
|
|
75
|
+
dd['__seq'] = idx + 1
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
_.forEach(columnsClo, (d) => {
|
|
79
|
+
if (d.cellClass && d?.cellClass?.indexOf('enum') != -1) {
|
|
80
|
+
// 处理枚举值
|
|
81
|
+
datasClo.forEach((dd) => {
|
|
82
|
+
dd[d.field] = d.cellRendererParams.datas[dd[d.field]]
|
|
83
|
+
})
|
|
84
|
+
}
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
// 根据列定义,取列定义的树深
|
|
88
|
+
const getDeepthOfCol = (col) => {
|
|
89
|
+
if (!col.children) {
|
|
90
|
+
return 1
|
|
91
|
+
} else {
|
|
92
|
+
var deepthSingle =
|
|
93
|
+
1 +
|
|
94
|
+
Math.max(
|
|
95
|
+
...col.children.map((d) => {
|
|
96
|
+
return getDeepthOfCol(d)
|
|
97
|
+
}),
|
|
98
|
+
)
|
|
99
|
+
col.deepth = deepthSingle
|
|
100
|
+
return deepthSingle
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
var deepth = Math.max(
|
|
104
|
+
...columnsClo.map((d) => {
|
|
105
|
+
var deepthSingle = getDeepthOfCol(d)
|
|
106
|
+
d.deepth = deepthSingle
|
|
107
|
+
return deepthSingle
|
|
108
|
+
}),
|
|
109
|
+
)
|
|
110
|
+
console.log('calc deepth = ', deepth)
|
|
111
|
+
|
|
112
|
+
// 根据列定义,取列定义的宽度
|
|
113
|
+
const getWidthOfCol = (col) => {
|
|
114
|
+
if (!col.children) {
|
|
115
|
+
return 1
|
|
116
|
+
} else {
|
|
117
|
+
var widthSingle = _.sum(
|
|
118
|
+
col.children.map((d) => {
|
|
119
|
+
return getWidthOfCol(d)
|
|
120
|
+
}),
|
|
121
|
+
)
|
|
122
|
+
col.width = widthSingle
|
|
123
|
+
return widthSingle
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
var width = _.sum(
|
|
127
|
+
columnsClo.map((d) => {
|
|
128
|
+
var widthSingle = getWidthOfCol(d)
|
|
129
|
+
d.width = widthSingle
|
|
130
|
+
return widthSingle
|
|
131
|
+
}),
|
|
132
|
+
)
|
|
133
|
+
console.log('calc width = ', width)
|
|
134
|
+
|
|
135
|
+
console.log('now columnsClo is ', columnsClo)
|
|
136
|
+
|
|
137
|
+
// 遍历树形数据,组织真正的待导出的表头数据
|
|
138
|
+
var columnTitle = []
|
|
139
|
+
var curCol = 1 // 用于辅助定位单元格开始结束位置,即当前遍历到的列的位置
|
|
140
|
+
var curDeep = 0 // 用于辅助定位单元格开始结束位置,即递归调用深度
|
|
141
|
+
function calcTitle(src, dist) {
|
|
142
|
+
curDeep += 1
|
|
143
|
+
src.reduce((rlt, col, idx) => {
|
|
144
|
+
if (col.children) {
|
|
145
|
+
rlt.push({
|
|
146
|
+
text: col.excelName || col.headerName || col.title, // 单元格数据
|
|
147
|
+
srow: curDeep, // 在excel开始行
|
|
148
|
+
scol: curCol, // 在excel开始列
|
|
149
|
+
erow: curDeep /* + 1*/, // 在excel结束行
|
|
150
|
+
ecol: curCol + col.width - 1, // 在excel结束列
|
|
151
|
+
})
|
|
152
|
+
calcTitle(col.children, rlt)
|
|
153
|
+
} else {
|
|
154
|
+
rlt.push({
|
|
155
|
+
text: col.excelName || col.headerName || col.title, // 单元格数据
|
|
156
|
+
srow: curDeep, // 在excel开始行
|
|
157
|
+
scol: curCol, // 在excel开始列
|
|
158
|
+
erow: deepth /* + 1*/, // 在excel结束行
|
|
159
|
+
ecol: curCol /* + 1*/, // 在excel结束列
|
|
160
|
+
})
|
|
161
|
+
curCol += 1
|
|
162
|
+
}
|
|
163
|
+
return rlt
|
|
164
|
+
}, dist)
|
|
165
|
+
curDeep -= 1
|
|
166
|
+
}
|
|
167
|
+
calcTitle(columnsClo, columnTitle)
|
|
168
|
+
|
|
169
|
+
// 组织真正的列定义,即所有的叶子结点
|
|
170
|
+
var columnsCalc = []
|
|
171
|
+
function calcColumns(src, dist) {
|
|
172
|
+
src.reduce((rlt, col) => {
|
|
173
|
+
if (col.children) {
|
|
174
|
+
calcColumns(col.children, rlt)
|
|
175
|
+
} else {
|
|
176
|
+
rlt.push(col)
|
|
177
|
+
}
|
|
178
|
+
return rlt
|
|
179
|
+
}, dist)
|
|
180
|
+
}
|
|
181
|
+
calcColumns(columnsClo, columnsCalc)
|
|
182
|
+
|
|
183
|
+
var columnAlign = columnsCalc.map((d) => d.align || 'left') // 对齐方式
|
|
184
|
+
var columnType = columnsCalc.map((d) => (d.align == 'right' || d.align == 'rightNum' ? 'n' : 's')) // 数据类型
|
|
185
|
+
var columnWidth = columnsCalc.map((d) =>
|
|
186
|
+
d.excelWidth ? d.excelWidth : d.width ? Math.floor(d.width / 10) : 10,
|
|
187
|
+
) // 列宽
|
|
188
|
+
var numberFormat = columnsCalc.map((d) => {
|
|
189
|
+
return d.numberFormat === undefined
|
|
190
|
+
? d.align == 'rightNum'
|
|
191
|
+
? '#,##0.0000'
|
|
192
|
+
: d.align == 'right'
|
|
193
|
+
? '#,##0.00'
|
|
194
|
+
: ''
|
|
195
|
+
: d.numberFormat
|
|
196
|
+
}) // 格式化信息
|
|
197
|
+
columnsCalc.map((d, idx) => {
|
|
198
|
+
d.field = d.field ? d.field : d.key
|
|
199
|
+
var t = d.excelName || d.headerName || d.title
|
|
200
|
+
t = t.replace(/<br\/>/g, '')
|
|
201
|
+
if (d.columnWidth !== undefined) {
|
|
202
|
+
columnWidth[idx] = d.columnWidth
|
|
203
|
+
} else {
|
|
204
|
+
if (t && columnWidth[idx] < t.length * 2) {
|
|
205
|
+
columnWidth[idx] = t.length * 2
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
})
|
|
209
|
+
var exportData = datasClo.map((d) => {
|
|
210
|
+
return columnsCalc.map((dd, idx) => {
|
|
211
|
+
if (dd.columnWidth !== undefined) {
|
|
212
|
+
columnWidth[idx] = dd.columnWidth
|
|
213
|
+
} else {
|
|
214
|
+
if (d[dd.field] && columnWidth[idx] < ('' + d[dd.field]).length * 2) {
|
|
215
|
+
columnWidth[idx] = ('' + d[dd.field]).length * 2
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
let cellStyle = null
|
|
219
|
+
if (dd.cellStyle) {
|
|
220
|
+
if (dd.cellStyle instanceof Function) {
|
|
221
|
+
cellStyle = dd.cellStyle(d[dd.field], d, datasClo)
|
|
222
|
+
} else {
|
|
223
|
+
cellStyle = dd.cellStyle
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
let formula = null
|
|
228
|
+
if (dd.formula) {
|
|
229
|
+
if (dd.formula instanceof Function) {
|
|
230
|
+
formula = dd.formula(d[dd.field], d, datasClo)
|
|
231
|
+
} else {
|
|
232
|
+
formula = dd.formula
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
return {
|
|
237
|
+
cellStyle,
|
|
238
|
+
formula,
|
|
239
|
+
value: d[dd.field],
|
|
240
|
+
}
|
|
241
|
+
})
|
|
242
|
+
})
|
|
243
|
+
|
|
244
|
+
return {
|
|
245
|
+
deepth,
|
|
246
|
+
columnAlign,
|
|
247
|
+
columnType,
|
|
248
|
+
columnWidth,
|
|
249
|
+
exportData,
|
|
250
|
+
numberFormat,
|
|
251
|
+
columnTitle,
|
|
252
|
+
columnsCalc,
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
var rowSpanExcelInfos = []
|
|
257
|
+
// 初始化表格跨行
|
|
258
|
+
function initRowSpanInfos(options) {
|
|
259
|
+
// 配置了单元格表格跨行的情况才执行以下计算
|
|
260
|
+
if (!!options.rowSpanColumns) {
|
|
261
|
+
if (!!options.rowSpanIndexCol) {
|
|
262
|
+
options.rowSpanIndexCol = options.rowSpanColumns[0]
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// 按列计算的合并结果
|
|
266
|
+
var rowSpanRlt = {}
|
|
267
|
+
|
|
268
|
+
var rowTmpMapping = {}
|
|
269
|
+
|
|
270
|
+
// 计算每一列的合并数据
|
|
271
|
+
function calcRowSpan(colId, followCol) {
|
|
272
|
+
// 用于excel导出计算
|
|
273
|
+
var colIdx = _.findIndex(options.columns, { field: colId })
|
|
274
|
+
|
|
275
|
+
// 已经计算过了
|
|
276
|
+
if (!!rowSpanRlt[colId]) {
|
|
277
|
+
return
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// 每一行数据的计算结果缓存变量
|
|
281
|
+
var rowSpansTmp = []
|
|
282
|
+
|
|
283
|
+
// 遍历数据的临时变量
|
|
284
|
+
var curVal = 'CUR_VAL'
|
|
285
|
+
|
|
286
|
+
// 当前值对应的缓存变量的第一行数据
|
|
287
|
+
var firstCurRow = {}
|
|
288
|
+
|
|
289
|
+
_.forEach(options.datas, function (d, idx) {
|
|
290
|
+
// 如果是首次计算跨行的主列,正常判断首行,否则要参考主列计算的值进行判断
|
|
291
|
+
var isFirstRow = !followCol
|
|
292
|
+
? d[colId] != curVal
|
|
293
|
+
: d[colId] != curVal || idx == (rowTmpMapping['' + idx] || {}).first
|
|
294
|
+
if (isFirstRow) {
|
|
295
|
+
// 如果是首次计算跨行的主列,需要缓存数据每一行的计算信息
|
|
296
|
+
if (!followCol && firstCurRow.first !== undefined) {
|
|
297
|
+
for (var j = firstCurRow.first; j <= firstCurRow.last; j++) {
|
|
298
|
+
rowTmpMapping['' + j] = {
|
|
299
|
+
first: firstCurRow.first,
|
|
300
|
+
last: firstCurRow.last,
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
curVal = d[colId]
|
|
305
|
+
firstCurRow = {
|
|
306
|
+
col: colId,
|
|
307
|
+
val: curVal,
|
|
308
|
+
first: idx,
|
|
309
|
+
last: idx,
|
|
310
|
+
rowSpan: 1,
|
|
311
|
+
}
|
|
312
|
+
rowSpansTmp.push(firstCurRow)
|
|
313
|
+
} else {
|
|
314
|
+
// 合并行
|
|
315
|
+
firstCurRow.last = idx
|
|
316
|
+
// rowSpan大于1表示此单元格要跨行
|
|
317
|
+
firstCurRow.rowSpan = firstCurRow.last - firstCurRow.first + 1
|
|
318
|
+
// rowspan 0表示要隐藏的cell
|
|
319
|
+
rowSpansTmp.push({ rowSpan: 0 })
|
|
320
|
+
|
|
321
|
+
// 最后一行没有放入firstCurRow数据里面,导致最后一个值的合并出了问题
|
|
322
|
+
if (!followCol && idx == options.datas.length - 1) {
|
|
323
|
+
for (var j = firstCurRow.first; j <= firstCurRow.last; j++) {
|
|
324
|
+
rowTmpMapping['' + j] = {
|
|
325
|
+
first: firstCurRow.first,
|
|
326
|
+
last: firstCurRow.last,
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
})
|
|
332
|
+
rowSpanRlt[colId] = rowSpansTmp
|
|
333
|
+
_.forEach(rowSpansTmp, function (row, idx) {
|
|
334
|
+
if (row.rowSpan > 1) {
|
|
335
|
+
rowSpanExcelInfos.push({
|
|
336
|
+
mergeRowS: idx,
|
|
337
|
+
mergeRowE: idx + row.rowSpan - 1,
|
|
338
|
+
megerColS: colIdx,
|
|
339
|
+
megerColE: colIdx,
|
|
340
|
+
})
|
|
341
|
+
}
|
|
342
|
+
})
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
calcRowSpan(options.rowSpanIndexCol)
|
|
346
|
+
|
|
347
|
+
// console.log(rowTmpMapping)
|
|
348
|
+
|
|
349
|
+
_.forEach(options.rowSpanColumns, function (col) {
|
|
350
|
+
calcRowSpan(col, true)
|
|
351
|
+
})
|
|
352
|
+
}
|
|
353
|
+
// console.log(rowSpanInfos)
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
/**
|
|
357
|
+
* 根据参数导出excel,目前系统仅支持agGrid和iviewTable,这两个表格的columns定义都是树形的,所以这里仅支持树形的列定义即可
|
|
358
|
+
* 根据每个column的树形信息,可以计算出每个column定义的单元格跨行跨列信息,直接得出excel待导出的表头
|
|
359
|
+
* 再根据列定义树形的叶子结点,可以得出每一列对应的字段名,根据这个信息组织待导出的数据
|
|
360
|
+
* 合并单元格需要单独配置,哪一列需要传参数进来,应该有一个主合并列,否则后面值全0的合并成一个了(直接拷贝slickgrid的吧)
|
|
361
|
+
* @param {
|
|
362
|
+
* title: '导出的excel名字,并excel内容的名字',
|
|
363
|
+
* columnAlign: ['center', 'left', 'right'], //'对齐方式'
|
|
364
|
+
* columnType: ['s', 'n', 'n'], // s String n Number
|
|
365
|
+
* columns: [] //'表头,列定义的树形结构',
|
|
366
|
+
* columnWidth: ['20','10'], //宽度,数组
|
|
367
|
+
* datas: [], // 数据,表格的原始数据
|
|
368
|
+
* paramLeft: '查询时间:2022年01月-2022年05月',
|
|
369
|
+
* paramRight: '箱、万元',
|
|
370
|
+
* numberFormat: ['', '0.00', '0.00'], // 数组,设置数据格式
|
|
371
|
+
* rowSpanColumns:[column1,column2……], // 需要跨行的列
|
|
372
|
+
* rowSpanIndexCol:'', // 根据哪一列进行跨行计算,如根据卷烟ITEM_NAME
|
|
373
|
+
* } excelData
|
|
374
|
+
*/
|
|
375
|
+
export function exportJsonToExcel(excelData) {
|
|
376
|
+
var calcExportDatas = getAgColumnTitleAndData(excelData)
|
|
377
|
+
|
|
378
|
+
console.log('calcExportDatas', calcExportDatas)
|
|
379
|
+
|
|
380
|
+
var title = excelData.title
|
|
381
|
+
|
|
382
|
+
var titleDeepth = calcExportDatas.deepth
|
|
383
|
+
var columnAlign = excelData.columnAlign || calcExportDatas.columnAlign
|
|
384
|
+
var columnType = excelData.columnType || calcExportDatas.columnType
|
|
385
|
+
|
|
386
|
+
var columnTitle = calcExportDatas.columnTitle
|
|
387
|
+
|
|
388
|
+
var columnWidth = excelData.columnWidth || calcExportDatas.columnWidth
|
|
389
|
+
|
|
390
|
+
var columnCount = columnAlign.length
|
|
391
|
+
|
|
392
|
+
var paramLeft = excelData.paramLeft
|
|
393
|
+
|
|
394
|
+
var paramRight = excelData.paramRight
|
|
395
|
+
|
|
396
|
+
var jsonData = calcExportDatas.exportData
|
|
397
|
+
|
|
398
|
+
var numberFormat = excelData.numberFormat || calcExportDatas.numberFormat
|
|
399
|
+
|
|
400
|
+
XlsxPopulate.fromBlankAsync()
|
|
401
|
+
.then((workbook) => {
|
|
402
|
+
// Modify the workbook.
|
|
403
|
+
var sheet = workbook.sheet('Sheet1') // 初始化的时候不能传中文进去
|
|
404
|
+
sheet.name(title)
|
|
405
|
+
// 设置列宽
|
|
406
|
+
for (var i = 0; i < columnCount; i++) {
|
|
407
|
+
sheet.column(i + 1).width(columnWidth[i] == 0 ? 10 : columnWidth[i])
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
var titleRange = sheet.range(1, 1, 1, columnCount)
|
|
411
|
+
titleRange.merged(true)
|
|
412
|
+
titleRange.style(titleStyle)
|
|
413
|
+
titleRange.cell(0, 0).value(title)
|
|
414
|
+
sheet.row(1).height(titleHeight)
|
|
415
|
+
|
|
416
|
+
var rowsNow = 2
|
|
417
|
+
|
|
418
|
+
if (!!excelData.paramLeft || !!excelData.paramRight) {
|
|
419
|
+
var paramLeftRange = sheet.range(2, 1, 2, Math.round(columnCount / 2))
|
|
420
|
+
paramLeftRange.cell(0, 0).value(paramLeft || '')
|
|
421
|
+
paramLeftRange.merged(true)
|
|
422
|
+
paramLeftRange.style(paramLeftStyle)
|
|
423
|
+
var paramRightRange = sheet.range(2, Math.round(columnCount / 2) + 1, 2, columnCount)
|
|
424
|
+
paramRightRange.cell(0, 0).value(paramRight || '')
|
|
425
|
+
paramRightRange.merged(true)
|
|
426
|
+
paramRightRange.style(paramRightStyle)
|
|
427
|
+
sheet.row(2).height(paramHeight)
|
|
428
|
+
rowsNow += 1
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
columnTitle.forEach((d) => {
|
|
432
|
+
var columnTitleRange = sheet.range(
|
|
433
|
+
d.srow + rowsNow - 1,
|
|
434
|
+
d.scol,
|
|
435
|
+
d.erow + rowsNow - 1,
|
|
436
|
+
d.ecol,
|
|
437
|
+
)
|
|
438
|
+
columnTitleRange.merged(true)
|
|
439
|
+
columnTitleRange.style(columnTitleStyle)
|
|
440
|
+
columnTitleRange.cell(0, 0).value(d.text.replace(/<br\/>/g, ''))
|
|
441
|
+
})
|
|
442
|
+
for (let i = 0; i < titleDeepth; i++) {
|
|
443
|
+
sheet.row(rowsNow + i).height(columnTitleHeight)
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
// 处理表格里的数据,挨家挨户搜一下
|
|
447
|
+
rowsNow += titleDeepth
|
|
448
|
+
|
|
449
|
+
for (var i = 0; i < jsonData.length; i++) {
|
|
450
|
+
var lineData = jsonData[i]
|
|
451
|
+
for (var j = 0; j < lineData.length; j++) {
|
|
452
|
+
if (columnType[j] === 's' && lineData[j]) {
|
|
453
|
+
sheet.cell(rowsNow + i, j + 1).value(lineData[j].value)
|
|
454
|
+
dataCellStyle.numberFormat = ''
|
|
455
|
+
} else if (columnType[j] === 'n' && lineData[j]) {
|
|
456
|
+
sheet
|
|
457
|
+
.cell(rowsNow + i, j + 1)
|
|
458
|
+
.value(lineData[j].value ? parseFloat(lineData[j].value) : lineData[j].value)
|
|
459
|
+
dataCellStyle.numberFormat = numberFormat[j] // 数字保留精度
|
|
460
|
+
} else {
|
|
461
|
+
// 预留一下,将来可能加别的样式
|
|
462
|
+
sheet.cell(rowsNow + i, j + 1).value('')
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
// 公式
|
|
466
|
+
if (lineData[j].formula) {
|
|
467
|
+
sheet.cell(rowsNow + i, j + 1).formula(lineData[j].formula)
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
// 样式
|
|
471
|
+
dataCellStyle.horizontalAlignment = columnAlign[j]
|
|
472
|
+
if (lineData[j].cellStyle) {
|
|
473
|
+
let cellStyle = _.merge({}, dataCellStyle, lineData[j].cellStyle)
|
|
474
|
+
sheet.cell(rowsNow + i, j + 1).style(cellStyle)
|
|
475
|
+
} else {
|
|
476
|
+
sheet.cell(rowsNow + i, j + 1).style(dataCellStyle)
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
if (excelData.rowColor && i % 2 != 0) {
|
|
480
|
+
var row = sheet.range(rowsNow + i, 1, rowsNow + i, columnCount)
|
|
481
|
+
row.style({ fill: 'f8f8f9' })
|
|
482
|
+
}
|
|
483
|
+
sheet.row(rowsNow + i).height(dataRowHeight)
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
if (!!excelData.rowSpanColumns) {
|
|
487
|
+
initRowSpanInfos({ ...excelData, columns: calcExportDatas.columnsCalc })
|
|
488
|
+
_.forEach(rowSpanExcelInfos, function (rowSpanInfo) {
|
|
489
|
+
var columnTitleRange = sheet.range(
|
|
490
|
+
rowSpanInfo.mergeRowS + rowsNow,
|
|
491
|
+
rowSpanInfo.megerColS + 1,
|
|
492
|
+
rowSpanInfo.mergeRowE + rowsNow,
|
|
493
|
+
rowSpanInfo.megerColE + 1,
|
|
494
|
+
)
|
|
495
|
+
columnTitleRange.merged(true)
|
|
496
|
+
})
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
// 表头无论如何都会有,都要固定,所以不需要加if判断
|
|
500
|
+
// if (excelData.leftColumns || excelData.topRows) {
|
|
501
|
+
sheet.freezePanes(excelData.leftColumns || 0, (excelData.topRows || 0) + rowsNow - 1)
|
|
502
|
+
// }
|
|
503
|
+
|
|
504
|
+
// Write to file.
|
|
505
|
+
workbook.outputAsync().then(function (blob) {
|
|
506
|
+
if (window.navigator && window.navigator.msSaveOrOpenBlob) {
|
|
507
|
+
// If IE, you must uses a different method.
|
|
508
|
+
window.navigator.msSaveOrOpenBlob(blob, title + '.xlsx')
|
|
509
|
+
} else {
|
|
510
|
+
var url = window.URL.createObjectURL(blob)
|
|
511
|
+
var a = document.createElement('a')
|
|
512
|
+
document.body.appendChild(a)
|
|
513
|
+
a.href = url
|
|
514
|
+
a.download = title + '.xlsx'
|
|
515
|
+
a.click()
|
|
516
|
+
window.URL.revokeObjectURL(url)
|
|
517
|
+
document.body.removeChild(a)
|
|
518
|
+
}
|
|
519
|
+
})
|
|
520
|
+
})
|
|
521
|
+
.catch((err) => console.log(err))
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
/**
|
|
525
|
+
* 根据参数导出excel,目前系统仅支持agGrid和iviewTable,这两个表格的columns定义都是树形的,所以这里仅支持树形的列定义即可
|
|
526
|
+
* 根据每个column的树形信息,可以计算出每个column定义的单元格跨行跨列信息,直接得出excel待导出的表头
|
|
527
|
+
* 再根据列定义树形的叶子结点,可以得出每一列对应的字段名,根据这个信息组织待导出的数据
|
|
528
|
+
* 合并单元格需要单独配置,哪一列需要传参数进来,应该有一个主合并列,否则后面值全0的合并成一个了(直接拷贝slickgrid的吧)
|
|
529
|
+
* @param {
|
|
530
|
+
* title: '导出的excel名字,并excel内容的名字',
|
|
531
|
+
* columnAlign: ['center', 'left', 'right'], //'对齐方式'
|
|
532
|
+
* columnType: ['s', 'n', 'n'], // s String n Number
|
|
533
|
+
* columns: [] //'表头,列定义的树形结构',
|
|
534
|
+
* columnWidth: ['20','10'], //宽度,数组
|
|
535
|
+
* datas: [], // 数据,表格的原始数据
|
|
536
|
+
* paramLeft: '查询时间:2022年01月-2022年05月',
|
|
537
|
+
* paramRight: '箱、万元',
|
|
538
|
+
* numberFormat: ['', '0.00', '0.00'], // 数组,设置数据格式
|
|
539
|
+
* rowSpanColumns:[column1,column2……], // 需要跨行的列
|
|
540
|
+
* rowSpanIndexCol:'', // 根据哪一列进行跨行计算,如根据卷烟ITEM_NAME
|
|
541
|
+
* } excelData
|
|
542
|
+
*/
|
|
543
|
+
export function importJsonFromExcel(excelData) {
|
|
544
|
+
return new Promise((resolve, reject) => {
|
|
545
|
+
var calcExportDatas = getAgColumnTitleAndData(excelData)
|
|
546
|
+
|
|
547
|
+
var titleDeepth = calcExportDatas.deepth
|
|
548
|
+
|
|
549
|
+
var jsonData = calcExportDatas.exportData
|
|
550
|
+
|
|
551
|
+
const reader = new FileReader()
|
|
552
|
+
reader.onload = async (event) => {
|
|
553
|
+
XlsxPopulate.fromDataAsync(event.target.result)
|
|
554
|
+
.then((workbook) => {
|
|
555
|
+
// Modify the workbook.
|
|
556
|
+
var sheet = workbook.sheet(0)
|
|
557
|
+
|
|
558
|
+
var rowsNow = 2
|
|
559
|
+
|
|
560
|
+
if (!!excelData.paramLeft || !!excelData.paramRight) {
|
|
561
|
+
rowsNow += 1
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
// 处理表格里的数据,挨家挨户搜一下
|
|
565
|
+
rowsNow += titleDeepth
|
|
566
|
+
|
|
567
|
+
let resutJson = []
|
|
568
|
+
// for (var i = 0; i < jsonData.length; i++) {
|
|
569
|
+
for (let i = rowsNow; i < sheet._rows.length; i++) {
|
|
570
|
+
var lineData = sheet.row(i)
|
|
571
|
+
let tmpRow = {}
|
|
572
|
+
resutJson.push(tmpRow)
|
|
573
|
+
// excel列数据 这个索引从1开始
|
|
574
|
+
for (let j = 1; j < lineData._cells.length; j++) {
|
|
575
|
+
let val = lineData._cells[j]?._value
|
|
576
|
+
if (j > calcExportDatas.columnsCalc.length) {
|
|
577
|
+
continue
|
|
578
|
+
}
|
|
579
|
+
let col = calcExportDatas.columnsCalc[j - 1]
|
|
580
|
+
tmpRow[col.field] = val
|
|
581
|
+
// excelData.datas[i][col.field] = val
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
resolve(resutJson)
|
|
586
|
+
})
|
|
587
|
+
.catch((err) => console.log(err))
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
reader.readAsArrayBuffer(excelData.file)
|
|
591
|
+
})
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
const ENGLISH_LETTER = [
|
|
595
|
+
'A',
|
|
596
|
+
'B',
|
|
597
|
+
'C',
|
|
598
|
+
'D',
|
|
599
|
+
'E',
|
|
600
|
+
'F',
|
|
601
|
+
'G',
|
|
602
|
+
'H',
|
|
603
|
+
'I',
|
|
604
|
+
'J',
|
|
605
|
+
'K',
|
|
606
|
+
'L',
|
|
607
|
+
'M',
|
|
608
|
+
'N',
|
|
609
|
+
'O',
|
|
610
|
+
'P',
|
|
611
|
+
'Q',
|
|
612
|
+
'R',
|
|
613
|
+
'S',
|
|
614
|
+
'T',
|
|
615
|
+
'U',
|
|
616
|
+
'V',
|
|
617
|
+
'W',
|
|
618
|
+
'X',
|
|
619
|
+
'Y',
|
|
620
|
+
'Z',
|
|
621
|
+
]
|
|
622
|
+
|
|
623
|
+
/**
|
|
624
|
+
* 根据列的数组下标返回excel对应的列号 (目前是按照.xlsx的定义计算的)
|
|
625
|
+
*
|
|
626
|
+
* @param {number} number 列的下标,从0开始计数
|
|
627
|
+
* @returns excel里的列号
|
|
628
|
+
*/
|
|
629
|
+
export function getExcelColumnIdx(number) {
|
|
630
|
+
if (!number) return ''
|
|
631
|
+
|
|
632
|
+
let rlt = ''
|
|
633
|
+
const length = ENGLISH_LETTER.length
|
|
634
|
+
|
|
635
|
+
while (number >= 0) {
|
|
636
|
+
const idx = number % length
|
|
637
|
+
rlt = ENGLISH_LETTER[idx] + rlt
|
|
638
|
+
|
|
639
|
+
number = parseInt((number - idx) / length) - 1
|
|
640
|
+
}
|
|
641
|
+
return rlt
|
|
642
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// 获取半年
|
|
2
|
+
export function getHalfYear(date: string) {
|
|
3
|
+
if (!date || date.length < 6) {
|
|
4
|
+
return ''
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
const year = date.substring(0, 4)
|
|
8
|
+
const month = date.substring(4, 6)
|
|
9
|
+
const halfYear = getHalfYearNum(parseInt(month))
|
|
10
|
+
return `${year}H${halfYear}`
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function getHalfYearNum(month: number | string) {
|
|
14
|
+
if (typeof month === 'string') {
|
|
15
|
+
if (isNaN(parseInt(month))) return 0
|
|
16
|
+
month = parseInt(month)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return month <= 6 ? 1 : 2
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function formatHalfYear(halfYear: string) {
|
|
23
|
+
if (!halfYear || halfYear.length < 6) {
|
|
24
|
+
return halfYear
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const year = halfYear.substring(0, 4)
|
|
28
|
+
const halfYearNum = parseInt(halfYear.substring(5))
|
|
29
|
+
const halfStr = halfYearNum === 1 ? '上半年' : '下半年'
|
|
30
|
+
return `${year}${halfStr}`
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function getHalfYearBeginMonth(halfYear: string) {
|
|
34
|
+
if (!halfYear || halfYear.length < 6) {
|
|
35
|
+
return halfYear
|
|
36
|
+
}
|
|
37
|
+
const year = halfYear.substring(0, 4)
|
|
38
|
+
const halfYearNum = parseInt(halfYear.substring(5))
|
|
39
|
+
const beginMonth = halfYearNum * 6 - 5
|
|
40
|
+
const monthStr = beginMonth < 10 ? `0${beginMonth}` : `${beginMonth}`
|
|
41
|
+
return `${year}${monthStr}`
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function getHalfYearEndMonth(halfYear: string) {
|
|
45
|
+
if (!halfYear || halfYear.length < 6) {
|
|
46
|
+
return halfYear
|
|
47
|
+
}
|
|
48
|
+
const year = halfYear.substring(0, 4)
|
|
49
|
+
const halfYearNum = parseInt(halfYear.substring(5))
|
|
50
|
+
const endMonth = halfYearNum * 2
|
|
51
|
+
const monthStr = endMonth < 10 ? `0${endMonth}` : `${endMonth}`
|
|
52
|
+
return `${year}${monthStr}`
|
|
53
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export * from './cache'
|
|
2
|
+
export * from './request'
|
|
3
|
+
export * from './sm3'
|
|
4
|
+
|
|
5
|
+
export * from './date'
|
|
6
|
+
export * from './enum'
|
|
7
|
+
export * from './excel'
|
|
8
|
+
export * from './event'
|
|
9
|
+
export * from './half-year'
|
|
10
|
+
export * from './is-type'
|
|
11
|
+
export * from './mime-type'
|
|
12
|
+
export * from './number'
|
|
13
|
+
export * from './quarter'
|
|
14
|
+
export * from './storage'
|
|
15
|
+
export * from './table'
|
|
16
|
+
export * from './token'
|
|
17
|
+
export * from './uuid'
|
|
18
|
+
export * from './validate'
|