背景:vue+elementui开发常见网页ERP零售收银过程中遇到打印商品凭条与小票的功能开发和调试。
软件调试
- 软件部分思路: iframe+window.print()。通过iframe渲染需要的凭条或者小票样式,使用window.print()触发浏览器的打印功能。
- iframe内嵌凭条或者小票是因为凭条小票的样式不一样,需要单独使用封装一个页面组件渲染后端返回的数据,并通过this.$refs.name.innerHTML将对应的凭条或者小票HTML文件内嵌到iframe中。
- window.print() 调用这个方法时,浏览器会打开打印对话框,允许用户选择打印设备、设置打印参数(如页眉、页脚等),然后将当前页面或指定的页面内容打印出来。
- 代码
打印组件
<template>
<div class="print">
<iframe id="iframe" style="display: none;"></iframe>
</div>
</template>
<script>
export default {
name: "print",
props: {
html: {
type: String,
default: ""
}
},
data(){
return {}
},
watch: {
},
methods: {
// 触发打印的函数,在父组件中调用
setBodyHtml(html) {
this.show = true;
const document = window.document;
const iframe = window.frames[0];
iframe.document.head.innerHTML = document.head.innerHTML; // 获取当前文档的头部给iframe
iframe.document.body.innerHTML = html; // 把传过来的html给iframe头部
// 图片和样式加载完成
Promise.all([this.loadStyle()]).then(res => {
// 打印
iframe.window.print();
this.$emit('refresh-event');
// 关闭打印
iframe.window.close();
});
},
//样式加载
loadStyle() {
const iframe = window.frames[0];
const styles = iframe.document.head.getElementsByTagName("style"); // <style>
const links = iframe.document.head.getElementsByTagName("link"); // <link>
let arrs = [];
arrs = arrs.concat(...styles, ...links);
return new Promise((resolve, reject) => {
for (let i = 0; i < arrs.length; i++) {
arrs[i].onload = function () {
if (i === arrs.length - 1) {
resolve("style 样式加载完成");
}
};
}
});
},
}
};
</script>
- 备注: vue中调用window.print()时,需要打印的页面DOM节点依旧挂载在当前页面的根节点上,所以当我们滑动页面时,底部会显示打印页面的HTML,解决方法是我们在未使用组件时可通过v-if隐藏它,当我们完成打印时iframe.window.close()关闭组件。
硬件调试
- 打印机硬件不同设配需要使用时需要进行调试,这里也总结一下。
- 驱动: 不同型号的打印设配驱动可前往对应官网下载。得力官网: www.nbdeli.com/products/li…
- 第一步添加设备
- 第二步安装对应设备驱动
解压安装包并根据指引安装驱动
- 第三步设置打印尺寸
打开打印机列表-右键选中打印机属性-首选项设置打印纸张尺寸。(凭条尺寸: 4030毫米;小票尺寸: 80210毫米)
- 第四步测试打印 打印测试页检查设备连接是否正常
- 备注 :部分设备需要适配对应端口才能打印,如果打印测试纸失败并且确定驱动安装成功,可打开对应设备的属性,检查端口设置,重新测试打印。