emacroh5lib 1.0.2 → 1.0.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.
@@ -0,0 +1,496 @@
1
+
2
+ import * as XLSX from 'xlsx'
3
+ import * as XLSXS from 'xlsx-style'
4
+ import { saveAs } from 'file-saver'
5
+ import { BookType } from 'xlsx';
6
+
7
+
8
+ export function generateArray(table: any) {
9
+ let out: Array<any> = [];
10
+ let rows = table.querySelectorAll("tr");
11
+ let ranges: Array<any> = [];
12
+ for (let R = 0; R < rows.length; ++R) {
13
+ let outRow: Array<any> = [];
14
+ let row = rows[R];
15
+ let columns = row.querySelectorAll("td");
16
+ for (let C = 0; C < columns.length; ++C) {
17
+ let cell = columns[C];
18
+ let colspan = cell.getAttribute("colspan");
19
+ let rowspan = cell.getAttribute("rowspan");
20
+ let cellValue = cell.innerText;
21
+ if (cellValue !== "" && cellValue == +cellValue) cellValue = +cellValue;
22
+
23
+ //Skip ranges
24
+ ranges.forEach(function (range: any) {
25
+ if (
26
+ R >= range.s.r &&
27
+ R <= range.e.r &&
28
+ outRow.length >= range.s.c &&
29
+ outRow.length <= range.e.c
30
+ ) {
31
+ for (let i = 0; i <= range.e.c - range.s.c; ++i) outRow.push(null);
32
+ }
33
+ });
34
+
35
+ //Handle Row Span
36
+ if (rowspan || colspan) {
37
+ rowspan = rowspan || 1;
38
+ colspan = colspan || 1;
39
+ ranges.push({
40
+ s: {
41
+ r: R,
42
+ c: outRow.length
43
+ },
44
+ e: {
45
+ r: (R + rowspan - 1),
46
+ c: (outRow.length + colspan - 1)
47
+ }
48
+ });
49
+ }
50
+
51
+ //Handle Value
52
+ outRow.push(cellValue !== "" ? cellValue : null);
53
+
54
+ //Handle Colspan
55
+ if (colspan)
56
+ for (var k = 0; k < colspan - 1; ++k) outRow.push(null);
57
+ }
58
+ out.push(outRow);
59
+ }
60
+ return [out, ranges];
61
+ }
62
+
63
+ export function datenum(v: any, date1904: any = null): number {
64
+ if (date1904) v += 1462;
65
+ let epoch = Date.parse(v);
66
+ return (epoch - new Date(Date.UTC(1899, 11, 30)).getTime()) / (24 * 60 * 60 * 1000);
67
+ }
68
+
69
+ export function sheet_from_array_of_arrays(data: any, opts: any = null) {
70
+
71
+ if (!opts) {
72
+ opts = ""
73
+ }
74
+
75
+ var ws: any = {};
76
+ var range = {
77
+ s: {
78
+ c: 10000000,
79
+ r: 10000000
80
+ },
81
+ e: {
82
+ c: 0,
83
+ r: 0
84
+ }
85
+ };
86
+ for (var R = 0; R != data.length; ++R) {
87
+ for (var C = 0; C != data[R].length; ++C) {
88
+ if (range.s.r > R) range.s.r = R;
89
+ if (range.s.c > C) range.s.c = C;
90
+ if (range.e.r < R) range.e.r = R;
91
+ if (range.e.c < C) range.e.c = C;
92
+ let cell: any = {
93
+ v: data[R][C]
94
+ };
95
+ // 如果单元格所在的值为空,让其值为“”,否则下面设置的边框对其不生效
96
+ if (cell.v == null) {
97
+ cell.v = "";
98
+ }
99
+ var cell_ref = XLSX.utils.encode_cell({
100
+ c: C,
101
+ r: R
102
+ });
103
+
104
+ if (typeof cell.v === "number") cell.t = "n";
105
+ else if (typeof cell.v === "boolean") cell.t = "b";
106
+ else if (cell.v instanceof Date) {
107
+ cell.t = "n";
108
+ cell.z = XLSX.SSF._table[14];
109
+ cell.v = datenum(cell.v);
110
+ } else cell.t = "s";
111
+
112
+ ws[cell_ref] = cell;
113
+ }
114
+ }
115
+ if (range.s.c < 10000000) ws["!ref"] = XLSX.utils.encode_range(range);
116
+ return ws;
117
+ }
118
+
119
+ class Workbook {
120
+
121
+ public SheetNames: any;
122
+ public Sheets: any;
123
+
124
+ constructor() {
125
+ if (!(this instanceof Workbook)) return new Workbook();
126
+ this.SheetNames = [];
127
+ this.Sheets = {};
128
+ }
129
+
130
+ }
131
+
132
+ export function s2ab(s: any) {
133
+ var buf = new ArrayBuffer(s.length);
134
+ var view = new Uint8Array(buf);
135
+ for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xff;
136
+ return buf;
137
+ }
138
+
139
+ export function export_table_to_excel(id: string) {
140
+ var theTable = document.getElementById(id);
141
+ var oo = generateArray(theTable);
142
+ var ranges = oo[1];
143
+
144
+ /* original data */
145
+ var data = oo[0];
146
+ var ws_name = "SheetJS";
147
+
148
+ var wb = new Workbook(),
149
+ ws = sheet_from_array_of_arrays(data);
150
+
151
+ /* add ranges to worksheet */
152
+ // ws['!cols'] = ['apple', 'banan'];
153
+ ws["!merges"] = ranges;
154
+
155
+ /* add worksheet to workbook */
156
+ wb.SheetNames.push(ws_name);
157
+ wb.Sheets[ws_name] = ws;
158
+
159
+ var wbout = XLSX.write(wb, {
160
+ bookType: "xlsx",
161
+ bookSST: false,
162
+ type: "binary"
163
+ });
164
+
165
+ saveAs(
166
+ new Blob([s2ab(wbout)], {
167
+ type: "application/octet-stream"
168
+ }),
169
+ "test.xlsx"
170
+ );
171
+ }
172
+
173
+ //数字转excel表头
174
+ export function number_to_excel(number: number) {
175
+ let str_1 = Math.floor(number / 26)
176
+ let str_2 = Math.round(number % 26) + 1
177
+ return (str_1 ? String.fromCharCode(0x60 + (str_1)).toUpperCase() : '') + String.fromCharCode(0x60 + (str_2)).toUpperCase();
178
+ }
179
+ // 主要修改内容在这里
180
+ export function export_json_to_excel({
181
+ title = null, // 新增的参数,表格标题
182
+ multiHeader = new Array<any>(),
183
+ header = new Array<any>(),
184
+ data = new Array<any>(),
185
+ filename = "excel-list",
186
+ styles = {} as any,
187
+ merges = new Array<any>(),
188
+ autoWidth = true,
189
+ bookType = "xlsx"
190
+ } = {}) {
191
+ /* original data */
192
+
193
+ console.log("样式", styles);
194
+
195
+
196
+ data = [...data];
197
+ data.unshift(header);
198
+ for (let i = multiHeader.length - 1; i > -1; i--) {
199
+ data.unshift(multiHeader[i]);
200
+ }
201
+ if (title) {
202
+ data.unshift(title); // 表格标题
203
+ }
204
+ var ws_name = "SheetJS";
205
+ var wb = new Workbook(),
206
+ ws = sheet_from_array_of_arrays(data);
207
+
208
+ if (merges.length > 0) {
209
+ if (!ws["!merges"]) ws["!merges"] = [];
210
+ merges.forEach(item => {
211
+ ws["!merges"].push(XLSX.utils.decode_range(item));
212
+ });
213
+ }
214
+
215
+ // 设置单元格宽度
216
+ if (autoWidth) {
217
+ /*设置worksheet每列的最大宽度*/
218
+ const colWidth = data.map(row =>
219
+ row.map((val: any) => {
220
+ /*先判断是否为null/undefined*/
221
+ if (val == null || val == undefined) {
222
+ return {
223
+ wch: 10
224
+ };
225
+ } else if ((val.toString().charCodeAt(3) || val.toString().charCodeAt(0)) > 255) {
226
+ /*再判断是否为中文*/
227
+ return {
228
+ wch: 10 + val.toString().length * 2
229
+ };
230
+ } else {
231
+ return {
232
+ wch: 10 + val.toString().length * 1.5
233
+ };
234
+ }
235
+ })
236
+ );
237
+ /*如果第一行是表格标题,会比较长,以主表第二行为初始值*/
238
+ let result = colWidth[title ? 1 : 0];
239
+ for (let i = 1; i < colWidth.length; i++) {
240
+ for (let j = 0; j < colWidth[i].length; j++) {
241
+ if (result[j] && result[j]["wch"] < colWidth[i][j]["wch"]) {
242
+ result[j]["wch"] = colWidth[i][j]["wch"];
243
+ }
244
+ }
245
+ }
246
+ ws["!cols"] = result;
247
+ }
248
+ /* add worksheet to workbook */
249
+ wb.SheetNames.push(ws_name);
250
+ wb.Sheets[ws_name] = ws;
251
+
252
+ var dataInfo = wb.Sheets[wb.SheetNames[0]];
253
+ // 设置单元格框线
254
+ const borderAll = {
255
+ top: {
256
+ style: "thin"
257
+ },
258
+ bottom: {
259
+ style: "thin"
260
+ },
261
+ left: {
262
+ style: "thin"
263
+ },
264
+ right: {
265
+ style: "thin"
266
+ }
267
+ };
268
+
269
+ // 给所有单元格加上边框,内容居中,字体,字号,标题表头特殊格式部分后面替换
270
+ for (var i in dataInfo) {
271
+ if (
272
+ i == "!ref" ||
273
+ i == "!merges" ||
274
+ i == "!cols" ||
275
+ i == "!rows" ||
276
+ i == "A1"
277
+ ) { } else {
278
+ dataInfo[i + ""].s = {
279
+ border: borderAll,
280
+ alignment: {
281
+ horizontal: "center",
282
+ vertical: "center"
283
+ },
284
+ font: {
285
+ name: "微软雅黑",
286
+ sz: 10
287
+ }
288
+ };
289
+ if (styles[i.replace(/[^A-Z]+/ig, '')]) {
290
+ Object.assign(dataInfo[i + ""].s, styles[i.replace(/[^A-Z]+/ig, '')])
291
+ }
292
+ }
293
+ }
294
+
295
+ // 设置表格样式
296
+ const arrabc = ["A",
297
+ "B",
298
+ "C",
299
+ "D",
300
+ "E",
301
+ "F",
302
+ "G",
303
+ "H",
304
+ "I",
305
+ "J",
306
+ "K",
307
+ "L",
308
+ "M",
309
+ "N",
310
+ "O",
311
+ "P",
312
+ "Q",
313
+ "R",
314
+ "S",
315
+ "T",
316
+ "U",
317
+ "V",
318
+ "W",
319
+ "X",
320
+ "Y",
321
+ "Z"
322
+ ]
323
+
324
+ // 给标题、表格描述信息、表头等部分加上特殊格式
325
+ arrabc.some(function (v) {
326
+ for (let j = 1; j < multiHeader.length + (title ? 3 : 2); j++) {
327
+ const _v = v + j
328
+ if (dataInfo[_v]) {
329
+ dataInfo[_v].s = {};
330
+ // 标题部分A1-Z1
331
+ if (j == 1) {
332
+ dataInfo[v + j].s = {
333
+ font: {
334
+ name: "微软雅黑",
335
+ sz: 12,
336
+ color: {
337
+ rgb: "000000"
338
+ },
339
+ bold: true,
340
+ italic: false,
341
+ underline: false
342
+ },
343
+ alignment: {
344
+ horizontal: "center",
345
+ vertical: "center"
346
+ }
347
+ };
348
+ } else {
349
+ // 表头部分,根据表头特殊格式设置
350
+ if (multiHeader.length == 0) {
351
+ // multiHeader.length = 0 时表头没有合并单元格,表头只占1行A2-Z2
352
+ const fv = v + (multiHeader.length + (title ? 2 : 1))
353
+ dataInfo[fv].s = {
354
+ border: borderAll,
355
+ font: {
356
+ name: "微软雅黑",
357
+ sz: 12,
358
+ bold: true
359
+ },
360
+ alignment: {
361
+ horizontal: "center",
362
+ vertical: "center"
363
+ },
364
+ fill: {
365
+ fgColor: {
366
+ rgb: "f0f0f0"
367
+ },
368
+ },
369
+ }
370
+ } else if (multiHeader.length == 1) {
371
+ // multiHeader.length = 0 时表头有合并单元格,表头只占2行A2-Z2,A3-Z3,这是没有描述信息只有表头合并的
372
+ dataInfo[v + j].s = {
373
+ border: borderAll,
374
+ font: {
375
+ name: "微软雅黑",
376
+ sz: 12,
377
+ },
378
+ alignment: {
379
+ horizontal: "center",
380
+ vertical: "center"
381
+ },
382
+ fill: {
383
+ fgColor: {
384
+ rgb: "f0f0f0"
385
+ }
386
+ },
387
+ }
388
+ } else {
389
+ // multiHeader.length = 0 时表头有合并单元格,表头多行
390
+ dataInfo[v + j].s = {
391
+ border: borderAll,
392
+ font: {
393
+ name: "微软雅黑",
394
+ sz: 10,
395
+ },
396
+ alignment: {
397
+ horizontal: "left",
398
+ vertical: "center"
399
+ }
400
+ }
401
+ }
402
+ }
403
+ // multiHeader.length + 2 是表头的最后1行
404
+ // console.log(dataInfo,dataInfo[v + (multiHeader.length + 2)],v + (multiHeader.length + 2))
405
+ dataInfo[v + (multiHeader.length + (title ? 2 : 1))].s = {
406
+ border: borderAll,
407
+ font: {
408
+ name: "微软雅黑",
409
+ sz: 12,
410
+ },
411
+ alignment: {
412
+ horizontal: "center",
413
+ vertical: "center"
414
+ },
415
+ fill: {
416
+ fgColor: {
417
+ rgb: "f0f0f0"
418
+ }
419
+ },
420
+ }
421
+ }
422
+ }
423
+ });
424
+
425
+
426
+
427
+ let wbout = XLSX.write(wb, {
428
+ bookType: bookType as BookType,
429
+ bookSST: false,
430
+ type: "binary"
431
+ });
432
+ saveAs(
433
+ new Blob([s2ab(wbout)], {
434
+ type: "application/octet-stream"
435
+ }),
436
+ `${filename}.${bookType}`
437
+ );
438
+ }
439
+
440
+ export function formatJson(filterVal: any, jsonData: any) {
441
+ jsonData.map((row: any, index: number) => {
442
+ row.index = index + 1;
443
+ });
444
+ return jsonData.map((v: any) =>
445
+ filterVal.map((j: any) => {
446
+ return v[j];
447
+ })
448
+ );
449
+ }
450
+
451
+ export function testToExcel(e: any) {
452
+ console.log("testToExcel", e);
453
+
454
+
455
+ let header = ['标签', '姓名', '性别', '出生年月日'];
456
+ let filterVal = ["tag", "childName", "gender", "birthday"];
457
+ let list = [{
458
+ tag: '示例班',
459
+ childName: '示例',
460
+ gender: '男',
461
+ birthday: '2016/10/12',
462
+ }];
463
+ let data = formatJson(filterVal, list);
464
+
465
+ let styles: any = {};//按列改样式
466
+ let length_str = number_to_excel(header.length - 1)
467
+ console.log("length_str", length_str);
468
+
469
+ styles["D1"] = {
470
+ alignment: {
471
+ horizontal: "center",
472
+ },
473
+ font: {
474
+ color: {
475
+ rgb: "DE3151"
476
+ },
477
+ }
478
+ }
479
+ let merges = ["A2:A64"] as never[];
480
+ export_json_to_excel({
481
+ filename: "这是一个表格",
482
+ header,
483
+ autoWidth: true,
484
+ merges: merges,
485
+ styles: styles,
486
+ data: data,
487
+ });
488
+ }
489
+
490
+ export default {
491
+ formatJson,
492
+ number_to_excel,
493
+ export_json_to_excel,
494
+ export_table_to_excel,
495
+ testToExcel
496
+ }
@@ -0,0 +1,25 @@
1
+ .app-container {
2
+ height: 100%;
3
+ width: 100%;
4
+ margin: 0;
5
+ padding: 0;
6
+ }
7
+
8
+ .filler {
9
+ width: 100%;
10
+ height: 100%;
11
+ display: inline-block;
12
+ position: absolute;
13
+ top: 0;
14
+ left: 0;
15
+ }
16
+
17
+ .list {
18
+ position: absolute;
19
+ top: 30px;
20
+ bottom: 30px;
21
+ left: 30px;
22
+ right: 300px;
23
+ box-shadow: 0 0 2px #AAA;
24
+ background-color: white;
25
+ }