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 相关文章推荐
js实现兼容IE6与IE7的DIV高度
May 13 Javascript
javascript获取鼠标位置部分的实例代码(兼容IE,FF)
Aug 05 Javascript
使用GruntJS构建Web程序之合并压缩篇
Jun 06 Javascript
JavaScript实现简洁的俄罗斯方块完整实例
Mar 01 Javascript
理解javascript对象继承
Apr 17 Javascript
JavaScript中push(),join() 函数 实例详解
Sep 06 Javascript
RequireJS 依赖关系的实例(推荐)
Jan 21 Javascript
js实现网页定位导航功能
Mar 07 Javascript
js和jQuery以及easyui实现对下拉框的指定赋值方法
Jan 23 jQuery
利用Dectorator分模块存储Vuex状态的实现
Feb 05 Javascript
利用Node.js如何实现文件循环覆写
Apr 05 Javascript
实现高性能javascript的注意事项
May 27 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学习 计数器实例代码
2008/06/15 PHP
兼容PHP5的PHP目录管理函数库
2008/07/10 PHP
PHP操作mysql函数详解,mysql和php交互函数
2011/05/19 PHP
PHP面向对象概念
2011/11/06 PHP
PHP去掉从word直接粘贴过来的没有用格式的函数
2012/10/29 PHP
PHP5.5新特性之yield理解与用法实例分析
2019/01/11 PHP
jquery的总体架构分析及实现示例详解
2014/11/08 Javascript
jQuery读取XML文件内容的方法
2015/03/09 Javascript
纯javascript模仿微信打飞机小游戏
2015/08/20 Javascript
javascript实现二级级联菜单的简单制作
2015/11/19 Javascript
浅析创建javascript对象的方法
2016/05/13 Javascript
微信小程序之MaterialDesign--input组件详解
2017/02/15 Javascript
JS基于正则实现数字千分位用逗号分隔的方法
2017/06/16 Javascript
node中的session的具体使用
2018/09/14 Javascript
vue-cli3环境变量与分环境打包的方法示例
2019/02/18 Javascript
vue.js的状态管理vuex中store的使用详解
2019/11/08 Javascript
简单了解Vue computed属性及watch区别
2020/07/10 Javascript
Python全局变量操作详解
2015/04/14 Python
python分割列表(list)的方法示例
2017/05/07 Python
Python字典添加,删除,查询等相关操作方法详解
2020/02/07 Python
python爬虫学习笔记之Beautifulsoup模块用法详解
2020/04/09 Python
python切割图片的示例
2020/11/12 Python
商务助理岗位职责
2013/11/13 职场文书
商场端午节活动方案
2014/01/29 职场文书
周年庆促销方案
2014/03/15 职场文书
《孔繁森》教学反思
2014/04/17 职场文书
总经理任命书范本
2014/06/05 职场文书
建筑横幅标语
2014/10/09 职场文书
教师廉洁自律个人总结
2015/02/10 职场文书
联村联户简报
2015/07/21 职场文书
导游词之金鞭溪风景区
2019/09/12 职场文书
Vue项目中如何封装axios(统一管理http请求)
2021/05/02 Vue.js
Python+Appium实现自动抢微信红包
2021/05/21 Python
QT与javascript交互数据的实现
2021/05/26 Javascript
nginx内存池源码解析
2021/11/20 Servers
Python列表的索引与切片
2022/04/07 Python