electron实现静默打印的示例代码


Posted in Javascript onAugust 12, 2019

前言

electron+vuecli3 实现设置打印机,静默打印小票功能

网上相关的资料比较少,这里给大家分享一下,希望大家可以少踩一些坑
github地址

必须要强调一下的是electron的版本必须是3.0.0不能,我尝试了4和5都没有实现

效果图

electron实现静默打印的示例代码

electron实现静默打印的示例代码

使用

git clone https://github.com/sunnie1992/electron-vue-print-demo.git
npm install
npm run electron:serve

实现

操作思路
1.用户点击打印
2.查询本地electron-store(用来向本地存储,读取数据)是否存打印机名称
3.已经设置,直接打印
4.没有设置,弹出设置打印机框
5.用户设置好确认后打印

首页App.vue引入了两个组件,一个是主动设置打印机的弹出printDialog

electron实现静默打印的示例代码

另外一个是打印组件,打印是通过webview将需要打印的内容渲染到html页面然后就能打印了

<template>
 <div id="app">
  <el-button type="primary" @click="showPrint">设置打印机</el-button>
  <printDialog :dialog-visible="dialogVisible" @cancel="handlePrintDialogCancel" />
  <pinter ref="print" :html-data="HtmlData"></pinter>
  <el-table :data="tableData" style="width: 100%">
   <el-table-column prop="date" label="日期" width="180" column-key="date">
   </el-table-column>
   <el-table-column prop="name" label="姓名" width="180">
   </el-table-column>
   <el-table-column prop="address" label="地址">
   </el-table-column>
   <el-table-column label="操作">
    <template slot-scope="scope">
     <el-button type="primary" @click="doPrint(scope.row)">打印</el-button>
    </template>
   </el-table-column>
  </el-table>
 </div>
</template>
<script>
import { ipcRenderer } from 'electron'
import printDialog from './components/PrintDialog.vue'
import Pinter from './components/pinter.vue'
export default {
 name: 'App',
 components: {
  Pinter,
  printDialog
 },
 data() {
  return {
   dialogVisible: false,
   HtmlData: '',
   printList: [],
   tableData: [{
    date: '2016-05-02',
    name: '我是小仙女',
    address: '上海市浦东新区',
    tag: '家'
   }, {
    date: '2016-05-04',
    name: '我是小仙女1',
    address: '上海市浦东新区',
    tag: '公司'
   }, {
    date: '2016-05-01',
    name: '我是小仙女2',
    address: '上海市浦东新区',
    tag: '家'
   }, {
    date: '2016-05-03',
    name: '我是小仙女3',
    address: '上海市浦东新区',
    tag: '公司'
   }]
  }
 },
 mounted() {
 },
 methods: {
  showPrint() {
   this.dialogVisible = true
  },
  handlePrintDialogCancel() {
   this.dialogVisible = false
  },
  doPrint(row) {
   this.HtmlData = row.name
   this.$refs.print.print(row.name)
  }
 }
}
</script>

<style>
#app {
 font-family: 'Avenir', Helvetica, Arial, sans-serif;
 -webkit-font-smoothing: antialiased;
 -moz-osx-font-smoothing: grayscale;
 text-align: center;
 color: #2c3e50;
 margin-top: 60px;
}
</style>

APP.VUE 每次点击打印按钮后触发组件的print方法并将数据传过去 this.$refs.print.print(row.name)
printer.vue 查询打印机,然后调用打印方法printRender。

<template>
 <div class="container">
  <webview id="printWebview" ref="printWebview" :src="fullPath" nodeintegration />
  <printDialog :dialog-visible="dialogVisible" @cancel="handlePrintDialogCancel" @select-print="printSelectAfter" />
 </div>
</template>
<script>
import { ipcRenderer } from 'electron'
import path from 'path'
import printDialog from './PrintDialog.vue'
export default {
 name: 'Pinter',
 components: {
  printDialog
 },
 props: {
  // HtmlData: {
  //  type: String,
  //  default: '',
  // },
 },
 data() {
  return {
   printList: [],
   dialogVisible: false,
   printDeviceName: '',
   fullPath: path.join(__static, 'print.html'),
   messageBox: null,
   htmlData: ''
  }
 },

 mounted() {
  const webview = this.$refs.printWebview
  webview.addEventListener('ipc-message', (event) => {
   if (event.channel === 'webview-print-do') {
    console.log(this.printDeviceName)
    webview.print(
     {
      silent: true,
      printBackground: true,
      deviceName: this.printDeviceName
     },
     (data) => {
      this.messageBox.close()
      if (data) {
       this.$emit('complete')
      } else {
       this.$emit('cancel')
      }
     },
    )
   }
  })
 },
 methods: {
  print(val) {
   this.htmlData = val
   this.getPrintListHandle()
  },
  // 获取打印机列表
  getPrintListHandle() {
   // 改用ipc异步方式获取列表,解决打印列数量多的时候导致卡死的问题
   ipcRenderer.send('getPrinterList')
   ipcRenderer.once('getPrinterList', (event, data) => {
    // 过滤可用打印机
    this.printList = data.filter(element => element.status === 0)
    // 1.判断是否有打印服务
    if (this.printList.length <= 0) {
     this.$message({
      message: '打印服务异常,请尝试重启电脑',
      type: 'error'
     })
     this.$emit('cancel')
    } else {
     this.checkPrinter()
    }
   })
  },
  // 2.判断打印机状态
  checkPrinter() {
   // 本地获取打印机
   const printerName = this.$electronStore.get('printForm') || ''
   const printer = this.printList.find(device => device.name === printerName)
   // 有打印机设备并且状态正常直接打印
   if (printer && printer.status === 0) {
    this.printDeviceName = printerName
    this.printRender()
   } else if (printerName === '') {
    this.$message({
     message: '请先设置其他打印机',
     type: 'error',
     duration: 1000,
     onClose: () => {
      this.dialogVisible = true
     }
    })
    this.$emit('cancel')
   } else {
    this.$message({
     message: '当前打印机不可用,请重新设置',
     type: 'error',
     duration: 1000,
     onClose: () => {
      this.dialogVisible = true
     }
    })

   }
  },

  handlePrintDialogCancel() {
   this.$emit('cancel')
   this.dialogVisible = false
  },
  printSelectAfter(val) {
   this.dialogVisible = false
   this.$electronStore.set('printForm', val.name)
   this.printDeviceName = val.name
   this.printRender()
  },
  printRender(html) {
   this.messageBox = this.$message({
    message: '打印中,请稍后',
    duration: 0
   })
   // 获取<webview>节点
   const webview = this.$refs.printWebview
   // 发送信息到<webview>里的页面
   webview.send('webview-print-render', {
    printName: this.printDeviceName,
    html: this.htmlData
   })
  }
 }
}
</script>
<style scoped>
.container {
 position: fixed;
 right: -500px;
}
</style>

public/print.html渲染webview页面成功后发送打印指令

<script>
  const { ipcRenderer } = require('electron')
  ipcRenderer.on('webview-print-render', (event, info) => {
   // 执行渲染
   document.getElementById('bd').innerHTML = info.html
   ipcRenderer.sendToHost('webview-print-do')
  })
 </script>

这里用到了electron-store存取本地数据

background.js 引入 初始化挂载在global

import ElectronStore from 'electron-store'
// ElectronStore 默认数据
import electronDefaultData from './config/electron-default-data'
let electronStore
app.on('ready', async() => {
 // 初始化配置文件
 electronStore = new ElectronStore({
  defaults: electronDefaultData,
  cwd: app.getPath('userData')
 })
 global.electronStore = electronStore
})

src/plugins/inject.js

注册$electronStore

// eslint-disable-next-line
import { remote } from 'electron'
export default {
 /* eslint no-param-reassign: "error" */
 install(Vue) {
  Vue.prototype.$electronStore = remote.getGlobal('electronStore')
 
 }
}

然后你就可以在vue文件里读取了

this.$electronStore.get('printForm') 和 this.$electronStore.set('printForm', val.name)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
iframe自适应宽度、高度 ie6 7 8,firefox 3.86下测试通过
Jul 29 Javascript
用JS控制回车事件的代码
Feb 20 Javascript
js实现无需数据库的县级以上联动行政区域下拉控件
Aug 14 Javascript
JavaScript中创建对象和继承示例解读
Feb 12 Javascript
easyui combobox开启搜索自动完成功能的实例代码
Nov 08 Javascript
Node.js使用Express.Router的方法
Nov 14 Javascript
微信小程序 如何引入外部字体库iconfont的图标
Jan 31 Javascript
Express本地测试HTTPS的示例代码
Jun 06 Javascript
在 Angular6 中使用 HTTP 请求服务端数据的步骤详解
Aug 06 Javascript
微信小程序 MinUI组件库系列之badge徽章组件示例
Aug 20 Javascript
详解ES6 CLASS在微信小程序中的应用实例
Apr 24 Javascript
JS异步堆栈追踪之为什么await胜过Promise
Apr 28 Javascript
微信小程序 弹窗输入组件的实现解析
Aug 12 #Javascript
微信小程序 腾讯地图SDK 获取当前地址实现解析
Aug 12 #Javascript
ElementUI radio组件选中小改造
Aug 12 #Javascript
Vue 3.0 前瞻Vue Function API新特性体验
Aug 12 #Javascript
微信小程序实现页面分享onShareAppMessage
Aug 12 #Javascript
react实现antd线上主题动态切换功能
Aug 12 #Javascript
vue从一个页面跳转到另一个页面并携带参数的解决方法
Aug 12 #Javascript
You might like
php写的带缓存数据功能的mysqli类
2012/09/06 PHP
使用WordPress发送电子邮件的相关PHP函数用法解析
2015/12/15 PHP
删除重复数据的算法
2006/11/23 Javascript
jquery tools之tabs 选项卡/页签
2009/07/25 Javascript
关于IE BUG与字符串截取substr的解决办法
2013/04/10 Javascript
jquery实现鼠标点击后展开列表内容的导航栏效果
2015/09/14 Javascript
Js的Array数组对象详解
2016/02/22 Javascript
jQuery 跨域访问解决原理案例详解
2016/07/09 Javascript
js removeChild 方法深入理解
2016/08/16 Javascript
用js控件div的滚动条,让它在内容更新时自动滚到底部的实现方法
2016/10/27 Javascript
js模式化窗口问题![window.dialogArguments]
2016/10/30 Javascript
JS中cookie的使用及缺点讲解
2017/05/13 Javascript
使用原生js+canvas实现模拟心电图的实例
2017/09/20 Javascript
javascript设计模式 ? 模板方法模式原理与用法实例分析
2020/04/23 Javascript
详解关于Vue单元测试的几个坑
2020/04/26 Javascript
jQuery HTML获取内容和属性操作实例分析
2020/05/20 jQuery
详谈Vue.js框架下main.js,App.vue,page/index.vue之间的区别
2020/08/12 Javascript
vue项目页面嵌入代码块vue-prism-editor的实现
2020/10/30 Javascript
[26:50]2018完美盛典DOTA2表演赛
2018/12/17 DOTA
python 实现删除文件或文件夹实例详解
2016/12/04 Python
浅析python协程相关概念
2018/01/20 Python
python模糊图片过滤的方法
2018/12/14 Python
Python简直是万能的,这5大主要用途你一定要知道!(推荐)
2019/04/03 Python
numpy下的flatten()函数用法详解
2019/05/27 Python
python 使用递归实现打印一个数字的每一位示例
2020/02/27 Python
Python常驻任务实现接收外界参数代码解析
2020/07/21 Python
使用canvas来完成线性渐变和径向渐变的功能的方法示例
2019/07/25 HTML / CSS
超市促销实习自我鉴定
2013/09/23 职场文书
初三班主任寄语大全
2014/04/04 职场文书
社会公德演讲稿
2014/05/20 职场文书
小学生十佳少年事迹材料
2014/08/20 职场文书
教师纪念9.18事件演讲稿范文
2014/09/14 职场文书
水利专业大学生职业生涯规划书范文
2014/09/17 职场文书
2014村书记党建工作汇报材料
2014/11/02 职场文书
2014年信贷员工作总结
2014/11/18 职场文书
乡镇法制宣传日活动总结
2015/05/05 职场文书