electron获取本地打印机并且实现打印

本文主要介绍了electron如何获取本地打印机,并且连接打印机进行打印

这里我用的是vue3,react或者vue2用户可自行根据代码来转换风格

1.打印机渲染在渲染进程,获取的话只能在主进程来获取

        1.1 主进程获取-background.js

import { app ,dialog} from 'electron'
let win

// 通过检查第二个实例启动时的事件来避免多个实例运行
const gotTheLock = app.requestSingleInstanceLock()

async function createWindow() {
  const config = {
    ...winState.winOptions,
    minWidth: 400, // 设置最小宽度
    webPreferences: {
      contextIsolation: false,
      enableRemoteModule: true,
      nodeIntegration: true,
      webSecurity: false, //允许跨域访问本地图片
      webviewTag: true,
    },
  }
  Menu.setApplicationMenu(null) // null值取消顶部菜单栏

  win = new BrowserWindow(config)
  if (process.env.WEBPACK_DEV_SERVER_URL) {
    // Load the url of the dev server if in development mode
    await win.loadURL(process.env.WEBPACK_DEV_SERVER_URL)
    if (!process.env.IS_TEST) win.webContents.openDevTools()
  } else {
    createProtocol('app')
    // Load the index.html when not in development
    win.loadURL('app://./index.html')
  }
  winState.manage(win)
}

app.on('ready', async () => {
  if (!gotTheLock) {
    app.quit()
  } else {
    app.on('second-instance', (event, commandLine, workingDirectory) => {
      if (win) {
        if (win.isMinimized()) {
          win.restore()
        }
        win.focus()
      }
    })
    createWindow()

// 在electron启动后注册所有的主进程ipc事件
    electronApiInit()

    win.on('closed', () => {
      win = null
    })
  }

})

// 主进程注册事件
function electronApiInit() {
  try {
    process.env.WEBPACK_DEV_SERVER_URL && win.setIcon(path.join(__dirname, `../public/favicon.png`))

    electronInit.initPrintList(win)
  } catch (error) {
    dialog.showErrorBox('ElectronApiInit', JSON.stringify(error.message))
  }
}

1.2 注册获取本地打印机事件

import { dialog, ipcMain } from 'electron'
export const initPrintList = (win) => {
  ipcMain.handle('getPrintList', async (event, isShowMessage) => {
    try {
       // 在background.js里把win对象传递进来,通过win的webContents的getPrintersAsync方法获取到本地打印机,在渲染进程进行读取
      const list = await win.webContents.getPrintersAsync()
      return list
    } catch (error) {
      console.log('error', error)
    }
  })
}

1.3渲染进程读取本地打印机数组(vue文件或者jsx文件)




<div v-for="item in systemPrintList" :key="item.name">
        <div :class="['p-x-10', item.isActive ? 'header-active' : 'header-max']"  @click="setActiveItem(item)" >{{ item.name }}</div>
      </div>

const { ipcRenderer } = require('electron')

import {ref} from 'vue'

const printList = ref([])

    // 这个函数写到vue文件的methods里
async getPrintList({ commit }, data) {
      const list = await ipcRenderer.invoke('getPrintList', data)
      list.forEach((l) => {
       // isDefault字段是返回自带的,代表着当前哪台打印机处于活跃状态
        l.isActive = l.isDefault
      })
      printList.value = list
      console.log('list', list)
}

// 设置当前活跃的打印机
const setActiveItem = (item) => {
  printList.value.forEach((f) => {
    f.isActive = f.name === item.name
  })
}

   到这步为止,已经可以获取到本地打印机,如果方便别的地方读取,可以存储到vuex/pinia/redux里

2.实现打印

 electron的打印主要可以分为两种,一种是webContents的print方法,另一种是webview的打印,这里我们使用的是webContents的打印

2.1 获取webContents

      要获取到webContents,首先需要获取到win。win在BrowserWindow可以拿到,因为打印是不能覆盖我们现有的electron页面,所以需要new一个新的BrowserWindow对象并且设置为show:false,我们可以封装一个print函数,打印的方法和函数之类的都可以写到这个函数里,这里我简单封装一个

// print.js
import { ipcMain, BrowserWindow } from 'electron'
export default function usePrint() {
  /**主窗体的win对象 */
  ipcMain.on('handle_print', (e, { htmlText, deviceName }) => {
    // 创建一个新的隐藏窗口,用于打印
    let printWindow = new BrowserWindow({ show: false, width: 1920, height: 1080, contextIsolation: false, enableRemoteModule: true, nodeIntegration: true, webSecurity: false })
    printWindow.loadURL('data:text/html,' + encodeURIComponent(htmlText))
    printWindow.webContents.print({ deviceName, silent: true })
  })
}

2.2 初始化主进程函数 

// background.js

import { app, protocol, BrowserWindow, Menu, dialog } from 'electron'
import usePrint from './electron-service/ipc/usePrint'

let win

async function createWindow() {
  const config = {
    ...winState.winOptions,
    minWidth: 400, // 设置最小宽度
    webPreferences: {
      contextIsolation: false,
      enableRemoteModule: true,
      nodeIntegration: true,
      webSecurity: false, //允许跨域访问本地图片
      webviewTag: true,
    },
  }
  Menu.setApplicationMenu(null) // null值取消顶部菜单栏

  win = new BrowserWindow(config)

  winState.manage(win)
}

app.on('ready', async () => {
  if (!gotTheLock) {
    app.quit()
  } else {
    app.on('second-instance', (event, commandLine, workingDirectory) => {
      if (win) {
        if (win.isMinimized()) {
          win.restore()
        }
        win.focus()
      }
    })
    createWindow()
  }
// 这里初始化print
  usePrint()
})

2.3 渲染进程发送事件,主进程监听进行打印 

<template>
<button @click="print">打印</button>
</template>

import { ipcRenderer } from 'electron'



// 这里我们使用html模板进行打印,deviceName为打印机名称,可以使用本地打印机名称,这里做测试用,所以我写死
const print = () => {
  const printInfo = {
    htmlText:
      '<!doctype html><html lang=\'en\'><head><meta charset=\'utf-8\'><title>打印</title><style>*{box-sizing: border-box;}   td{ word-break: break-all;}</style></head><body><div style=\'position: relative;width: 100%;height: 100%\'><div style=\'width:100%;min-height:25px;display:flex;flex-wrap:wrap;margin-left:0px;margin-right:0px;margin-Top:0px;margin-bottom:1px;\'><div style=\'display:block;word-break: break-all;flex: 0 0 33.33333336%;\'></div><div style=\'display:block;word-break: break-all;flex: 0 0 33.33333336%;\'><div style=\'font-size:18px;font-weight:normal;text-align:center;margin-left:0px;margin-right:0px;margin-Top:0px;margin-bottom:1px;\'>粤十-库存过户单</div></div><div style=\'display:block;word-break: break-all;flex: 0 0 33.33333336%;\'><div style=\'text-align:justify-start\'><img src=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAAA8CAIAAABTvhANAAABKUlEQVR42u3TQQqAIBBA0bn/pQ0MShzHFq2E91dhZlq8aCcUvfviGdlPyNf51nLyuNT4VB6MoekV02rVs9VgddK8ybxCtbH8AX8eM+9hufJywueJpp+7WW3zBdohBYQQQgghhBBCCCGEEEIIIYQQQgghhBBCCCGEEEIIIYQQQgghhBBCCCGEEEIIIYQQQgghhBBCCCGEEEIIIYQQQgghhBBCCCGEEEIIIYQQQgghhBBCCCGEEEIIIYQQQgghhBBCCCGEEEIIIYQQQgghhBBCCCGEEEIIIYQQQgghhBBCCCGEEEIIIYQQQgghhBBCCCGEEEIoCUIJQkkQShBKglCCUBKEEoSSIJQglAShBKEkCCUIJUEoQSgJQglCSRBKEEqCUIJQEoQShJLeLiIpS/zZp3V9AAAAAElFTkSuQmCC style=\'width:273px;height:70px;margin-left:0px;margin-right:0px;margin-Top:0px;margin-bottom:1px;\' /></div><div style=\'font-size:12px;font-weight:normal;text-align:center;margin-left:0px;margin-right:0px;margin-Top:0px;margin-bottom:1px;\'>GH-20230914-000005</div></div></div><div style=\'width:100%;min-height:25px;display:flex;flex-wrap:wrap;margin-left:0px;margin-right:0px;margin-Top:0px;margin-bottom:1px;\'><div style=\'display:block;word-break: break-all;flex: 0 0 50.000000039999996%;\'><div style=\'font-size:15px;font-weight:normal;text-align:left;margin-left:0px;margin-right:0px;margin-Top:0px;margin-bottom:1px;\'>过户单号:GH-20230914-000005</div><div style=\'font-size:15px;font-weight:normal;text-align:left;margin-left:0px;margin-right:0px;margin-Top:0px;margin-bottom:1px;\'>原货主:非标测试货主</div></div><div style=\'display:block;word-break: break-all;flex: 0 0 50.000000039999996%;\'><div style=\'font-size:15px;font-weight:normal;text-align:left;margin-left:0px;margin-right:0px;margin-Top:0px;margin-bottom:1px;\'>过户时间:</div><div style=\'font-size:15px;font-weight:normal;text-align:left;margin-left:0px;margin-right:0px;margin-Top:0px;margin-bottom:1px;\'>新货主:企业系统企业货主7</div></div></div><div style=\'margin-left:0px;margin-right:0px;margin-Top:0px;margin-bottom:1px;\'><table borderCollapse="collapse" border="none" style=\'font-size:15px;border-collapse:collapse;width:100%\'><thead><tr style=\'white-space: pre-wrap;\'><td style="border: solid #000 1px;height: undefinedpx;width: 30px; text-align: undefined">序号</td><td style="border: solid #000 1px;height: undefinedpx;width: 30px; text-align: undefined">商品名称</td><td style="border: solid #000 1px;height: undefinedpx;width: 30px; text-align: undefined">批次号</td><td style="border: solid #000 1px;height: undefinedpx;width: 30px; text-align: undefined">过户数量</td><td style="border: solid #000 1px;height: undefinedpx;width: 30px; text-align: undefined">库存数量</td><td style="border: solid #000 1px;height: undefinedpx;width: 30px; text-align: undefined">库存重量</td><td style="border: solid #000 1px;height: undefinedpx;width: 30px; text-align: undefined">过户重量</td><td style="border: solid #000 1px;height: undefinedpx;width: 30px; text-align: undefined">分配数量</td><td style="border: solid #000 1px;height: undefinedpx;width: 30px; text-align: undefined">可用数量</td><td style="border: solid #000 1px;height: undefinedpx;width: 30px; text-align: undefined">生产日期</td><td style="border: solid #000 1px;height: undefinedpx;width: 30px; text-align: undefined">失效日期</td><td style="border: solid #000 1px;height: undefinedpx;width: 30px; text-align: undefined">物料号</td><td style="border: solid #000 1px;height: undefinedpx;width: 30px; text-align: undefined">托盘号</td></tr></thead><tbody><tr style=\'height: undefinedpx;white-space: pre-wrap\'><td style="border: solid #000 1px; text-align: undefined">1</td><td style="border: solid #000 1px; text-align: undefined">高粱酒</td><td style="border: solid #000 1px; text-align: undefined">#000694</td><td style="border: solid #000 1px; text-align: undefined">2</td><td style="border: solid #000 1px; text-align: undefined">2</td><td style="border: solid #000 1px; text-align: undefined">2</td><td style="border: solid #000 1px; text-align: undefined">2</td><td style="border: solid #000 1px; text-align: undefined">0</td><td style="border: solid #000 1px; text-align: undefined">2</td><td style="border: solid #000 1px; text-align: undefined"></td><td style="border: solid #000 1px; text-align: undefined"></td><td style="border: solid #000 1px; text-align: undefined"></td><td style="border: solid #000 1px; text-align: undefined">TP202309134723</td></tr><tr style=\'height: undefinedpx;white-space: pre-wrap\'><td style="border: solid #000 1px; text-align: undefined">2</td><td style="border: solid #000 1px; text-align: undefined">150克冰袋,130个/框</td><td style="border: solid #000 1px; text-align: undefined">#000700</td><td style="border: solid #000 1px; text-align: undefined">33</td><td style="border: solid #000 1px; text-align: undefined">33</td><td style="border: solid #000 1px; text-align: undefined">643.5</td><td style="border: solid #000 1px; text-align: undefined">643.5</td><td style="border: solid #000 1px; text-align: undefined">0</td><td style="border: solid #000 1px; text-align: undefined">33</td><td style="border: solid #000 1px; text-align: undefined"></td><td style="border: solid #000 1px; text-align: undefined"></td><td style="border: solid #000 1px; text-align: undefined"></td><td style="border: solid #000 1px; text-align: undefined">TP202309144826</td></tr><tr style=\'height: undefinedpx;white-space: pre-wrap\'><td style="border: solid #000 1px; text-align: undefined"></td><td style="border: solid #000 1px; text-align: undefined"></td><td style="border: solid #000 1px; text-align: undefined">合计</td><td style="border: solid #000 1px; text-align: undefined">35</td><td style="border: solid #000 1px; text-align: undefined">35</td><td style="border: solid #000 1px; text-align: undefined">645.5</td><td style="border: solid #000 1px; text-align: undefined">645.5</td><td style="border: solid #000 1px; text-align: undefined"></td><td style="border: solid #000 1px; text-align: undefined"></td><td style="border: solid #000 1px; text-align: undefined"></td><td style="border: solid #000 1px; text-align: undefined"></td><td style="border: solid #000 1px; text-align: undefined"></td><td style="border: solid #000 1px; text-align: undefined"></td></tr></tbody></table></div><div style=\'font-size:15px;font-weight:normal;text-align:left;margin-left:0px;margin-right:0px;margin-Top:0px;margin-bottom:30px;\'>备注:</div><div style=\'width:100%;min-height:25px;display:flex;flex-wrap:wrap;margin-left:0px;margin-right:0px;margin-Top:0px;margin-bottom:1px;\'><div style=\'display:block;word-break: break-all;flex: 0 0 33.33333336%;\'><div style=\'font-size:15px;font-weight:normal;text-align:left;margin-left:0px;margin-right:0px;margin-Top:0px;margin-bottom:1px;\'>过户件数:45</div></div><div style=\'display:block;word-break: break-all;flex: 0 0 33.33333336%;\'><div style=\'font-size:15px;font-weight:normal;text-align:left;margin-left:0px;margin-right:0px;margin-Top:0px;margin-bottom:1px;\'>过户重量:840.5</div></div><div style=\'display:block;word-break: break-all;flex: 0 0 33.33333336%;\'><div style=\'font-size:15px;font-weight:normal;text-align:left;margin-left:0px;margin-right:0px;margin-Top:0px;margin-bottom:1px;\'>过户体积:0</div></div></div><div style=\'width:100%;min-height:25px;display:flex;flex-wrap:wrap;margin-left:0px;margin-right:0px;margin-Top:0px;margin-bottom:1px;\'><div style=\'display:block;word-break: break-all;flex: 0 0 25.000000019999998%;\'><div style=\'font-size:15px;font-weight:normal;text-align:left;margin-left:0px;margin-right:0px;margin-Top:0px;margin-bottom:1px;\'>审核人:</div><div style=\'font-size:15px;font-weight:normal;text-align:left;margin-left:0px;margin-right:0px;margin-Top:0px;margin-bottom:1px;\'>创建人:潇哥哥</div></div><div style=\'display:block;word-break: break-all;flex: 0 0 25.000000019999998%;\'><div style=\'font-size:15px;font-weight:normal;text-align:left;margin-left:0px;margin-right:0px;margin-Top:0px;margin-bottom:1px;\'>主管:</div></div><div style=\'display:block;word-break: break-all;flex: 0 0 25.000000019999998%;\'><div style=\'font-size:15px;font-weight:normal;text-align:left;margin-left:0px;margin-right:0px;margin-Top:0px;margin-bottom:1px;\'>原货主:非标测试货主</div></div><div style=\'display:block;word-break: break-all;flex: 0 0 25.000000019999998%;\'><div style=\'font-size:15px;font-weight:normal;text-align:left;margin-left:0px;margin-right:0px;margin-Top:0px;margin-bottom:1px;\'>新货主:企业系统企业货主7</div></div></div></div></body></html>',
    deviceName: '皓诚达打印机',
  }
  ipcRenderer.send('handle_print', printInfo)
}

2.4 打印完成 

此时查看打印队列发现已经发送过去并且完成打印

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值