y-admin-ui 0.5.2 → 0.5.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.
- package/lib/utils/core.ts +45 -0
- package/lib/utils/directives/click-outside/index.ts +106 -0
- package/lib/utils/index.ts +142 -0
- package/lib/utils/printer.ts +997 -0
- package/lib/utils/vue/props/runtime.ts +3 -0
- package/lib/utils/vue/typescript.ts +1 -0
- package/lib/y-admin-ui.js +1487 -1569
- package/lib/y-admin-ui.js.gz +0 -0
- package/lib/y-admin-ui.umd.cjs +14 -14
- package/package.json +1 -1
@@ -0,0 +1,997 @@
|
|
1
|
+
/** 打印插件 */
|
2
|
+
|
3
|
+
export interface PrintThisOptions {
|
4
|
+
hide?: Array<string> | string;
|
5
|
+
horizontal?: boolean | string | null | undefined;
|
6
|
+
iePreview?: boolean;
|
7
|
+
blank?: boolean;
|
8
|
+
close?: boolean;
|
9
|
+
margin?: string | number | null | undefined;
|
10
|
+
title?: string;
|
11
|
+
isHideNone?: boolean;
|
12
|
+
}
|
13
|
+
|
14
|
+
export interface PrintHtmlOptions {
|
15
|
+
html?: string;
|
16
|
+
print?: boolean;
|
17
|
+
loading?: boolean;
|
18
|
+
header?: string;
|
19
|
+
footer?: string;
|
20
|
+
before?: Function;
|
21
|
+
done?: Function;
|
22
|
+
style?: string;
|
23
|
+
}
|
24
|
+
|
25
|
+
export interface PrintHtmlOptionsExtends extends PrintThisOptions {
|
26
|
+
html?: string;
|
27
|
+
print?: boolean;
|
28
|
+
loading?: boolean;
|
29
|
+
header?: string;
|
30
|
+
footer?: string;
|
31
|
+
before?: Function;
|
32
|
+
done?: Function;
|
33
|
+
style?: string;
|
34
|
+
}
|
35
|
+
|
36
|
+
export interface PrintPageOptionsExtends extends PrintHtmlOptionsExtends {
|
37
|
+
htmls?: Array<string>;
|
38
|
+
pages?: Array<string>;
|
39
|
+
style?: string;
|
40
|
+
padding?: string;
|
41
|
+
isDebug?: boolean;
|
42
|
+
width?: string;
|
43
|
+
height?: string;
|
44
|
+
}
|
45
|
+
|
46
|
+
export interface makeTableCols {
|
47
|
+
field?: string;
|
48
|
+
title?: string;
|
49
|
+
width?: number | string;
|
50
|
+
align?: string;
|
51
|
+
thAlign?: string;
|
52
|
+
colspan?: number;
|
53
|
+
rowspan?: number;
|
54
|
+
style?: string;
|
55
|
+
thStyle?: string;
|
56
|
+
templet?: Function;
|
57
|
+
[key : string]: any;
|
58
|
+
}
|
59
|
+
|
60
|
+
|
61
|
+
/**
|
62
|
+
* ie 打印预览控件
|
63
|
+
*/
|
64
|
+
const ieWebBrowser =
|
65
|
+
'<object id="WebBrowser" classid="clsid:8856F961-340A-11D0-A96B-00C04FD705A2" width="0" height="0"></object>';
|
66
|
+
|
67
|
+
/**
|
68
|
+
* iframe 打印窗口的 id
|
69
|
+
*/
|
70
|
+
const printFrameId = 'y-printer-frame';
|
71
|
+
|
72
|
+
/**
|
73
|
+
* 打印全局样式的 style 的 id
|
74
|
+
*/
|
75
|
+
const printStyleId = 'y-printer-style';
|
76
|
+
|
77
|
+
/**
|
78
|
+
* 打印方向设置的 style 的 id
|
79
|
+
*/
|
80
|
+
const printOptionId = 'y-printer-set';
|
81
|
+
|
82
|
+
/**
|
83
|
+
* 加载层 id
|
84
|
+
*/
|
85
|
+
const loadingElId = 'y-printer-loading';
|
86
|
+
|
87
|
+
/**
|
88
|
+
* 正在打印标识的 class
|
89
|
+
*/
|
90
|
+
const printingClass = 'y-printer-printing';
|
91
|
+
|
92
|
+
/**
|
93
|
+
* 打印时隐藏的 class
|
94
|
+
*/
|
95
|
+
const hideClass = 'y-printer-hide';
|
96
|
+
|
97
|
+
/**
|
98
|
+
* 打印时隐藏不占位置的 class
|
99
|
+
*/
|
100
|
+
const hideNoneClass = 'y-printer-hide-none';
|
101
|
+
|
102
|
+
/**
|
103
|
+
* 生成随机 id
|
104
|
+
* @param length 长度
|
105
|
+
*/
|
106
|
+
function uuid(length = 8) {
|
107
|
+
const num = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';
|
108
|
+
let str = 'p_';
|
109
|
+
for (let i = 0; i < length; i++) {
|
110
|
+
str += num.charAt(Math.floor(Math.random() * num.length));
|
111
|
+
}
|
112
|
+
return str;
|
113
|
+
}
|
114
|
+
|
115
|
+
/**
|
116
|
+
* 是否是 ie
|
117
|
+
*/
|
118
|
+
function isIE() {
|
119
|
+
return !!window['ActiveXObject'] || 'ActiveXObject' in window;
|
120
|
+
}
|
121
|
+
|
122
|
+
/**
|
123
|
+
* 获取的打印 iframe
|
124
|
+
*/
|
125
|
+
function getPrintFrame() {
|
126
|
+
const pFrame = document.getElementById(printFrameId);
|
127
|
+
if (pFrame && pFrame.parentNode) {
|
128
|
+
pFrame.parentNode.removeChild(pFrame);
|
129
|
+
}
|
130
|
+
const elem = document.createElement('iframe');
|
131
|
+
elem.id = printFrameId;
|
132
|
+
elem.style.width = '0px';
|
133
|
+
elem.style.height = '0px';
|
134
|
+
elem.style.position = 'fixed';
|
135
|
+
elem.style.visibility = 'hidden';
|
136
|
+
document.body.appendChild(elem);
|
137
|
+
elem.focus();
|
138
|
+
return elem;
|
139
|
+
}
|
140
|
+
|
141
|
+
/**
|
142
|
+
* 获取打印全局样式
|
143
|
+
* @param isPrinting 是否已开始打印
|
144
|
+
*/
|
145
|
+
function getCommonCss(isPrinting = false) {
|
146
|
+
return `
|
147
|
+
@media print {
|
148
|
+
html, body {
|
149
|
+
padding: 0;
|
150
|
+
margin: 0;
|
151
|
+
}
|
152
|
+
|
153
|
+
::-webkit-scrollbar {
|
154
|
+
width: 0 !important;
|
155
|
+
height: 0!important;
|
156
|
+
}
|
157
|
+
|
158
|
+
.el-scrollbar__wrap {
|
159
|
+
margin: 0 !important;
|
160
|
+
}
|
161
|
+
}
|
162
|
+
|
163
|
+
/* 打印时不显示的元素 */
|
164
|
+
.${hideClass}.${printingClass} {
|
165
|
+
visibility: hidden !important;
|
166
|
+
}
|
167
|
+
.${hideClass} {
|
168
|
+
${isPrinting ? 'visibility: hidden !important;' : ''}
|
169
|
+
}
|
170
|
+
.${hideClass}.${printingClass}.${hideNoneClass},
|
171
|
+
.${hideClass}.${hideNoneClass}${isPrinting ? '' : '-no'} {
|
172
|
+
display: none !important;
|
173
|
+
}
|
174
|
+
|
175
|
+
/* 表格样式 */
|
176
|
+
.y-printer-table {
|
177
|
+
width: 100%;
|
178
|
+
border-collapse: collapse;
|
179
|
+
border: none;
|
180
|
+
}
|
181
|
+
.y-printer-table td, .y-printer-table th {
|
182
|
+
color: #333;
|
183
|
+
padding: 9px 15px;
|
184
|
+
border: 1px solid #333;
|
185
|
+
word-break: break-all;
|
186
|
+
}
|
187
|
+
|
188
|
+
/* loading样式 */
|
189
|
+
#${loadingElId} {
|
190
|
+
position: fixed;
|
191
|
+
top: 0;
|
192
|
+
left: 0;
|
193
|
+
right: 0;
|
194
|
+
bottom: 0;
|
195
|
+
background-color: hsla(0, 0%, 100%, .9);
|
196
|
+
z-index: 19000000;
|
197
|
+
}
|
198
|
+
#${loadingElId}:after {
|
199
|
+
content: "";
|
200
|
+
width: 40px;
|
201
|
+
height: 40px;
|
202
|
+
position: absolute;
|
203
|
+
top: 50%;
|
204
|
+
left: 50%;
|
205
|
+
margin: -20px auto auto -20px;
|
206
|
+
border: 2px solid #3296FA;
|
207
|
+
border-right-color: transparent;
|
208
|
+
border-bottom-color: transparent;
|
209
|
+
border-radius: 50%;
|
210
|
+
animation: ele-printer-loading-anim .8s linear infinite;
|
211
|
+
}
|
212
|
+
@keyframes ele-printer-loading-anim {
|
213
|
+
from {
|
214
|
+
transform: rotate(0deg);
|
215
|
+
}
|
216
|
+
to {
|
217
|
+
transform: rotate(360deg);
|
218
|
+
}
|
219
|
+
}
|
220
|
+
|
221
|
+
/* 带页眉页脚页面样式 */
|
222
|
+
.y-printer-table-page {
|
223
|
+
width: 100%;
|
224
|
+
border-collapse: collapse;
|
225
|
+
border: none;
|
226
|
+
}
|
227
|
+
.y-printer-table-page td {
|
228
|
+
padding: 0;
|
229
|
+
border: none;
|
230
|
+
}
|
231
|
+
`;
|
232
|
+
}
|
233
|
+
|
234
|
+
/**
|
235
|
+
* 获取分页打印的样式
|
236
|
+
* @param padding 每一页边距
|
237
|
+
* @param width 每一页宽度
|
238
|
+
* @param height 每一页高度
|
239
|
+
*/
|
240
|
+
function getPageStyleHtml(padding: any, width: any, height: any) {
|
241
|
+
return `
|
242
|
+
<style>
|
243
|
+
body {
|
244
|
+
margin: 0 !important;
|
245
|
+
}
|
246
|
+
|
247
|
+
/* 自定义边距及宽高样式 */
|
248
|
+
.ele-printer-page .ele-printer-page-item {
|
249
|
+
width: ${width ?? 'auto'};
|
250
|
+
height: ${height ?? 'auto'};
|
251
|
+
padding: ${padding ?? '0'};
|
252
|
+
page-break-after: always !important;
|
253
|
+
box-sizing: border-box !important;
|
254
|
+
border: none !important;
|
255
|
+
position: relative;
|
256
|
+
}
|
257
|
+
|
258
|
+
/* 调试模式样式 */
|
259
|
+
.ele-printer-page.ele-printer-debug .ele-printer-page-item {
|
260
|
+
border: 1px solid red !important;
|
261
|
+
}
|
262
|
+
|
263
|
+
/* 全局样式 */
|
264
|
+
${getCommonCss(true)}
|
265
|
+
</style>
|
266
|
+
`;
|
267
|
+
}
|
268
|
+
|
269
|
+
/**
|
270
|
+
* 生成控制打印的 html
|
271
|
+
* @param option PrintHtmlOption
|
272
|
+
*/
|
273
|
+
function getOptionHtml(option: PrintPageOptionsExtends) {
|
274
|
+
const { beforeJs, doneJs } = addCallback(option.before, option.done);
|
275
|
+
const blank = option.blank || (option.iePreview !== false && isIE());
|
276
|
+
const closeJs = blank && option.close !== false ? 'window.close();' : '';
|
277
|
+
const hideLoadJs =
|
278
|
+
'parent.hideElePrinterLoading&&parent.hideElePrinterLoading();';
|
279
|
+
const optHtml = [];
|
280
|
+
|
281
|
+
// 增加打印设置的 css
|
282
|
+
optHtml.push(`<style type="text/css" media="print" id="${printOptionId}">`);
|
283
|
+
optHtml.push('@page {');
|
284
|
+
// 打印方向
|
285
|
+
if (typeof option.horizontal !== 'undefined') {
|
286
|
+
optHtml.push(`size: ${option.horizontal ? 'landscape' : 'portrait'};`);
|
287
|
+
}
|
288
|
+
// 页间距
|
289
|
+
if (option.margin != null) {
|
290
|
+
optHtml.push(`margin: ${option.margin};`);
|
291
|
+
}
|
292
|
+
optHtml.push(`}`);
|
293
|
+
optHtml.push(`</style>`);
|
294
|
+
|
295
|
+
// 增加打印和回调的 js
|
296
|
+
if (option.iePreview !== false && isIE()) {
|
297
|
+
// 兼容 ie 打印预览
|
298
|
+
optHtml.push(ieWebBrowser);
|
299
|
+
if (option.print !== false) {
|
300
|
+
optHtml.push(`
|
301
|
+
<script>
|
302
|
+
window.onload = function() {
|
303
|
+
${beforeJs}
|
304
|
+
try {
|
305
|
+
window.WebBrowser.ExecWB(7, 1);
|
306
|
+
} catch(e) {
|
307
|
+
console.error(e);
|
308
|
+
window.print();
|
309
|
+
}
|
310
|
+
${hideLoadJs}
|
311
|
+
${doneJs}
|
312
|
+
${closeJs}
|
313
|
+
}
|
314
|
+
</script>
|
315
|
+
`);
|
316
|
+
}
|
317
|
+
} else if (option.print !== false) {
|
318
|
+
optHtml.push(`
|
319
|
+
<script>
|
320
|
+
window.onload = function() {
|
321
|
+
${beforeJs}
|
322
|
+
window.print();
|
323
|
+
${hideLoadJs}
|
324
|
+
${doneJs}
|
325
|
+
${closeJs}
|
326
|
+
}
|
327
|
+
</script>
|
328
|
+
`);
|
329
|
+
}
|
330
|
+
return optHtml.join('');
|
331
|
+
}
|
332
|
+
|
333
|
+
/**
|
334
|
+
* 加入核心样式
|
335
|
+
*/
|
336
|
+
function addCommonCss() {
|
337
|
+
if (!document.getElementById(printStyleId)) {
|
338
|
+
const elem = document.createElement('style');
|
339
|
+
elem.id = printStyleId;
|
340
|
+
elem.setAttribute('type', 'text/css');
|
341
|
+
elem.innerHTML = getCommonCss();
|
342
|
+
document.body.appendChild(elem);
|
343
|
+
}
|
344
|
+
}
|
345
|
+
|
346
|
+
/**
|
347
|
+
* 增加页眉页脚
|
348
|
+
* @param html 页面内容
|
349
|
+
* @param header 页眉
|
350
|
+
* @param footer 页脚
|
351
|
+
*/
|
352
|
+
function addHeaderFooter(html: string, header: string | undefined, footer: string | undefined) {
|
353
|
+
if (!header && !footer) {
|
354
|
+
return html ?? '';
|
355
|
+
}
|
356
|
+
let result = '<table class="y-printer-table-page">';
|
357
|
+
if (header) {
|
358
|
+
result += `<thead><tr><td>${header}</td></tr></thead>`;
|
359
|
+
}
|
360
|
+
result += `<tbody><tr><td>${html ?? ''}</td></tr></tbody>`;
|
361
|
+
if (footer) {
|
362
|
+
result += `<tfoot><tr><td>${footer}</td></tr></tfoot>`;
|
363
|
+
}
|
364
|
+
return result + '</table>';
|
365
|
+
}
|
366
|
+
|
367
|
+
/**
|
368
|
+
* 添加回调监听
|
369
|
+
* @param before 打印前回调
|
370
|
+
* @param done 打印后回调
|
371
|
+
*/
|
372
|
+
function addCallback(before: any, done: any) {
|
373
|
+
const taskId = 'p' + uuid();
|
374
|
+
if (!window['yPrinterBefore']) {
|
375
|
+
window['yPrinterBefore'] = {};
|
376
|
+
}
|
377
|
+
if (!window['yPrinterDone']) {
|
378
|
+
window['yPrinterDone'] = {};
|
379
|
+
}
|
380
|
+
if (before) {
|
381
|
+
window['yPrinterBefore'][taskId] = before;
|
382
|
+
}
|
383
|
+
if (done) {
|
384
|
+
window['yPrinterDone'][taskId] = done;
|
385
|
+
}
|
386
|
+
const beforeJs = `;parent.elePrinterBefore&&parent.elePrinterBefore.${taskId}&&parent.elePrinterBefore.${taskId}();`;
|
387
|
+
const doneJs = `;parent.elePrinterDone&&parent.elePrinterDone.${taskId}&&parent.elePrinterDone.${taskId}();`;
|
388
|
+
return { taskId, beforeJs, doneJs };
|
389
|
+
}
|
390
|
+
|
391
|
+
/**
|
392
|
+
* 隐藏元素
|
393
|
+
* @param elems 需要隐藏的元素
|
394
|
+
* @param isNone 是否是隐藏不占位置
|
395
|
+
*/
|
396
|
+
function hideElem(elems: Array<string> | string, isNone: boolean) {
|
397
|
+
Array.prototype.forEach.call(
|
398
|
+
document.getElementsByClassName(hideClass),
|
399
|
+
(elem) => {
|
400
|
+
if (elem?.classList) {
|
401
|
+
elem.classList.add(printingClass);
|
402
|
+
}
|
403
|
+
}
|
404
|
+
);
|
405
|
+
if (!elems) {
|
406
|
+
return;
|
407
|
+
}
|
408
|
+
const isArray =
|
409
|
+
Array?.isArray(elems) ||
|
410
|
+
// eslint-disable-next-line no-prototype-builtins
|
411
|
+
NodeList?.prototype?.isPrototypeOf(elems) ||
|
412
|
+
// eslint-disable-next-line no-prototype-builtins
|
413
|
+
HTMLCollection?.prototype?.isPrototypeOf(elems);
|
414
|
+
Array.prototype.forEach.call(isArray ? elems : [elems], (elem) => {
|
415
|
+
if (typeof elem === 'string') {
|
416
|
+
Array.prototype.forEach.call(document.querySelectorAll(elem), (el) => {
|
417
|
+
if (el?.classList) {
|
418
|
+
el.classList.add(hideClass);
|
419
|
+
el.classList.add(printingClass);
|
420
|
+
if (isNone) {
|
421
|
+
el.classList.add(hideNoneClass);
|
422
|
+
}
|
423
|
+
}
|
424
|
+
});
|
425
|
+
} else if (elem?.classList) {
|
426
|
+
elem.classList.add(hideClass);
|
427
|
+
elem.classList.add(printingClass);
|
428
|
+
if (isNone) {
|
429
|
+
elem.classList.add(hideNoneClass);
|
430
|
+
}
|
431
|
+
}
|
432
|
+
});
|
433
|
+
}
|
434
|
+
|
435
|
+
/**
|
436
|
+
* 取消隐藏元素
|
437
|
+
* @param elems 需要取消隐藏的元素
|
438
|
+
*/
|
439
|
+
function showElem(elems: string | Object) {
|
440
|
+
Array.prototype.forEach.call(
|
441
|
+
document.getElementsByClassName(hideClass),
|
442
|
+
(elem) => {
|
443
|
+
if (elem?.classList) {
|
444
|
+
elem.classList.remove(printingClass);
|
445
|
+
}
|
446
|
+
}
|
447
|
+
);
|
448
|
+
if (!elems) {
|
449
|
+
return;
|
450
|
+
}
|
451
|
+
const isArray =
|
452
|
+
Array?.isArray(elems) ||
|
453
|
+
// eslint-disable-next-line no-prototype-builtins
|
454
|
+
NodeList?.prototype?.isPrototypeOf(elems) ||
|
455
|
+
// eslint-disable-next-line no-prototype-builtins
|
456
|
+
HTMLCollection?.prototype?.isPrototypeOf(elems);
|
457
|
+
Array.prototype.forEach.call(isArray ? elems : [elems], (elem) => {
|
458
|
+
if (typeof elem === 'string') {
|
459
|
+
Array.prototype.forEach.call(document.querySelectorAll(elem), (el) => {
|
460
|
+
if (el?.classList) {
|
461
|
+
el.classList.remove(hideClass);
|
462
|
+
el.classList.remove(printingClass);
|
463
|
+
el.classList.remove(hideNoneClass);
|
464
|
+
}
|
465
|
+
});
|
466
|
+
} else if (elem?.classList) {
|
467
|
+
elem.classList.remove(hideClass);
|
468
|
+
elem.classList.remove(printingClass);
|
469
|
+
elem.classList.remove(hideNoneClass);
|
470
|
+
}
|
471
|
+
});
|
472
|
+
}
|
473
|
+
|
474
|
+
/**
|
475
|
+
* 显示加载层
|
476
|
+
*/
|
477
|
+
export function showPrintLoading() {
|
478
|
+
addCommonCss();
|
479
|
+
let elem = document.getElementById(loadingElId);
|
480
|
+
if (!elem) {
|
481
|
+
elem = document.createElement('div');
|
482
|
+
elem.id = loadingElId;
|
483
|
+
document.body.appendChild(elem);
|
484
|
+
}
|
485
|
+
elem.style.display = 'block';
|
486
|
+
window['hideElePrinterLoading'] = () => {
|
487
|
+
hidePrintLoading();
|
488
|
+
};
|
489
|
+
return elem;
|
490
|
+
}
|
491
|
+
|
492
|
+
/**
|
493
|
+
* 关闭加载层
|
494
|
+
*/
|
495
|
+
export function hidePrintLoading() {
|
496
|
+
const elem = document.getElementById(loadingElId);
|
497
|
+
if (elem) {
|
498
|
+
elem.style.display = 'none';
|
499
|
+
}
|
500
|
+
}
|
501
|
+
|
502
|
+
/**
|
503
|
+
* 打印当前页面
|
504
|
+
* @param hide 需要隐藏的元素
|
505
|
+
* @param horizontal 是否横向打印
|
506
|
+
* @param iePreview 是否支持ie打印预览
|
507
|
+
* @param blank 是否在新窗口打印
|
508
|
+
* @param close 如果在新窗口打印,打印完是否关闭新窗口
|
509
|
+
* @param margin 页间距
|
510
|
+
* @param title 页面标题
|
511
|
+
*
|
512
|
+
*/
|
513
|
+
export function printThis(
|
514
|
+
{
|
515
|
+
hide = '',
|
516
|
+
horizontal = false,
|
517
|
+
iePreview = true,
|
518
|
+
blank = false,
|
519
|
+
close = true,
|
520
|
+
margin = 0,
|
521
|
+
title,
|
522
|
+
isHideNone
|
523
|
+
}: PrintThisOptions
|
524
|
+
) {
|
525
|
+
// 让当前窗口获取焦点
|
526
|
+
window.focus();
|
527
|
+
|
528
|
+
// 加入打印全局样式
|
529
|
+
addCommonCss();
|
530
|
+
|
531
|
+
// 增加打印设置的 css
|
532
|
+
const optElem = document.getElementById(printOptionId);
|
533
|
+
if (optElem && optElem.parentNode) {
|
534
|
+
optElem.parentNode.removeChild(optElem);
|
535
|
+
}
|
536
|
+
const optStr = [];
|
537
|
+
// 打印方向设置
|
538
|
+
if (typeof horizontal === 'boolean') {
|
539
|
+
optStr.push(`size: ${horizontal ? 'landscape' : 'portrait'};`);
|
540
|
+
}
|
541
|
+
// 页间距设置
|
542
|
+
if (margin != null) {
|
543
|
+
optStr.push(`margin: ${margin};`);
|
544
|
+
}
|
545
|
+
if (optStr) {
|
546
|
+
const elem = document.createElement('style');
|
547
|
+
elem.id = printOptionId;
|
548
|
+
elem.setAttribute('type', 'text/css');
|
549
|
+
elem.setAttribute('media', 'print');
|
550
|
+
elem.innerHTML = `@page { ${optStr.join('')} }`;
|
551
|
+
document.body.appendChild(elem);
|
552
|
+
}
|
553
|
+
|
554
|
+
// 隐藏打印时需要隐藏的内容
|
555
|
+
hideElem(hide, isHideNone);
|
556
|
+
|
557
|
+
// 设置窗口标题
|
558
|
+
const oldTitle = document.title;
|
559
|
+
if (title) {
|
560
|
+
document.title = title;
|
561
|
+
}
|
562
|
+
|
563
|
+
let pWin;
|
564
|
+
if (!blank) {
|
565
|
+
// 当前窗口打印
|
566
|
+
pWin = window;
|
567
|
+
if (iePreview !== false && isIE()) {
|
568
|
+
if (!document.getElementById('WebBrowser')) {
|
569
|
+
const elem = document.createElement('object');
|
570
|
+
elem.id = 'WebBrowser';
|
571
|
+
elem.setAttribute(
|
572
|
+
'classid',
|
573
|
+
'clsid:8856F961-340A-11D0-A96B-00C04FD705A2'
|
574
|
+
);
|
575
|
+
elem.style.display = 'none';
|
576
|
+
document.body.appendChild(elem);
|
577
|
+
}
|
578
|
+
try {
|
579
|
+
window['WebBrowser'].ExecWB(7, 1);
|
580
|
+
} catch (e) {
|
581
|
+
pWin.print();
|
582
|
+
}
|
583
|
+
} else {
|
584
|
+
pWin.print();
|
585
|
+
}
|
586
|
+
} else {
|
587
|
+
// 新窗口打印
|
588
|
+
pWin = window.open('', '_blank');
|
589
|
+
if (pWin) {
|
590
|
+
pWin.focus();
|
591
|
+
// 写入内容到打印窗口
|
592
|
+
const pDoc = pWin.document;
|
593
|
+
if (pDoc) {
|
594
|
+
pDoc.open();
|
595
|
+
let html =
|
596
|
+
'<!DOCTYPE html>' +
|
597
|
+
document.getElementsByTagName('html')[0]?.outerHTML;
|
598
|
+
// 去除js
|
599
|
+
html = html
|
600
|
+
.replace(/<script/g, '<div style="display:none;" ')
|
601
|
+
.replace(/<\/script>/g, '</div>');
|
602
|
+
|
603
|
+
const addHtml = function (str: string) {
|
604
|
+
html = html.replace(/<\/html>/, `${str}</html>`);
|
605
|
+
};
|
606
|
+
|
607
|
+
if (iePreview !== false && isIE()) {
|
608
|
+
if (!document.getElementById('WebBrowser')) {
|
609
|
+
addHtml(ieWebBrowser);
|
610
|
+
}
|
611
|
+
addHtml(`
|
612
|
+
<script>
|
613
|
+
window.onload = function() {
|
614
|
+
try {
|
615
|
+
window.WebBrowser.ExecWB(7,1);
|
616
|
+
} catch(e) {
|
617
|
+
console.error(e);
|
618
|
+
window.print();
|
619
|
+
}
|
620
|
+
${close !== false ? 'window.close();' : ''}
|
621
|
+
}
|
622
|
+
</script>
|
623
|
+
`);
|
624
|
+
} else {
|
625
|
+
addHtml(`
|
626
|
+
<script>
|
627
|
+
window.onload = function() {
|
628
|
+
window.print();
|
629
|
+
${close !== false ? 'window.close();' : ''}
|
630
|
+
}
|
631
|
+
</script>
|
632
|
+
`);
|
633
|
+
}
|
634
|
+
|
635
|
+
pDoc.write(html);
|
636
|
+
pDoc.close();
|
637
|
+
}
|
638
|
+
}
|
639
|
+
}
|
640
|
+
|
641
|
+
// 恢复窗口标题
|
642
|
+
if (title) {
|
643
|
+
document.title = oldTitle;
|
644
|
+
}
|
645
|
+
|
646
|
+
// 恢复隐藏的内容
|
647
|
+
showElem(hide);
|
648
|
+
|
649
|
+
return pWin;
|
650
|
+
}
|
651
|
+
|
652
|
+
/**
|
653
|
+
* 打印任意内容
|
654
|
+
* @param option PrintHtmlOption
|
655
|
+
* @param 参数说明,都是可选参数,此外还支持 printThis 的所有参数
|
656
|
+
* @param html 要打印内容 String
|
657
|
+
* @param print 是否立即打印 Boolean
|
658
|
+
* @param loading 是否显示加载层 Boolean
|
659
|
+
* @param header 页眉 String
|
660
|
+
* @param footer 页脚 String
|
661
|
+
* @param before Function 打印开始的回调
|
662
|
+
* @param done Function 打印完成的回调
|
663
|
+
* @param style String 打印的自定义样式
|
664
|
+
*/
|
665
|
+
export function printHtml(option: PrintHtmlOptionsExtends) {
|
666
|
+
if (option.loading !== false && option.blank !== true) {
|
667
|
+
showPrintLoading();
|
668
|
+
}
|
669
|
+
|
670
|
+
// 创建打印窗口
|
671
|
+
let pWin, pDoc;
|
672
|
+
if (option.blank || (option.iePreview !== false && isIE())) {
|
673
|
+
// 新窗口打印
|
674
|
+
pWin = window.open('', '_blank');
|
675
|
+
pDoc = pWin?.document;
|
676
|
+
} else {
|
677
|
+
// 当前窗口打印
|
678
|
+
const pFrame = getPrintFrame();
|
679
|
+
pWin = pFrame.contentWindow;
|
680
|
+
pDoc = pFrame.contentDocument || pWin?.document;
|
681
|
+
}
|
682
|
+
|
683
|
+
if (pWin) {
|
684
|
+
// 让打印窗口获取焦点
|
685
|
+
pWin.focus();
|
686
|
+
// 写入内容到打印窗口
|
687
|
+
if (pDoc && option.html) {
|
688
|
+
pDoc.open();
|
689
|
+
pDoc.write(`
|
690
|
+
<!DOCTYPE html>
|
691
|
+
<head>
|
692
|
+
<meta charset="UTF-8"/>
|
693
|
+
<title>${option.title ?? ''}</title>
|
694
|
+
<style>
|
695
|
+
${getCommonCss(true)}
|
696
|
+
</style>
|
697
|
+
${option.style ?? ''}
|
698
|
+
</head>
|
699
|
+
<html>
|
700
|
+
<body>
|
701
|
+
${addHeaderFooter(option.html, option.header, option.footer)}
|
702
|
+
${getOptionHtml(option)}
|
703
|
+
</body>
|
704
|
+
</html>
|
705
|
+
`);
|
706
|
+
pDoc.close();
|
707
|
+
}
|
708
|
+
}
|
709
|
+
return pWin;
|
710
|
+
}
|
711
|
+
|
712
|
+
/**
|
713
|
+
* 分页打印
|
714
|
+
* @param option PrintPageOption
|
715
|
+
*/
|
716
|
+
export function printPage(option: PrintPageOptionsExtends) {
|
717
|
+
if (option.loading !== false && option.blank !== true) {
|
718
|
+
showPrintLoading();
|
719
|
+
}
|
720
|
+
|
721
|
+
// 创建打印窗口
|
722
|
+
let pWin, pDoc;
|
723
|
+
if (option.blank || (option.iePreview !== false && isIE())) {
|
724
|
+
// 新窗口打印
|
725
|
+
pWin = window.open('', '_blank');
|
726
|
+
pDoc = pWin?.document;
|
727
|
+
} else {
|
728
|
+
// 当前窗口打印
|
729
|
+
const pFrame = getPrintFrame();
|
730
|
+
pWin = pFrame.contentWindow;
|
731
|
+
pDoc = pFrame.contentDocument || pWin?.document;
|
732
|
+
}
|
733
|
+
|
734
|
+
if (pWin && pDoc) {
|
735
|
+
// 让打印窗口获取焦点
|
736
|
+
pWin.focus();
|
737
|
+
// 写入内容到打印窗口
|
738
|
+
const content =
|
739
|
+
(option.pages ?? option.htmls)
|
740
|
+
?.map((h) => `<div class="ele-printer-page-item">${h}</div>`)
|
741
|
+
.join('') ?? '';
|
742
|
+
const pageClass =
|
743
|
+
'ele-printer-page' + (option.isDebug ? ' ele-printer-debug' : '');
|
744
|
+
const contentHtml = `<div class="${pageClass}">${content}</div>`;
|
745
|
+
pDoc.open();
|
746
|
+
pDoc.write(`
|
747
|
+
<!DOCTYPE html>
|
748
|
+
<html>
|
749
|
+
<head>
|
750
|
+
<meta charset="UTF-8"/>
|
751
|
+
<title>${option.title ?? ''}</title>
|
752
|
+
${getPageStyleHtml(option.padding, option.width, option.height)}
|
753
|
+
${option.style ?? ''}
|
754
|
+
</head>
|
755
|
+
<body>
|
756
|
+
${addHeaderFooter(contentHtml, option.header, option.footer)}
|
757
|
+
${getOptionHtml(option)}
|
758
|
+
</body>
|
759
|
+
</html>
|
760
|
+
`);
|
761
|
+
pDoc.close();
|
762
|
+
}
|
763
|
+
return pWin;
|
764
|
+
}
|
765
|
+
|
766
|
+
/**
|
767
|
+
* 打印 pdf
|
768
|
+
* @param option PrintPdfOption
|
769
|
+
*/
|
770
|
+
export function printPdf(option: any) {
|
771
|
+
if (option.loading !== false) {
|
772
|
+
showPrintLoading();
|
773
|
+
}
|
774
|
+
const pFrame = getPrintFrame();
|
775
|
+
const pWin = pFrame.contentWindow;
|
776
|
+
pFrame.onload = () => {
|
777
|
+
if (!pFrame.getAttribute('src')) {
|
778
|
+
return;
|
779
|
+
}
|
780
|
+
pFrame.focus();
|
781
|
+
option.before && option.before();
|
782
|
+
pWin?.print();
|
783
|
+
hidePrintLoading();
|
784
|
+
option.done && option.done();
|
785
|
+
};
|
786
|
+
|
787
|
+
// 开始打印
|
788
|
+
function doPrint(arraybuffer: BlobPart) {
|
789
|
+
const localPdf = new window.Blob([arraybuffer], {
|
790
|
+
type: 'application/pdf'
|
791
|
+
});
|
792
|
+
// 兼容 IE
|
793
|
+
if (window.navigator && window.navigator['msSaveOrOpenBlob']) {
|
794
|
+
window.navigator['msSaveOrOpenBlob'](localPdf, 'print.pdf');
|
795
|
+
hidePrintLoading();
|
796
|
+
} else {
|
797
|
+
pFrame.setAttribute('src', window.URL.createObjectURL(localPdf));
|
798
|
+
}
|
799
|
+
}
|
800
|
+
|
801
|
+
// 请求 pdf 数据
|
802
|
+
if (option.arraybuffer) {
|
803
|
+
doPrint(option.arraybuffer);
|
804
|
+
} else if (option.url) {
|
805
|
+
const req = new window.XMLHttpRequest();
|
806
|
+
req.open('GET', option.url, true);
|
807
|
+
req.responseType = 'arraybuffer';
|
808
|
+
req.onload = () => {
|
809
|
+
if ([200, 201].indexOf(req.status) === -1) {
|
810
|
+
return option.error && option.error(req.status, req.statusText);
|
811
|
+
}
|
812
|
+
doPrint(req.response);
|
813
|
+
};
|
814
|
+
req.send();
|
815
|
+
}
|
816
|
+
return pWin;
|
817
|
+
}
|
818
|
+
|
819
|
+
/**
|
820
|
+
* 生成表格 html
|
821
|
+
* @param data 数据
|
822
|
+
* @param cols 列配置
|
823
|
+
* @param thead 是否需要表头
|
824
|
+
*/
|
825
|
+
export function makeTable(data: Array<any>, cols: makeTableCols, thead = true) {
|
826
|
+
// 恢复 cols 参数初始状态
|
827
|
+
cols.forEach((col: any[]) => {
|
828
|
+
col.forEach((c) => {
|
829
|
+
c.INIT_OK = void 0;
|
830
|
+
c.key = void 0;
|
831
|
+
c.colGroup = void 0;
|
832
|
+
c.HAS_PARENT = void 0;
|
833
|
+
c.parentKey = void 0;
|
834
|
+
c.PARENT_COL_INDEX = void 0;
|
835
|
+
});
|
836
|
+
});
|
837
|
+
|
838
|
+
// cols 转为嵌套结构
|
839
|
+
const colArrays: any[] = [];
|
840
|
+
let colIndex = 0;
|
841
|
+
for (let i1 = 0; i1 < cols.length; i1++) {
|
842
|
+
const item1 = cols[i1];
|
843
|
+
for (let i2 = 0; i2 < item1.length; i2++) {
|
844
|
+
const item2 = item1[i2];
|
845
|
+
if (!item2) {
|
846
|
+
item1.splice(i2, 1);
|
847
|
+
continue;
|
848
|
+
}
|
849
|
+
// 合并单元格处理
|
850
|
+
item2.key = i1 + '-' + i2;
|
851
|
+
let CHILD_COLS = null;
|
852
|
+
if (item2.colGroup || (item2.colspan && item2.colspan > 1)) {
|
853
|
+
item2.colGroup = true;
|
854
|
+
CHILD_COLS = [];
|
855
|
+
colIndex++;
|
856
|
+
let childIndex = 0;
|
857
|
+
for (let i22 = 0; i22 < cols[i1 + 1].length; i22++) {
|
858
|
+
const item22 = { ...cols[i1 + 1][i22] };
|
859
|
+
if (
|
860
|
+
item22.HAS_PARENT ||
|
861
|
+
(childIndex > 1 && childIndex == item2.colspan)
|
862
|
+
) {
|
863
|
+
cols[i1 + 1][i22] = item22;
|
864
|
+
continue;
|
865
|
+
}
|
866
|
+
item22.HAS_PARENT = true;
|
867
|
+
item22.parentKey = i1 + '-' + i2;
|
868
|
+
item22.key = i1 + 1 + '-' + i22;
|
869
|
+
item22.PARENT_COL_INDEX = colIndex;
|
870
|
+
CHILD_COLS.push(item22);
|
871
|
+
childIndex =
|
872
|
+
childIndex +
|
873
|
+
Number(item22.colspan && item22.colspan > 1 ? item22.colspan : 1);
|
874
|
+
cols[i1 + 1][i22] = item22;
|
875
|
+
}
|
876
|
+
}
|
877
|
+
item2.CHILD_COLS = CHILD_COLS;
|
878
|
+
if (!item2.PARENT_COL_INDEX) {
|
879
|
+
colArrays.push(item2);
|
880
|
+
}
|
881
|
+
cols[i1][i2] = item2;
|
882
|
+
}
|
883
|
+
}
|
884
|
+
|
885
|
+
// 遍历嵌套结构 cols 的方法
|
886
|
+
const eachCols = function (callback: Function, arr: Array<any>) {
|
887
|
+
if (!arr) {
|
888
|
+
arr = colArrays;
|
889
|
+
}
|
890
|
+
for (let i = 0; i < arr.length; i++) {
|
891
|
+
const item = arr[i];
|
892
|
+
callback && callback(i, item);
|
893
|
+
if (item.CHILD_COLS) {
|
894
|
+
eachCols(callback, item.CHILD_COLS);
|
895
|
+
}
|
896
|
+
}
|
897
|
+
};
|
898
|
+
|
899
|
+
// 计算表格宽度
|
900
|
+
let maxWidth = 1;
|
901
|
+
let needSetWidth = true;
|
902
|
+
const colgroupHtml = [] as any;
|
903
|
+
eachCols((_i: any, c: any) => {
|
904
|
+
if (!c.colGroup) {
|
905
|
+
colgroupHtml.push('<col');
|
906
|
+
if (c.width) {
|
907
|
+
colgroupHtml.push(` width="${c.width}"`);
|
908
|
+
}
|
909
|
+
colgroupHtml.push('/>');
|
910
|
+
if (c.width && !/\d+%$/.test(String(c.width))) {
|
911
|
+
maxWidth += c.width + 1;
|
912
|
+
} else {
|
913
|
+
needSetWidth = false;
|
914
|
+
}
|
915
|
+
}
|
916
|
+
});
|
917
|
+
|
918
|
+
// 表头
|
919
|
+
const thHtml = cols
|
920
|
+
.map((cs) => {
|
921
|
+
const th = cs
|
922
|
+
.map((c) => {
|
923
|
+
return `<th
|
924
|
+
colspan="${c.colspan || 1}"
|
925
|
+
rowspan="${c.rowspan || 1}"
|
926
|
+
align="${c.thAlign || c.align || 'left'}"
|
927
|
+
style="${c.thStyle}">${c.title || ''}
|
928
|
+
</th>`;
|
929
|
+
})
|
930
|
+
.join('');
|
931
|
+
return '<tr>' + th + '</tr>';
|
932
|
+
})
|
933
|
+
.join('');
|
934
|
+
const headHtml = '<thead>' + thHtml + '</thead>';
|
935
|
+
|
936
|
+
// 主体
|
937
|
+
const trHtml = data
|
938
|
+
.map((d: any, index: any) => {
|
939
|
+
const tr = ['<tr>'];
|
940
|
+
let colIndex = 0;
|
941
|
+
eachCols((_i: any, c: any) => {
|
942
|
+
if (!c.colGroup) {
|
943
|
+
const value = c.field ? d[c.field] : '';
|
944
|
+
const content = c.templet ? c.templet(d, index, colIndex) : value;
|
945
|
+
const align = c.align || 'left';
|
946
|
+
tr.push(`<td align="${align}" style="${c.style}">${content}</td>`);
|
947
|
+
colIndex++;
|
948
|
+
}
|
949
|
+
});
|
950
|
+
tr.push('</tr>');
|
951
|
+
return tr.join('');
|
952
|
+
})
|
953
|
+
.join('');
|
954
|
+
const bodyHtml = '<tbody>' + trHtml + '</tbody>';
|
955
|
+
|
956
|
+
return `<table
|
957
|
+
style="width: ${needSetWidth ? maxWidth + 'px' : '100%'};"
|
958
|
+
class="y-printer-table">
|
959
|
+
<colgroup>${colgroupHtml.join('')}</colgroup>
|
960
|
+
${thead ? headHtml : ''} ${bodyHtml}
|
961
|
+
</table>`;
|
962
|
+
}
|
963
|
+
|
964
|
+
/**
|
965
|
+
* 打印指定区域
|
966
|
+
* @param elem HTMLElement
|
967
|
+
* @param option 参数配置 支持 printThis 所有参数
|
968
|
+
*/
|
969
|
+
export function printElement(elem: HTMLElement, option: PrintThisOptions) {
|
970
|
+
if (!elem) {
|
971
|
+
return null;
|
972
|
+
}
|
973
|
+
const bodyChilds = Array.prototype.filter.call(
|
974
|
+
document.body.children,
|
975
|
+
(el) => {
|
976
|
+
if (
|
977
|
+
typeof el?.tagName === 'string' &&
|
978
|
+
['style', 'script', 'link'].includes(el.tagName.toLowerCase())
|
979
|
+
) {
|
980
|
+
return false;
|
981
|
+
}
|
982
|
+
return true;
|
983
|
+
}
|
984
|
+
);
|
985
|
+
hideElem(bodyChilds, true);
|
986
|
+
const parntEl = elem.parentNode;
|
987
|
+
const nextEl = elem.nextElementSibling;
|
988
|
+
document.body.appendChild(elem);
|
989
|
+
const pWin = printThis(option);
|
990
|
+
if (nextEl) {
|
991
|
+
parntEl?.insertBefore(elem, nextEl);
|
992
|
+
} else {
|
993
|
+
parntEl?.appendChild(elem);
|
994
|
+
}
|
995
|
+
showElem(bodyChilds);
|
996
|
+
return pWin;
|
997
|
+
}
|