视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
electron实现静默打印的示例代码
2020-11-27 21:52:35 责编:小采
文档

前言

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

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

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

效果图


使用

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

另外一个是打印组件,打印是通过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)

下载本文
显示全文
专题