electron-react对接打印机 实现打印功能

思路

在electron-react项目当中要实现打印部分页面内容的需求,
第一种方法是使用iframe标签打印,这种方法最简单网上有很多教程,使用iframe.contentWindow.print()这个方法会弹出打印对话框,我还没有找到关闭的方法,所以没有采用。
第二种方法是在使用electron的主线程调用webContents.print()方法,这个方法相对比较复杂,主线程和渲染线程之间需要通信。

流程如下:
主线程 :A 渲染线程:B
1.B 发送获取打印机列表的请求,
2.A 响应渲染线程的请求,获取到打印机列表过后发给 B
3.B 收到打印机列表过后进行数据处理选择一个打印机准备开始打印
4.B 把设计好的打印页面data 发送给 A 准备开始打印
5. A 收到打印请求过后 创建一个新的浏览器窗口,把 B 发过来的data渲染到打印窗口里面,开始打印 ,打印成功过后 关闭打印窗口。
整个过程就是这样。

特别注意

进程之间的通信监听的事件要区分on和once的使用,如在渲染进程中的函数
getPrint()startPrint() ,这两个函数会重复调用,函数里面的监听事件应该用once而不是on,因为每一次执行函数都会去挂载一个监听事件,使用on会一直挂载不会自动销毁,如果你调用了n次getPrint函数将会有n个同一种监听事件被挂载,按照常规的逻辑应该是一种监听事件应该只挂载一个才对。

主线程设计思路

在主线程中需要做的事情:
1.获取打印机列表
2.实例化一个新的浏览器窗口用于打印
3.打印结束过后需要关闭这个打印窗口

在主线程和渲染线程之间用ipcMain.on方法监听对方发出的事件

ipcMain.on('getPrinterList', () => {
  1  // 主线程获取打印机列表
    const list = mainWindow.webContents.getPrinters();
    // 通过webContents发送事件到渲染线程,同时将打印机列表也传过去
    mainWindow.webContents.send('allPrinterList', list);
  });
  ipcMain.on('printStart', (_event, obj) => {
  2  const printWindow = new BrowserWindow({ // 实例化一个新的浏览器窗口用于打印
      webPreferences: {
        nodeIntegration: true,
        webSecurity: false,
        enableRemoteModule: true
      },
      show: false,
      width: size.width,
      height: size.height,
      fullscreenable: true,
      minimizable: false
    });
    // 打印窗口添加html页面
    printWindow.loadURL(`data:text/html;charset=utf-8,${encodeURI(obj.html)}`);
    printWindow.webContents.once('did-finish-load', () => { // 等待页面加载完成过后再打印
      printWindow.webContents.print({
        silent: true, // 不显示打印对话框
        printBackground: true, // 是否打印背景图像
        deviceName: obj.deviceName
      }, (success: boolean, failureReason: string) => {
        mainWindow.webContents.send('res', { success, failureReason });
  3      printWindow.close();// 打印过后关闭该窗口
      });
    });
  });

渲染进程设计思路

1.通过获取打印机列表按钮发送一个请求到主线程获取打印机列表
2.把想要打印的内容发给主线程进行打印

import { ipcRenderer } from 'electron';

// 获取打印机列表
const printList = [];
const printWebview = useRef(null);  //获取dom节点
function getPrint() {
 1   ipcRenderer.send('getPrinterList');
    console.log('发送获取打印机列表事件');
    // 监听主线程发送打印机列表的事件
    ipcRenderer.once('allPrinterList', (event, data) => {
      printList = data;
      // console.log(data); // data就是返回的打印机数据列表
    });
  }
  
  // 打印程序
function startPrint(obj) { // obj 是打印机对象
    console.log(obj);
    const printStyle = '<style>@page{margin:0}</style>';
    const printData = {
      deviceName: obj[1].name, // 打印机名称
      html: printStyle + printWebview.current.innerHTML // 你需要打印的内容
    };
2    ipcRenderer.send('printStart', printData);
   // 监听主线程发送的打印结果的事件
    ipcRenderer.once('res', (_e, data) => {
      // console.warn(e);
      console.log('执行完打印程序', data);
    });
  }

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值