1. 首页
  2. 前端基础

用JS开发桌面应用(三)打印篇

九、打印

很多情况下程序中使用的打印都是用户无感知的。并且想要灵活的控制打印内容,往往需要借助打印机给我们提供的api再进行开发,这种开发方式非常繁琐,并且开发难度较大。第一次在业务中用到Electron其实就是用到它的打印功能,这里就多介绍一些。

Electron提供的打印api可以非常灵活的控制打印设置的显示,并且可以通过html来书写打印内容。Electron提供了两种方式进行打印,一种是直接调用打印机打印,一种是打印到pdf

并且有两种对象可以调用打印:

  • 通过windowwebcontent对象,使用此种方式需要单独开出一个打印的窗口,可以将该窗口隐藏,但是通信调用相对复杂。
  • 使用页面的webview元素调用打印,可以将webview隐藏在调用的页面中,通信方式比较简单。

上面两种方式同时拥有printprintToPdf方法。

用JS开发桌面应用(三)打印篇

9.1 调用系统打印

contents.print([options], [callback]);

打印配置(options)中只有简单的三个配置:

  • silent:打印时是否不展示打印配置(是否静默打印)
  • printBackground:是否打印背景
  • deviceName:打印机设备名称

首先要将我们使用的打印机名称配置好,并且要在调用打印前首先要判断打印机是否可用。

使用webContentsgetPrinters方法可获取当前设备已经配置的打印机列表,注意配置过不是可用,只是在此设备上安装过驱动。

通过getPrinters获取到的打印机对象:https://electronjs.org/docs/api/structures/printer-info

我们这里只管关心两个,namestatusstatus0时表示打印机可用。

print的第二个参数callback是用于判断打印任务是否发出的回调,而不是打印任务完成后的回调。所以一般打印任务发出,回调函数即会调用并返回参数true。这个回调并不能判断打印是否真的成功了。

    if (this.state.curretnPrinter) {
      mainWindow.webContents.print({
        silent: silent, printBackground: true, deviceName: this.state.curretnPrinter
      }, () => { })
    } else {
      remote.dialog.showErrorBox('错误', '请先选择一个打印机!')
    }

9.2 打印到PDF

printToPdf的用法基本和print相同,但是print的配置项非常少,而printToPdf则扩展了很多属性。这里翻了一下源码发现还有很多没有被贴进api的,大概有三十几个包括可以对打印的margin,打印页眉页脚等进行配置。

contents.printToPDF(options, callback)

callback函数在打印失败或打印成功后调用,可获取打印失败信息或包含PDF数据的缓冲区。

    const pdfPath = path.join(os.tmpdir(), 'webviewPrint.pdf');
    const webview = document.getElementById('printWebview');
    const renderHtml = '我是被临时插入webview的内容...';
    webview.executeJavaScript('document.documentElement.innerHTML =`' + renderHtml + '`;');
    webview.printToPDF({}, (err, data) => {
      console.log(err, data);
      fs.writeFile(pdfPath, data, (error) => {
        if (error) throw error
        shell.openExternal(`file://${pdfPath}`)
        this.setState({ webviewPdfPath: pdfPath })
      });
    });

这个例子中的打印是使用webview完成的,通过调用executeJavaScript方法可动态向webview插入打印内容。

9.3 两种打印方案的选择

上面提到,使用webviewwebcontent都可以调用打印功能,使用webcontent打印,首先要有一个打印窗口,这个窗口不能随时打印随时创建,比较耗费性能。可以将它在程序运行时启动好,并做好事件监听。

此过程需和调用打印的进行做好通信,大致过程如下:

用JS开发桌面应用(三)打印篇

可见通信非常繁琐,使用webview进行打印可实现同样的效果但是通信方式会变得简单,因为渲染进程和webview通信不需要经过主进程,通过如下方式即可:

  const webview = document.querySelector('webview')
  webview.addEventListener('ipc-message', (event) => {
    console.log(event.channel)
  })
  webview.send('ping');

  const {ipcRenderer} = require('electron')
  ipcRenderer.on('ping', () => {
    ipcRenderer.sendToHost('pong')
  })

之前专门为ELectron打印写过一个DEMOelectron-print-demo有兴趣可以clone下来看一下。

9.4 打印功能封装

下面是几个针对常用打印功能的工具函数封装。

/**
 * 获取系统打印机列表
 */
export function getPrinters() {
  let printers = [];
  try {
    const contents = remote.getCurrentWindow().webContents;
    printers = contents.getPrinters();
  } catch (e) {
    console.error('getPrintersError', e);
  }
  return printers;
}
/**
 * 获取系统默认打印机
 */
export function getDefaultPrinter() {
  return getPrinters().find(element => element.isDefault);
}
/**
 * 检测是否安装了某个打印驱动
 */
export function checkDriver(driverMame) {
  return getPrinters().find(element => (element.options["printer-make-and-model"] || '').includes(driverMame));
}
/**
 * 根据打印机名称获取打印机对象
 */
export function getPrinterByName(name) {
  return getPrinters().find(element => element.name === name);
}

小结

希望你阅读本篇文章后可以达到以下几点:

  • 了解Electron的基本运行原理
  • 掌握Electron开发的核心基础知识
  • 了解Electron关于弹框、打印、保护、打包等功能的基本使用

系列目录:

  1. 用JS开发桌面应用(一)原理篇
  2. 用JS开发桌面应用(二)基本应用
  3. 用JS开发桌面应用(三)打印篇
  4. 用JS开发桌面应用(四)程序保护
  5. 用JS开发桌面应用(五)终篇

文中如有错误,欢迎在评论区指正,如果这篇文章帮助到了你,欢迎点赞和关注。

链接:https://github.com/ConardLi/ConardLi.github.io

看完两件小事

如果你觉得这篇文章对你挺有启发,我想请你帮我两个小忙:

  1. 关注我们的 GitHub 博客,让我们成为长期关系
  2. 把这篇文章分享给你的朋友 / 交流群,让更多的人看到,一起进步,一起成长!
  3. 关注公众号 「IT平头哥联盟」,公众号后台回复「资源」 免费领取我精心整理的前端进阶资源教程

JS中文网是中国领先的新一代开发者社区和专业的技术媒体,一个帮助开发者成长的社区,目前已经覆盖和服务了超过 300 万开发者,你每天都可以在这里找到技术世界的头条内容。欢迎热爱技术的你一起加入交流与学习,JS中文网的使命是帮助开发者用代码改变世界

本文著作权归作者所有,如若转载,请注明出处

转载请注明:文章转载自「 Js中文网 · 前端进阶资源教程 」https://www.javascriptc.com

标题:用JS开发桌面应用(三)打印篇

链接:https://www.javascriptc.com/3251.html

« 用JS开发桌面应用(二)基本应用
用JS开发桌面应用(一)原理篇»

相关推荐

QR code