vue3简单打印实现(新测试:vue2打印原理相同)
前端打印 vue2+ 简单实现
·
需求
vue3+ts+vite
重要:灵感来源大佬总结
主要实现原理
window.print()方法调起浏览器打印
规避页面重新赋值用以解决页面在打印后按键失效问题
上代码
const handlePrint = () =>{
editableIs.value = false;
showChang.value =true;//以上用于关闭不需要打印的部分 最简单的方法是给dom v-if,不需要赘述吧
setTimeout(function(){//双向绑定需要给页面渲染时间,延迟一定时间
let oldStr = window.document.body.innerHTML; // 获取body的内容
let start = "<!--startprint-->"; // 开始打印标识, 17个字符
let end = "<!--endprint-->"; // 结束打印标识
let newStr = oldStr.substr(oldStr.indexOf(start) + 17); // 截取开始打印标识之后的内容
newStr = newStr.substring(0, newStr.indexOf(end)); // 截取开始打印标识和结束打印标识之间的内容
let printData = newStr
printHtml(printData)
},500)
}
注意配合打印后的回调
window.onafterprint = function(event) {
//放开隐藏的元素
editableIs.value = true;
showChang.value =false;
};
这里是需要引入的printHtml方法
export default function printHtml(html) {
let style = getStyle();
let container = getContainer(html);
document.body.appendChild(style);
document.body.appendChild(container);
getLoadPromise(container).then(() => {
window.print();
document.body.removeChild(style);
document.body.removeChild(container);
});
}
// 设置打印样式
function getStyle() {
let styleContent = `#print-container {
display: none;
}
@media print {
body > :not(.print-container) {
display: none;
}
html,
body {
display: block !important;
}
#print-container {
display: block;
}
}`;
let style = document.createElement("style");
style.innerHTML = styleContent;
return style;
}
// 清空打印内容
function cleanPrint() {
let div = document.getElementById('print-container')
if (!!div) {
document.querySelector('body').removeChild(div)
}
}
// 新建DOM,将需要打印的内容填充到DOM
function getContainer(html) {
cleanPrint()
let container = document.createElement("div");
container.setAttribute("id", "print-container");
container.innerHTML = html;
return container;
}
// 图片完全加载后再调用打印方法
function getLoadPromise(dom) {
let imgs = dom.querySelectorAll("img");
imgs = [].slice.call(imgs);
if (imgs.length === 0) {
return Promise.resolve();
}
let finishedCount = 0;
return new Promise(resolve => {
function check() {
finishedCount++;
if (finishedCount === imgs.length) {
resolve();
}
}
imgs.forEach(img => {
img.addEventListener("load", check);
img.addEventListener("error", check);
})
});
}
防止还有看不懂的
import printHtml from "../../utils/print" //找个文件夹丢进去 引入
问题
打印缺少css样式 :目前已符合项目需求,需要的话可以在封装方法中引入css
优势还是挺大的,避免了转图片再打印时的dom切割问题
上个图
再次感谢大佬
https://blog.csdn.net/qq_38128179/article/details/103344021
补充:
在vite打包后页面中注释内容会被删除-----使用无意义的标签如"<i v-if=“colse” name=“test"> < v-if=“colse” i>"进行包裹,调整切割位数就可以了,注意v-if的时机
vue2
// dom部分 可用if控制
<i test='name'></i>
<div>
打印测试测测测测测测测测测
</div>
<i test='names'></i>
methods: {
handlePrint() {
setTimeout(function(){//双向绑定需要给页面渲染时间,延迟一定时间
//以下可替换为newStr = document.getElementById("print").innerHTML
let oldStr = window.document.body.innerHTML; // 获取body的内容
console.log(oldStr)
let start = '<i test="name">'; // 开始打印标识, 19个字符 注意""
let end = '<i test="names"></i>'; // 结束打印标识
let newStr = oldStr.substr(oldStr.indexOf(start) + 19); // 截取开始打印标识之后的内容
newStr = newStr.substring(0, newStr.indexOf(end)); // 截取开始打印标识和结束打印标识之间的内容
let printData = newStr
console.log(newStr)
printHtml(printData)
},1000)
}
},
补充一下canvas打印发放—echarts
原理:将canvas转为图片 ,替换本页的画布为图片,注这里为打印弹窗区域内容,而不需要将原本内容替换回来只需要在打印时关闭弹窗,就相当于刷新了弹窗
<div id="print">
<!-打印内容 canvas的包裹标签上加标识testCharts->
</div>
handlePrint() {
this.dialogVisible = true;
let newStr="";
// setTimeout(function () {//双向绑定需要给页面渲染时间,延迟一定时间
let cvs = document.getElementsByTagName("canvas");
let resImgs = document.getElementsByClassName("testCharts");
for(let i = 0;i<resImgs.length;i++){
let context = cvs[0].getContext("2d");
let img = new Image();
let strDataURL = cvs[0].toDataURL("image/png");
img.src = strDataURL;
resImgs[i].innerHTML = `<img src="${strDataURL}">`;
}
newStr = document.getElementById("print").innerHTML;//置换完图片获取页面
// }, 1000)
setTimeout(()=>{
this.dialogVisible = false;
printHtml(newStr);
},1000)
}
更多推荐
已为社区贡献4条内容
所有评论(0)