vxe-pc-ui
Version:
A vue based PC component library
241 lines (240 loc) • 13 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.assemblePageBreak = assemblePageBreak;
exports.createPrintFrame = createPrintFrame;
exports.destroyPageBreak = destroyPageBreak;
exports.printHtml = void 0;
exports.trimHtml = trimHtml;
var _xeUtils = _interopRequireDefault(require("xe-utils"));
var _dom = require("../../ui/src/dom");
var _log = require("../../ui/src/log");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
const browseObj = _xeUtils.default.browse();
// 打印
let printFrame;
// 默认导出或打印的 HTML 样式
const defaultHtmlStyle = 'body{padding:0;font-family:"Microsoft YaHei",微软雅黑,"MicrosoftJhengHei",华文细黑,STHeiti,MingLiu}body *{-webkit-box-sizing:border-box;box-sizing:border-box}.vxe-table{border-collapse:collapse;text-align:left;border-spacing:0}.vxe-table:not(.is--print){table-layout:fixed}.vxe-table,.vxe-table th,.vxe-table td,.vxe-table td{border-color:#D0D0D0;border-style:solid;border-width:0}.vxe-table.is--print{width:100%}.border--default,.border--full,.border--outer{border-top-width:1px}.border--default,.border--full,.border--outer{border-left-width:1px}.border--outer,.border--default th,.border--default td,.border--full th,.border--full td,.border--outer th,.border--inner th,.border--inner td{border-bottom-width:1px}.border--default,.border--outer,.border--full th,.border--full td{border-right-width:1px}.border--default th,.border--full th,.border--outer th{background-color:#f8f8f9}.vxe-table td>div,.vxe-table th>div{padding:.5em .4em}.col--center{text-align:center}.col--right{text-align:right}.vxe-table:not(.is--print) .col--ellipsis>div{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;word-break:break-all}.vxe-table--tree-node{text-align:left}.vxe-table--tree-node-wrapper{position:relative}.vxe-table--tree-icon-wrapper{position:absolute;top:50%;width:1em;height:1em;text-align:center;-webkit-transform:translateY(-50%);transform:translateY(-50%);-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:pointer}.vxe-table--tree-unfold-icon,.vxe-table--tree-fold-icon{position:absolute;width:0;height:0;border-style:solid;border-width:.5em;border-right-color:transparent;border-bottom-color:transparent}.vxe-table--tree-unfold-icon{left:.3em;top:0;border-left-color:#939599;border-top-color:transparent}.vxe-table--tree-fold-icon{left:0;top:.3em;border-left-color:transparent;border-top-color:#939599}.vxe-table--tree-cell{display:block;padding-left:1.5em}.vxe-table input[type="checkbox"]{margin:0}.vxe-table input[type="checkbox"],.vxe-table input[type="radio"],.vxe-table input[type="checkbox"]+span,.vxe-table input[type="radio"]+span{vertical-align:middle;padding-left:0.4em}';
function trimHtml(html) {
return `${html}`.replace(/(<!---->)/, '');
}
function createPrintFrame() {
const frame = document.createElement('iframe');
frame.className = 'vxe-table--print-frame';
return frame;
}
function appendPrintFrame() {
if (!printFrame.parentNode) {
document.body.appendChild(printFrame);
}
}
function afterPrintEvent() {
requestAnimationFrame(removeFrame);
}
function removeFrame() {
if (printFrame) {
if (printFrame.parentNode) {
try {
printFrame.contentDocument.write('');
} catch (e) {}
printFrame.parentNode.removeChild(printFrame);
}
printFrame = null;
}
}
function getExportBlobByString(str, type) {
return new Blob([str], {
type: `text/${type};charset=utf-8;`
});
}
const defaultPrintMargin = 50;
const defaultFontColor = '#000000';
function parsePageStyle(val) {
const styOpts = Object.assign({}, val);
const headStyOpts = Object.assign({}, styOpts.header);
const titStyOpts = Object.assign({}, styOpts.title);
const footStyOpts = Object.assign({}, styOpts.footer);
const pnStyOpts = Object.assign({}, styOpts.pageNumber);
let mVal = defaultPrintMargin;
let marginTop = mVal;
let marginBottom = mVal;
let marginLeft = mVal;
let marginRight = mVal;
if (_xeUtils.default.isNumber(styOpts.margin) || _xeUtils.default.isString(styOpts.margin)) {
mVal = styOpts.margin;
marginTop = mVal;
marginBottom = mVal;
marginLeft = mVal;
marginRight = mVal;
}
return {
marginTop: (0, _dom.toCssUnit)(styOpts.marginTop || marginTop),
marginBottom: (0, _dom.toCssUnit)(styOpts.marginBottom || marginBottom),
marginLeft: (0, _dom.toCssUnit)(styOpts.marginLeft || marginLeft),
marginRight: (0, _dom.toCssUnit)(styOpts.marginRight || marginRight),
fontSize: (0, _dom.toCssUnit)(styOpts.fontSize),
color: styOpts.color,
textAlign: styOpts.textAlign,
header: {
height: (0, _dom.toCssUnit)(headStyOpts.height),
textAlign: headStyOpts.textAlign
},
title: {
color: titStyOpts.color,
fontSize: (0, _dom.toCssUnit)(titStyOpts.fontSize),
textAlign: titStyOpts.textAlign
},
footer: {
height: (0, _dom.toCssUnit)(footStyOpts.height),
textAlign: footStyOpts.textAlign
},
pageNumber: {
color: pnStyOpts.color,
fontSize: (0, _dom.toCssUnit)(pnStyOpts.fontSize),
textAlign: pnStyOpts.textAlign
}
};
}
function createCssLink(urls) {
if (urls) {
return urls.map(url => `<link rel="stylesheet" href="${url}">`).join('\n');
}
return '';
}
function createHtmlPage(opts, printHtml) {
const {
pageStyle,
customStyle,
styleUrls
} = opts;
const pageStyObj = parsePageStyle(pageStyle);
const headStyOpts = pageStyObj.header;
const titStyOpts = pageStyObj.title;
const footStyOpts = pageStyObj.header;
const pnStyOpts = pageStyObj.pageNumber;
const isPbMode = opts._pageBreaks || opts.pageBreaks && opts.pageBreaks.length;
return ['<!DOCTYPE html><html>', '<head>', '<meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no,minimal-ui">', `<title>${opts.title || ''}</title>`, createCssLink(styleUrls), `<style media="print">@page{size:auto;${isPbMode ? 'margin: 0mm;' : ''}}</style>`, `<style>body{font-size:${pageStyObj.fontSize || '14px'};color:${pageStyObj.color || defaultFontColor};text-align:${pageStyObj.textAlign || 'left'};}</style>`, '<style>', '.vxe-print-slots{display:none;}', '.vxe-print-page-break.align--center{text-align:center;}', '.vxe-print-page-break.align--left{text-align:left;}', '.vxe-print-page-break.align--right{text-align:right;}', '.vxe-print-page-break{break-before:always;page-break-before:always;display:flex;flex-direction:column;height:100vh;overflow:hidden;}', '.vxe-print-page-break--body{display:flex;flex-direction:row;flex-grow:1;overflow:hidden;}', '.vxe-print-page-break--left,.vxe-print-page-break--right{flex-shrink:0;height:100%;}', `.vxe-print-page-break--left{width:${pageStyObj.marginLeft};}`, `.vxe-print-page-break--right{width:${pageStyObj.marginRight};}`, '.vxe-print-page-break--header,.vxe-print-page-break--footer{display:flex;justify-content:center;flex-direction:column;flex-shrink:0;width:100%;}', `.vxe-print-page-break--header{height:${headStyOpts.height || pageStyObj.marginTop};padding:0 ${pageStyObj.marginLeft} 0 ${pageStyObj.marginRight};text-align:${headStyOpts.textAlign || 'left'};}`, `.vxe-print-page-break--header-title{font-size:${titStyOpts.fontSize || '1.6em'};color:${titStyOpts.color || defaultFontColor};text-align:${opts.headerAlign || pnStyOpts.textAlign || 'center'};}`, `.vxe-print-page-break--footer{height:${footStyOpts.height || pageStyObj.marginBottom};padding:0 ${pageStyObj.marginLeft} 0 ${pageStyObj.marginRight};text-align:${footStyOpts.textAlign || 'left'};}`, '.vxe-print-page-break--content{flex-grow:1;overflow:hidden;}', `.vxe-print-page-break--footer-page-number{font-size:${pnStyOpts.fontSize || '1.2em'};color:${pnStyOpts.color || defaultFontColor};text-align:${opts.footerAlign || pnStyOpts.textAlign || 'center'};}`, '</style>', '<style>.vxe-table{white-space:pre;}</style>', `<style>${defaultHtmlStyle}</style>`, isPbMode ? '<style>body{margin:0;}</style>' : '', customStyle ? `<style>${customStyle}</style>` : '', '</head>', '<body>', `${printHtml}`, '</body>', '</html>'].join('');
}
function handlePrint(opts, printHtml = '') {
const {
beforeMethod,
styleUrls
} = opts;
if (styleUrls && styleUrls.length) {
styleUrls.forEach(url => {
if (!/.css$/.test(url)) {
(0, _log.warnLog)('vxe.error.errProp', [url, `${url}.css`]);
}
});
}
if (beforeMethod) {
printHtml = beforeMethod({
content: printHtml,
html: printHtml,
options: opts
}) || '';
}
printHtml = createHtmlPage(opts, printHtml);
const blob = getExportBlobByString(printHtml, 'html');
return new Promise(resolve => {
if (browseObj.msie) {
removeFrame();
printFrame = createPrintFrame();
appendPrintFrame();
const contentDocument = printFrame.contentDocument;
if (contentDocument) {
contentDocument.write(printHtml);
contentDocument.execCommand('print');
}
setTimeout(() => {
resolve({
status: true
});
}, 300);
} else {
if (!printFrame) {
printFrame = createPrintFrame();
printFrame.onload = evnt => {
const frameEl = evnt.target;
if (frameEl.src) {
try {
const contentWindow = frameEl.contentWindow;
if (contentWindow) {
contentWindow.onafterprint = afterPrintEvent;
contentWindow.print();
}
} catch (e) {}
}
resolve({
status: true
});
};
printFrame.onerror = () => {
resolve({
status: false
});
};
}
appendPrintFrame();
printFrame.src = URL.createObjectURL(blob);
}
});
}
function createPageBreak(opts) {
const {
title,
showPageNumber,
align,
headerAlign,
footerAlign,
showAllPageTitle
} = opts;
const pageBreaks = opts.pageBreaks || [];
const pageCount = pageBreaks.length;
return pageBreaks.map((item, index) => {
const bodyHtml = item.bodyHtml;
const headerHtml = item.headerHtml || opts.headerHtml;
const footerHtml = item.footerHtml || opts.footerHtml;
const leftHtml = item.leftHtml || opts.leftHtml;
const rightHtml = item.rightHtml || opts.rightHtml;
const currentPage = index + 1;
const params = {
currentPage,
pageCount
};
return [`<div class="${['vxe-print-page-break', align ? `align--${align}` : ''].join(' ')}">`, `<div class="${['vxe-print-page-break--header', headerAlign ? `align--${headerAlign}` : ''].join(' ')}">`, headerHtml ? `${_xeUtils.default.isFunction(headerHtml) ? headerHtml(params) : headerHtml || ''}` : title && (showAllPageTitle || !index) ? `<div class="vxe-print-page-break--header-title">${title || ''}</div>` : '', '</div>', '<div class="vxe-print-page-break--body">', `<div class="vxe-print-page-break--left">${_xeUtils.default.isFunction(leftHtml) ? leftHtml(params) : leftHtml || ''}</div>`, `<div class="vxe-print-page-break--content">${_xeUtils.default.isFunction(bodyHtml) ? bodyHtml(params) : bodyHtml || ''}</div>`, `<div class="vxe-print-page-break--right">${_xeUtils.default.isFunction(rightHtml) ? rightHtml(params) : rightHtml || ''}</div>`, '</div>', `<div class="${['vxe-print-page-break--footer', footerAlign ? `align--${footerAlign}` : ''].join(' ')}">`, footerHtml ? `${_xeUtils.default.isFunction(footerHtml) ? footerHtml(params) : footerHtml || ''}` : showPageNumber ? `<div class="vxe-print-page-break--footer-page-number">${currentPage}/${pageCount}</div>` : '', '</div>', '</div>'].join('');
}).join('');
}
const printHtml = options => {
const opts = Object.assign({
_pageBreaks: false,
customLayout: true
}, options);
if (opts.sheetName) {
opts.title = opts.title || opts.sheetName;
}
if (opts.style) {
opts.customStyle = opts.customStyle || opts.style;
}
if (opts.beforePrintMethod) {
opts.beforeMethod = opts.beforeMethod || opts.beforePrintMethod;
}
if (opts.pageBreaks && opts.pageBreaks.length) {
return handlePrint(opts, createPageBreak(opts));
}
const printHtml = opts.html || opts.content;
return handlePrint(opts, printHtml);
};
exports.printHtml = printHtml;
function assemblePageBreak($xePageBreak, elem, pageBreakConfig) {
const staticPageBreaks = $xePageBreak.reactData.staticPageBreaks;
const parentElem = elem.parentNode;
if (parentElem && staticPageBreaks) {
staticPageBreaks.splice(_xeUtils.default.arrayIndexOf(parentElem.children, elem), 0, pageBreakConfig);
$xePageBreak.reactData.staticPageBreaks = staticPageBreaks.slice(0);
}
}
function destroyPageBreak($xePageBreak, pageBreakConfig) {
$xePageBreak.reactData.staticPageBreaks = $xePageBreak.reactData.staticPageBreaks.filter(item => item.id !== pageBreakConfig.id);
}