vue+typescript项目中无法使用vue-print-nb 打印
问题vue项目改造成对typescript支持的项目后,vue-print-nb打印指令无法使用尝试有没有对应的typescript包,发现没有解决办法node_modules目录下找到vue-print-nb,复制出src/packages目录下的print.js和printarea.js。把他们后缀改成ts,然后内部的类型处理一下。print.tsimport Print from './pr
·
最优雅的方法
感谢评论区大佬netzhouxiang_
提供的方法
declare module 'vue-print-nb';
问题
vue项目改造成对typescript支持的项目后,vue-print-nb打印指令无法使用
尝试有没有对应的typescript包,发现没有
解决办法
node_modules目录下找到vue-print-nb,复制出src/packages目录下的print.js和printarea.js。
把他们后缀改成ts,然后内部的类型处理一下。
print.ts
import Print from './printarea';
import Vue from "vue";
Vue.directive("print", {
inserted: function (el, binding, vnode) {
let vue: any = vnode.context;
let closeBtn = true;
let id = '';
el.addEventListener('click', () => {
vue.$nextTick(() => {
if (typeof binding.value === 'string') {
id = binding.value;
} else if (typeof binding.value === 'object' && !!binding.value.id) {
id = binding.value.id;
let ids = id.replace(new RegExp("#", "g"), '');
let elsdom = document.getElementById(ids);
if (!elsdom) console.log("id in Error"), id = '';
}
// 局部打印
if (id) {
localPrint();
} else {
// 直接全局打印
window.print();
}
});
});
const localPrint = () => {
if (closeBtn) {
closeBtn = false;
new Print({
ids: id, // * 局部打印必传入id
standard: '', // 文档类型,默认是html5,可选 html5,loose,strict
extraHead: binding.value.extraHead, // 附加在head标签上的额外标签,使用逗号分隔
extraCss: binding.value.extraCss, // 额外的css连接,多个逗号分开
popTitle: binding.value.popTitle, // title的标题
endCallback() { // 调用打印之后的回调事件
closeBtn = true;
}
});
}
};
}
});
printarea.ts
export default class {
constructor(option: any) {
let that: any = this;
that.standards = {
strict: 'strict',
loose: 'loose',
html5: 'html5'
};
that.selectArray = []; // 存储select的
that.counter = 0;
that.settings = {
standard: that.standards.html5,
extraHead: '', // 附加在head标签上的额外元素,使用逗号分隔
extraCss: '', // 额外的css逗号分隔
popTitle: '', // 标题
endCallback: null, // 成功打开后的回调函数
ids: '' // 局部打印的id
};
Object.assign(that.settings, option);
that.init();
}
init() {
let that: any = this;
that.counter++;
that.settings.id = `printArea_${that.counter}`;
let PrintAreaWindow = that.getPrintWindow(); // 创建iframe
that.write(PrintAreaWindow.doc); // 写入内容
that.print(PrintAreaWindow);
that.settings.endCallback();
}
print(PAWindow: any) {
let that: any = this;
let paWindow = PAWindow.win;
const _loaded = () => {
paWindow.focus();
paWindow.print();
try {
let box: any = document.getElementById(that.settings.id);
let canvasList: any = that.elsdom.querySelectorAll('.canvasImg')
console.log(that.elsdom)
for (let i = 0; i < canvasList.length; i++) {
let _parent = canvasList[i].parentNode
_parent.removeChild(canvasList[i])
}
box.parentNode.removeChild(box);
} catch (e) {
console.log(e);
}
};
if (window.ActiveXObject) {
paWindow.onload = _loaded();
return false;
}
paWindow.onload = () => {
_loaded();
};
}
write(PADocument: any, $ele: any) {
let that: any = this;
PADocument.open();
PADocument.write(`${that.docType()}<html>${that.getHead()}${that.getBody()}</html>`);
PADocument.close();
}
docType() {
let that: any = this;
if (that.settings.standard === that.standards.html5) {
return '<!DOCTYPE html>';
}
var transitional = that.settings.standard === that.standards.loose ? ' Transitional' : '';
var dtd = that.settings.standard === that.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 that: any = this;
let extraHead = '';
let links = '';
let style = '';
if (that.settings.extraHead) {
that.settings.extraHead.replace(/([^,]+)/g, (m: any) => {
extraHead += m;
});
}
// 复制所有link标签
[].forEach.call(document.querySelectorAll('link'), function (item: any, i) {
if (item.href.indexOf('.css') >= 0) {
links += `<link type="text/css" rel="stylesheet" href="${item.href}" >`;
}
});
// 循环获取style标签的样式
let domStyle = document.styleSheets;
if (domStyle && domStyle.length > 0) {
for (let i = 0; i < domStyle.length; i++) {
try {
if (domStyle[i].cssRules || domStyle[i].rules) {
let rules = domStyle[i].cssRules || domStyle[i].rules;
for (let b = 0; b < rules.length; b++) {
style += rules[b].cssText;
}
}
} catch (e) {
console.log(domStyle[i].href + e);
}
}
}
if (that.settings.extraCss) {
that.settings.extraCss.replace(/([^,\s]+)/g, (m: any) => {
links += `<link type="text/css" rel="stylesheet" href="${m}">`;
});
}
return `<head><title>${that.settings.popTitle}</title>${extraHead}${links}<style type="text/css">${style}</style></head>`;
}
getBody() {
let that: any = this;
let ids = that.settings.ids;
ids = ids.replace(new RegExp("#", "g"), '');
that.elsdom = that.beforeHanler(document.getElementById(ids));
let ele = that.getFormData(that.elsdom);
let htm = ele.outerHTML;
return '<body>' + htm + '</body>';
}
// 克隆节点之前做的操作
beforeHanler(elsdom: any) {
let canvasList = elsdom.querySelectorAll('canvas');
// canvas转换png图片
for (let i = 0; i < canvasList.length; i++) {
if (!canvasList[i].style.display) {
let _parent = canvasList[i].parentNode
let _canvasUrl = canvasList[i].toDataURL('image/png')
let _img = new Image()
_img.className = 'canvasImg'
_img.style.display = 'none'
_img.src = _canvasUrl
// _parent.replaceChild(_img, canvasList[i])
_parent.appendChild(_img)
}
}
return elsdom
}
// 根据type去处理form表单
getFormData(ele: any) {
let copy = ele.cloneNode(true);
let copiedInputs = copy.querySelectorAll('input,select,textarea');
let canvasImgList = copy.querySelectorAll('.canvasImg,canvas');
let selectCount = -1;
// 处理所有canvas
for (let i = 0; i < canvasImgList.length; i++) {
let _parent = canvasImgList[i].parentNode
let item = canvasImgList[i]
// 删除克隆后的canvas节点
if (item.tagName.toLowerCase() === 'canvas') {
_parent.removeChild(item)
} else {
item.style.display = 'block'
}
}
// 处理所有输入框
for (let i = 0; i < copiedInputs.length; i++) {
let item = copiedInputs[i];
let typeInput = item.getAttribute('type');
let copiedInput = copiedInputs[i];
// 获取select标签
if (!typeInput) {
typeInput = item.tagName === 'SELECT' ? 'select' : item.tagName === 'TEXTAREA' ? 'textarea' : '';
}
// 处理input框
if (item.tagName === 'INPUT') {
// 除了单选框 多选框比较特别
if (typeInput === 'radio' || typeInput === 'checkbox') {
copiedInput.setAttribute('checked', item.checked);
//
} else {
copiedInput.value = item.value;
copiedInput.setAttribute('value', item.value);
}
// 处理select
} else if (typeInput === 'select') {
selectCount++;
for (let b = 0; b < ele.querySelectorAll('select').length; b++) {
let select = ele.querySelectorAll('select')[b]; // 获取原始层每一个select
!select.getAttribute('newbs') && select.setAttribute('newbs', b) // 添加标识
if (select.getAttribute('newbs') == selectCount) {
let opSelectedIndex = ele.querySelectorAll('select')[selectCount].selectedIndex;
item.options[opSelectedIndex].setAttribute('selected', true);
}
}
// 处理textarea
} else {
copiedInput.innerHTML = item.value;
copiedInput.setAttribute('html', item.value);
}
}
return copy;
}
getPrintWindow() {
let that: any = this;
var f = that.Iframe();
return {
f: f,
win: f.contentWindow || f,
doc: f.doc
};
}
Iframe() {
let that: any = this;
let frameId = that.settings.id;
let iframe: any;
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.doc = iframe.contentDocument ? iframe.contentDocument : (iframe.contentWindow ? iframe.contentWindow.document : iframe.document);
iframe.onload = function () {
var win = iframe.contentWindow || iframe;
that.print(win);
}
} catch (e) {
throw new Error(e + '. iframes may not be supported in that browser.');
}
if (iframe.doc == null) {
throw new Error('Cannot find document.');
}
return iframe;
}
}
main.ts中直接引入,注意目录结构
import "@/directive/vue-print-nb/print";
更多推荐
已为社区贡献23条内容
所有评论(0)