electron实现打印功能

2,259 阅读5分钟

electron实现打印功能

前不久公司中需要实现electron应用打印功能,做完后记录一下实现方式。

实现 electron 打印功能 ,基本的实现方法有:

附上electron入门文档 入门文档

贴上官网地址:官网地址

1,使用electron 中的 webContents.print方法实现

webContents.printElectron 提供的用于直接将网页内容发送到打印机进行打印的方法。它模拟浏览器的打印功能,支持打印页面的内容,包括文本、图像、表格等。

具体思路:渲染进程和主进程通信,使用 BrowserWindow 打开一个隐藏的窗口,窗口内容为需要打印的内容,然后使用 print 方法打印窗口中的内容。

例子:渲染进程中点击打印按钮,实现打印

1,渲染进程页面,点击按钮触发 Preload脚本暴露的方法

<template>
  <div>打印的内容</div>
  <button @click=print>打印</button>
</template>

<script>
  export default {
    data(){},
    methods:{
      print(){
        // 需要打印页面的路径
        const url = '../index.vue'
        window.ipcRenderer.print(url)
      }
    }
  }
</script>

2,Preload 预加载脚本,暴露方法到 window

const {contextBridge,ipcRenderer} = require('electron') 

contextBridge.exposeInMainWorld('ipcRenderer',{
    print(url){
        // 渲染进程给主进程发送⼀个消息
        ipcRenderer.send('print',url)
    }
})

3,主进程,接收到消息,触发事件

import { ipcMain, BrowserWindow } from 'electron'
  /**主窗体的win对象 */
  ipcMain.on('print', (e, url) => {
    // 创建一个新的隐藏窗口,用于打印
    let printWindow = new BrowserWindow({ 
      show: false, 
      width: 1920, 
      height: 1080, 
      frame: false, // 禁用窗口框架,移除菜单和标题栏
      contextIsolation: false,
      enableRemoteModule: true, 
      nodeIntegration: true, 
      webSecurity: false 
    })
    // 指定窗口加载的页面
    printWindow.loadFile(url);
    // 导航完成时触发,即选项卡的旋转器将停止旋转,并指派onload事件后。
    printWindow.webContents.on('did-finish-load', () => {
      // 进行打印
      printWindow.webContents.print();
      // 关闭窗口
      printWindow.close();
    })
  }) 

因为 print 是打印窗口的所有内容,所以打开窗口时配置show:false窗口不显示,frame: false 禁用窗口框架,移除菜单和标题栏

例子:打印时不想进行选择配置,直接静默打印

1,修改主进程的被触发的方法

import { ipcMain, BrowserWindow } from 'electron'
  /**主窗体的win对象 */
  ipcMain.on('print', (e, url) => async{
    // 创建一个新的隐藏窗口,用于打印
    let printWindow = new BrowserWindow({ 
      show: false, 
      width: 1920, 
      height: 1080, 
      frame: false, // 禁用窗口框架,移除菜单和标题栏
      contextIsolation: false,
      enableRemoteModule: true, 
      nodeIntegration: true, 
      webSecurity: false 
    })
    // 指定窗口加载的页面
    printWindow.loadFile(url);
    // 导航完成时触发,即选项卡的旋转器将停止旋转,并指派onload事件后。
    printWindow.webContents.on('did-finish-load', () => {
      // 获取打印机列表
      const list = await newWindow.webContents.getPrintersAsync()
      // 获取活跃打印机的名称
      const deviceName = list.find((err)=>err.isDefault).name
      // 进行打印
      // silent:true 静默打印
      // deviceName 指定打印机名称
      printWindow.webContents.print({ deviceName, silent: true });
      // 关闭窗口
      printWindow.close();
    })
  }) 

如果出现打印出来为空白页,可以将 printWindow.close() 放到 setTimeout 延迟执行试试,如果延迟后没问题,那就说明是打印页面加载慢导致的,可以将主进程的打印方法进行拆分为两个方法,一个打开新窗口,一个进行打印,然后分别在,点击打印按钮触发打开新窗口方法,打印页面加载完成触发打印方法。

2,使用electronwebviewwebview.print()方法实现

WebView是一个自定义元素 (<webview>),仅在 Electron 内工作。 它们以 "进程外 iframe" 实现。 这意味着所有与 <webview> 的通信都是异步使用 IPC 进行的。 <webview>元素有许多自定义方法和事件,类似于webContents,使您能够更多地控制内容。

与 <iframe><webview> 相比往往稍慢,但在加载和与第三方内容通信以及处理各种事件方面提供了更大的控制。

基本思路:在渲染进程中将需要打印的内容放到 webview中,然后使用 webview.print() 进行打印

<template>
    <webview id="myWebView" :src="printUrl" style="width: 100%; height: 100%"></webview>
    <button @click='print'> 打印 </button>
</template>

<script>
  export default {
    data(){},
    methods:{
      print(){
        const webview = document.querySelector('webview');
        webview.print();
      }
    }
  }
</script>

webview.print()可以直接在渲染进程中使用,无需与主进程通信。webview.print() 配置项与 webContents.print基本一直。

默认情况下,Electron >= 5禁用 webview 标签。 在构造 BrowserWindow 时,需要通过设置 webviewTag webPreferences选项来启用标签。

3,使用元素的 embed 元素实现

HTML <embed> 元素将外部内容嵌入文档中的指定位置。此内容由外部应用程序或其他交互式内容源(如浏览器插件)提供。

具体思路:将需要打印的内容转化为PDF,传入 embed 指定格式为 PDFembed展示PDF时自带打印按钮

<div style="height: 100vh;">
    <embed :src="url" width="100%" height="100%" type="application/pdf">
</div>

转化为 pdf 可使用 Electron自带的webContents.printToPDFhtml-pdf和其它的一些转化库

总结

方法优点缺点适用场景
webContents.print高度可定制,支持静默打印、高 DPI 配置仅适用于 Electron 的 BrowserWindow
,需确保页面加载完成
主进程控制打印,适合复杂打印需求
webview.print()简单易用,直接在渲染进程中调用依赖 webview
标签,打印功能较基础
渲染进程嵌入页面的简单打印
embed
元素
实现简单,适合加载并打印 PDF 文件打印行为不可控,结果可能与复杂页面的预期不符静态内容(PDF、HTML)打印,简单快速实现
  • 如果需要高度自定义的打印功能,推荐使用 webContents.print,尤其是在主进程中对打印行为进行精确控制的场景。
  • 如果需要嵌入外部页面或快速实现打印,使用 webview.print() 更为便捷。
  • 如果只是简单打印 PDF 或静态页面内容,利用 embed 元素是最轻量级的选择。

根据实际需求选择合适的方法,可以在不同场景中更高效地实现打印功能。

有问题欢迎指出!