UNPKG

vue-print-nb-jeecg

Version:

This is a directive wrapper for printed, Simple, fast, convenient, light. ( 特定改造版本: 解决IE兼容问题和支持Canvas自适应打印 )

223 lines (207 loc) 8.12 kB
export default class { constructor(option) { this.standards = { strict: 'strict', loose: 'loose', html5: 'html5' }; this.counter = 0; this.settings = { standard: this.standards.html5, extraHead: '', // 附加在head标签上的额外元素,使用逗号分隔 extraCss: '', // 额外的css逗号分隔 popTitle: '', // 标题 endCallback: null, // 成功打开后的回调函数 el: '' // 局部打印的id }; Object.assign(this.settings, option); this.init(); }; init() { this.counter++; this.settings.id = `printArea_${this.counter}`; let box = document.getElementById(this.settings.id); if (box) { box.parentNode.removeChild(box); } let PrintAreaWindow = this.getPrintWindow(); // 创建iframe this.write(PrintAreaWindow.doc); // 写入内容 //this.print(PrintAreaWindow); this.settings.endCallback(); }; print(PAWindow) { let paWindow = PAWindow; console.log('---调用打印 focus-----'); paWindow.focus(); paWindow.print(); console.log('---调用打印 print-----'); }; write(PADocument, $ele) { PADocument.open(); PADocument.write(`${this.docType()}<html>${this.getHead()}${this.getBody()}</html>`); PADocument.close(); }; docType() { if (this.settings.standard === this.standards.html5) { return '<!DOCTYPE html>'; } var transitional = this.settings.standard === this.standards.loose ? ' Transitional' : ''; var dtd = this.settings.standard === this.standards.loose ? 'loose' : 'strict'; return `<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01${transitional}//EN" "http://www.w3.org/TR/html4/${dtd}.dtd">`; }; getHead() { let extraHead = ''; let links = ''; let style = ''; if (this.settings.extraHead) { this.settings.extraHead.replace(/([^,]+)/g, function(m) { extraHead += m; }); } [].forEach.call(document.querySelectorAll('link'), function (item, i) { if (item.href.indexOf('.css') >= 0) { links += '<link type="text/css" rel="stylesheet" href="' + item.href + '" >'; } }); for (let i = 0 ; i < document.styleSheets.length; i++) { if (document.styleSheets[i].cssRules || document.styleSheets[i].rules) { let rules = document.styleSheets[i].cssRules || document.styleSheets[i].rules; for (let b = 0 ; b < rules.length; b++) { try { style += rules[b].cssText; } catch (err) {} } } } if (this.settings.extraCss) { this.settings.extraCss.replace(/([^,\s]+)/g, function(m) { links += `<link type="text/css" rel="stylesheet" href="${m}">`; }); } return `<head><title>${this.settings.popTitle}</title>${extraHead}${links}<style type="text/css">${style}</style></head>`; }; getBody() { let ele = this.getFormData(document.querySelector(this.settings.el)); let htm = ele.outerHTML; console.log('htm', htm); return '<body>' + htm + '</body>'; }; // 处理form表单的默认状态 getFormData(ele) { let that = this let copy = ele.cloneNode(true); //update-begin--Author:sunjianlei Date:20190510 for:支持忽略打印的标签---------------------- let allElements = copy.querySelectorAll('*'); [].forEach.call(allElements, function (item) { let attr = item.getAttribute('ignore-print'); attr = (attr == null ? item.getAttribute('ignoreprint') : attr); if (attr != null && attr.toString() === 'true') { item.outerHTML = '' } }); //update-end--Author:sunjianlei Date:20190510 for:支持忽略打印的标签---------------------- let copiedInputs = copy.querySelectorAll('input,select,textarea'); [].forEach.call(copiedInputs, function (item, i) { let typeInput = item.getAttribute('type'); let copiedInput = copiedInputs[i]; // update-begin--Author:sunjianlei Date:20191101 for:优化赋值逻辑方式 ---------------------- if (typeInput == null) { typeInput = item.tagName === 'SELECT' ? 'select' : item.tagName === 'TEXTAREA' ? 'textarea' : ''; } if (typeInput === 'radio' || typeInput === 'checkbox') { item.checked && copiedInput.setAttribute('checked', item.checked); } else if (typeInput === 'select') { [].forEach.call(copiedInput.querySelectorAll('option'), function (op, b) { if (op.selected) { op.setAttribute('selected', true); } }); } else if (typeInput === 'textarea') { // update-begin--Author:sunjianlei Date:20220302 for:修复textarea换行会出现<br>的问题 ---------------------- copiedInput.innerHTML = item.value // update-end----Author:sunjianlei Date:20220302 for:修复textarea换行会出现<br>的问题 ---------------------- } else { copiedInput.value = item.value; copiedInput.setAttribute('value', item.value); } //update-end--Author:sunjianlei Date:20191101 for:优化赋值逻辑方式 ---------------------- }); //update-begin--Author:jianlei Date:20190507 for:支持Canvas打印-------------------- var sourceCanvas = ele.querySelectorAll('canvas'); var copyCanvas = copy.querySelectorAll('canvas'); [].forEach.call(copyCanvas, function (item, i) { // update-begin--author:sunjianlei date:20220407 for:echarts canvas宽度自适应 --------- if (that.isECharts(item)) { if (item.parentElement.style.width) { item.parentElement.style.width = '100%' item.parentElement.style.height = 'auto' } if (item.parentElement.parentElement.style.width) { item.parentElement.parentElement.style.width = '100%' item.parentElement.parentElement.style.height = 'auto' } } // update-end--author:sunjianlei date:20220407 for:echarts canvas宽度自适应 --------- var url = sourceCanvas[i].toDataURL() //update-begin--Author:sunjianlei Date:20190510 for:canvas宽度自适应---------------------- item.outerHTML = '<img src="' + url + '" style="width:100%;"/>' //update-end--Author:sunjianlei Date:20190510 for:canvas宽度自适应---------------------- }); //update-end--Author:jianlei Date:20190507 for:支持Canvas打印---------------------- return copy; }; /** * 判断是否是 ECharts 的 Canvas * * @param item canvas * @time 2022-4-7 * @author sunjianlei */ isECharts(item) { let attrName = '_echarts_instance_' let parent = item.parentElement if (parent.getAttribute(attrName) != null) { return true } if (parent.parentElement) { return parent.parentElement.getAttribute(attrName) != null } return false }; getPrintWindow() { var f = this.Iframe(); return { win: f.contentWindow || f, doc: f.doc }; }; Iframe() { let frameId = this.settings.id; let iframe; var that = this; try { iframe = document.createElement('iframe'); document.body.appendChild(iframe); iframe.style.border = '0px'; iframe.style.position = 'absolute'; iframe.style.width = '0px'; iframe.style.height = '0px'; iframe.style.right = '0px'; iframe.style.top = '0px'; iframe.setAttribute('id', frameId); iframe.setAttribute('src', new Date().getTime()); iframe.doc = null; iframe.onload = function () { var win = iframe.contentWindow || iframe; that.print(win); } iframe.doc = iframe.contentDocument ? iframe.contentDocument : (iframe.contentWindow ? iframe.contentWindow.document : iframe.document); } catch (e) { throw new Error(e + '. iframes may not be supported in this browser.'); } if (iframe.doc == null) { throw new Error('Cannot find document.'); } return iframe; }; };