electron@7.2.4实现打印功能

tech2023-06-13  121

一、background.js,项目入口配置文件

import { app, protocol, BrowserWindow, ipcMain } from 'electron' /* * * 省略多数默认配置 * * */ /* * 打印 * */ //在主线程下,通过ipcMain对象监听渲染线程传过来的getPrinterList事件 ipcMain.on('getPrinterList', (event) => { //主线程获取打印机列表 const list = win.webContents.getPrinters(); //通过webContents发送事件到渲染线程,同时将打印机列表也传过去 win.webContents.send('getPrinterList', list); });

二、printerDiff.vue,打印组件,在components里面创建

<template> <div class="container"> <webview id="printWebview" ref="printWebview" :src="fullPath" nodeintegration/> <printDialog :dialog-visible="dialogVisible" @cancel="handlePrintDialogCancel" @select-print="printSelectAfter"/> </div> </template> <script> const {ipcRenderer} = window.require('electron') import path from 'path' import printDialog from '@/components/PrintDialog.vue' import { Message } from 'element-ui' 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', async event => { if (event.channel === 'webview-print-do') { await webview.print({ silent: true, printBackground: true, deviceName: this.printDeviceName }) } }) }, 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) { Message.info('打印服务异常,请尝试重启电脑') this.$emit('cancel') } else { this.dialogVisible = true // this.checkPrinter() } }) }, // 2.判断打印机状态 checkPrinter () { // 本地获取打印机 const printerName = this.$util.getLocalStorage('printForm') const printer = this.printList.find(device => device.name === printerName) // 有打印机设备并且状态正常直接打印 if (printer && printer.status === 0) { this.printDeviceName = printerName this.printRender() } else if (printerName === '') { Message.info('请先设置其他打印机') this.dialogVisible = true this.$emit('cancel') } else { Message.info('当前打印机不可用,请重新设置') this.dialogVisible = true } }, handlePrintDialogCancel () { this.$emit('cancel') this.dialogVisible = false }, printSelectAfter (val) { this.dialogVisible = false this.$util.setLocalStorage('printForm', val.name) this.printDeviceName = val.name this.printRender() }, printRender (html) { Message.info('打印中,请稍后') console.log(this.printDeviceName); console.log(this.htmlData); // 获取<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>
__static无法使用的时候,.eslintrc.js文件添加

globals: { __static: true }

module.exports = { root: true, env: { node: true }, 'extends': [ 'plugin:vue/essential', 'eslint:recommended' ], rules: { 'no-unused-vars': 'off', 'no-console': 'off', 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off' }, parserOptions: { parser: 'babel-eslint' }, globals: { __static: true }, }
不能直接使用require,需要使用

window.require(‘electron’)

注意

一定要这样写,不要像大部分网络案例写回调,写回调将会报错 webview.print({ silent: true, printBackground: true, deviceName: this.printDeviceName })

添加回调报错


三、PrintDialog.vue,打印机列表组件,在components里面创建

this.$util.getLocalStorage(‘printForm’)是获取缓存里面打印机名称,自定义封装的方法,具体写法随意
<template> <div> <el-dialog width="300px" :visible="dialogVisible" :append-to-body="true" :show-close="false" title="打印机设置"> <el-table :data="printList" highlight-current-row border @current-change="handleCurrentChange"> <el-table-column label="打印机名称"> <template slot-scope="scope"> {{ scope.row.name }} <!--<el-tag v-if="scope.row.name==printName" type="primary" disable-transitions>默认</el-tag>--> </template> </el-table-column> <div slot="empty"> 暂无可用打印机 </div> </el-table> <div class="buttonStyle"> <el-button @click="$emit('cancel')">取消</el-button> <el-button type="primary" @click="checkPrinter">确认</el-button> </div> </el-dialog> </div> </template> <script> const {ipcRenderer} = window.require('electron') import { Message } from 'element-ui' export default { name: '', props: { dialogVisible: { type: Boolean, default: false } }, data () { return { rowData: null, printList: [], } }, computed: { printName(){ return this.$util.getLocalStorage('printForm') } }, watch: { dialogVisible: { immediate: true, handler: 'getPrintListHandle' }, }, methods: { // 获取打印机列表 getPrintListHandle (dialogVisible) { if (!dialogVisible) { return } // 改用ipc异步方式获取列表,解决打印列数量多的时候导致卡死的问题 ipcRenderer.send('getPrinterList') ipcRenderer.once('getPrinterList', (event, data) => { // 过滤可用打印机 this.printList = data.filter(element => element.status === 0) }) }, handleCurrentChange (row) { this.rowData = row }, // 取消 cancel () { this.dialogVisible = false }, checkPrinter () { // 本地获取打印机 const printerName = this.$util.getLocalStorage('printForm') const printer = this.printList.find(device => device.name === printerName) // 有打印机设备并且状态正常直接打印 if (printer && printer.status === 0) { this.selectPrint() } else if (printerName === '') { Message.info('请先设置其他打印机') } else { Message.info('当前打印机不可用,请重新设置') } }, selectPrint () { if (this.rowData) { this.$util.setLocalStorage('printForm', this.rowData.name) this.$emit('select-print', this.rowData) } else { Message.info('您还没有选择打印机') } }, } } </script> <style scoped> .buttonStyle { text-align: right; margin-top: 20px; } </style>

四、Login.vue,页面

<template> <div> <printerDiff ref="printRef" :html-data="htmlData"></printerDiff> </div> </template> <script> import printerDiff from '@/components/printerDiff.vue' import { Message } from 'element-ui' const path = window.require('path') export default { name: 'Login', data () { return { printList: [], fullPath: path.join(__static, 'print.html'), printDeviceName: '', htmlData: '我是小仙女', } }, methods: { // 获取打印机列表 doPrint() { if(this.$util.getLocalStorage('printForm') == null){ // 改用ipc异步方式获取列表,解决打印列数量多的时候导致卡死的问题 ipcRenderer.send('getPrinterList') ipcRenderer.once('getPrinterList', (event, data) => { // 过滤可用打印机 this.printList = data.filter(element => element.status === 0) // 1.判断是否有打印服务 if (this.printList.length <= 0) { Message.error('打印服务异常,请尝试重启电脑') } else { this.$util.setLocalStorage('printForm', this.printList[0].name) this.$refs.printRef.print(this.htmlData) } }) } else { this.$refs.printRef.print(this.htmlData) } }, }, components: { printerDiff } } </script> <style lang="scss" scoped> </style>

五、在public目录创建print.html

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"/> <meta name="viewport" content="width=device-width, initial-scale=1.0"/> <meta http-equiv="X-UA-Compatible" content="ie=edge"/> <title>Document</title> <style> body, html { padding: 0; margin: 0; font-size: 30px; } @page { margin: 0px; } .title { font-size: 16px; padding: 10px 0; border-bottom: 1px solid #333333; } </style> </head> <body id="bd"></body> <script> const {ipcRenderer} = window.require('electron') ipcRenderer.on('webview-print-render', (event, info) => { let obj = '' obj += `<div class="title">${info.html}</div>` // 执行渲染 document.getElementById('bd').innerHTML = obj ipcRenderer.sendToHost('webview-print-do') }) </script> </html>
最新回复(0)