📜  在 ElectronJS 中打印

📅  最后修改于: 2022-05-13 01:56:29.422000             🧑  作者: Mango

在 ElectronJS 中打印

ElectronJS是一个开源框架,用于使用能够在 Windows、macOS 和 Linux 操作系统上运行的 HTML、CSS 和 JavaScript 等 Web 技术构建跨平台原生桌面应用程序。它将 Chromium 引擎和NodeJS组合成一个单一的运行时。

在某些桌面应用程序中,开发人员希望提供一种功能,使用户可以从应用程序内下载或打印内容。例如,在银行应用程序中,用户希望打印他/她的帐户对帐单,并显示在屏幕上。 Electron 除了将内容保存为 PDF 文件外,还提供了一种我们可以使用BrowserWindow对象和webContents属性直接打印内容的方法。 webContents属性为我们提供了某些实例事件和方法,我们可以通过它们打印正在显示的BrowserWindow实例的内容、打印远程 URL 的内容或从本地系统打印文件。本教程将演示如何在 Electron 中打印内容。

我们假设您熟悉上述链接中涵盖的先决条件。为了使 Electron 正常工作,需要在系统中预先安装nodenpm

  • 项目结构:
    项目结构

示例:我们将首先按照给定的步骤构建基本的电子应用程序。

  • 第 1 步:导航到空目录以设置项目,然后运行以下命令,
    npm init

    生成package.json文件。如果没有安装Electron ,请使用 npm 安装。

    npm install electron --save

    此命令还将创建package-lock.json文件并安装所需的node_modules依赖项。根据项目结构创建assets文件夹。
    包.json:

    {
      "name": "electron-print",
      "version": "1.0.0",
      "description": "Print Files in Electron ",
      "main": "main.js",
      "scripts": {
        "start": "electron ."
      },
      "keywords": [
        "electron"
      ],
      "author": "Radhesh Khanna",
      "license": "ISC",
      "dependencies": {
        "electron": "^8.2.5"
      }
    }
    
  • 第二步:根据项目结构创建一个main.js文件。该文件是主进程并充当应用程序的入口点。复制以下链接中给出的main.js文件的样板代码。我们已经修改了代码以满足我们的项目需求。

    主.js:

    const { app, BrowserWindow } = require('electron')
      
    function createWindow () {
      // Create the browser window.
      const win = new BrowserWindow({
        width: 800,
        height: 600,
        webPreferences: {
          nodeIntegration: true
        }
      })
      
      // Load the index.html of the app.
      win.loadFile('src/index.html')
      
      // Open the DevTools.
      win.webContents.openDevTools()
    }
      
    // This method will be called when Electron has finished
    // initialization and is ready to create browser windows.
    // Some APIs can only be used after this event occurs.
    // This method is equivalent to 'app.on('ready', function())'
    app.whenReady().then(createWindow)
      
    // Quit when all windows are closed.
    app.on('window-all-closed', () => {
      // On macOS it is common for applications and their menu bar
      // to stay active until the user quits explicitly with Cmd + Q
      if (process.platform !== 'darwin') {
        app.quit()
      }
    })
      
    app.on('activate', () => {
        // On macOS it's common to re-create a window in the 
        // app when the dock icon is clicked and there are no 
        // other windows open.
      if (BrowserWindow.getAllWindows().length === 0) {
        createWindow()
      }
    })
      
    // In this file, you can include the rest of your 
    // app's specific main process code. You can also 
    // put them in separate files and require them here.
    
  • 第三步:src目录下创建index.html文件和index.js文件。我们还将从上述链接复制index.html文件的样板代码。我们已经修改了代码以满足我们的项目需求。

    索引.html:

    
    
      
        
        Hello World!
        
        
      
      
        

    Hello World!

        We are using node      , Chrome      , and Electron      .                
  • 输出:此时,我们的基本电子应用程序已设置完毕。要启动 Electron 应用程序,请运行以下命令:
    npm start

    图形用户界面输出

在 Electron 中打印: BrowserWindow实例和webContents属性是Main Process的一部分。要在渲染器进程中导入和使用BrowserWindow ,我们将使用 Electron远程模块。有关远程模块的更多详细信息,请参阅此链接。

  • 方法一:打印当前活动的BrowserWindow实例的内容。

    webContents.print(options, callback)方法使用 Chromium 的预览打印设置打印BrowserWindow内容。该方法实现了一个回调函数。它接受以下参数。有关webContents.print()方法的更多详细信息,请参阅此链接。

    • options: Object (可选)它接受以下参数,
      • silent: Boolean (可选)如果此值设置为true ,应用程序将不会提示用户进行打印机设置和配置。它将采用对象中设置的值或默认打印机设置。默认值为false
      • printBackground: Boolean (可选)它接受网页的背景颜色和图像,如果有的话。默认值为false
      • deviceName: String (可选)设置要使用的打印机设备名称。必须是打印机驱动程序识别的系统定义名称。
      • color: Boolean (可选)设置打印页面是彩色还是灰度。默认值为true
      • Landscape: Boolean (可选)定义打印页面的模式。此值定义是否应以横向模式打印网页。默认值为false表示纵向模式。
      • scaleFactor:整数(可选)网页的比例因子。除非必要,否则不应更改此值。
      • pagesPerSheet:整数(可选)每个实际页面应打印的网页数。网页将在实际打印页面上以幻灯片的形式显示。
      • collate: Boolean (可选)定义是否应整理页面。默认值为false 。整理是指将网页排列成预定的顺序。 Collate 从多个不同的部分创建一致的逻辑集合。例如,按页码的顺序排列页面。
      • 份数:整数(可选)需要打印的文档集的份数。
      • duplexMode: String (可选)设置打印网页的双面模式。值可以是simplexshortEdgelongEdgeshortEdge定义您从纸张宽度(例如在传统记事本中)翻页。
      • header: String (可选)网页打印副本上的自定义标题。
      • footer: String (可选)网页打印副本上的自定义页脚。
      • dpi:对象(可选)它代表每英寸点数。它是打印页面密度的量度。它接受以下参数,
        • 水平:整数(可选)水平 dpi。
        • 垂直:整数(可选)垂直 dpi。
      • margins: Object (可选)它接受以下参数,
        • marginType: String (可选)值可以是defaultnoneprintableAreacustom 。如果选择自定义。我们还需要定义以下值,
        • top:整数(可选)像素为单位定义的上边距。
        • left:整数(可选)像素为单位定义的左边距。
        • 底部:整数(可选)像素为单位定义的底部边距。
        • right:整数(可选)像素为单位定义的右边距。

        所有这些值都是单个对象的一部分。

      静默属性设置为true时,如果未定义deviceName属性和默认系统设置进行打印,Electron 将选择系统的默认打印机。如果静默属性设置为false ,则 Electron 将打开一个对话框,显示所有默认系统打印机设置。可以从该自定义对话框调整和更改对象中定义的所有其他值。
      注意:要强制此方法打印到新页面,请使用page-break-before: always; CSS 中的属性。根据 Electron 的最新版本,在某些系统环境中存在一些与静默属性相关的错误。当静默属性设置为true时,它会在打印不同的文件(例如 PDF 文件)时导致一些问题。

    • 回调:函数(可选)它由两个值组成,
      • success: Boolean指示打印调用是否成功。
      • failureReason:如果打印调用不成功,则错误的字符串描述。

    要在Renderer Process中获取当前BrowserWindow实例,我们可以使用BrowserWindow对象提供的一些静态方法。

    • BrowserWindow.getAllWindows():此方法返回活动/打开的BrowserWindow实例的数组。在这个应用程序中,我们只有一个活动的 BrowserWindow实例,它可以直接从 Array 中引用,如代码所示。
    • BrowserWindow.getFocusedWindow():此方法返回在应用程序中聚焦的BrowserWindow实例。如果没有找到当前BrowserWindow实例,则返回null 。在这个应用程序中,我们只有一个活动的 BrowserWindow实例,可以直接使用该方法引用它,如代码所示。

    index.html :在该文件中添加以下代码段。



       

    index.js :在该文件中添加以下代码段。

    const electron = require('electron')
    // Importing BrowserWindow from Main
    const BrowserWindow = electron.remote.BrowserWindow;
      
    var current = document.getElementById('current'); 
    var options = {
        silent: false,
        printBackground: true,
        color: false,
        margin: {
            marginType: 'printableArea'
        },
        landscape: false,
        pagesPerSheet: 1,
        collate: false,
        copies: 1,
        header: 'Header of the Page',
        footer: 'Footer of the Page'
    }
      
    current.addEventListener('click', (event) => {
        let win = BrowserWindow.getFocusedWindow();
        // let win = BrowserWindow.getAllWindows()[0];
      
        win.webContents.print(options, (success, failureReason) => {
            if (!success) console.log(failureReason);
      
            console.log('Print Initiated');
        });
    });
    

    输出:

    可打印页面:
    打印页

  • 方法 2:通过在 BrowserWindow 实例中加载内容来打印远程 URL 或本地系统文件的内容。

    在这种情况下,我们创建了一个新的 BrowserWindow实例并将show属性设置为false 。因此,新创建的窗口将永远不会显示。我们使用win.loadURL(path)方法在BrowserWindow中加载外部 URL 的内容。 url路径可以是http://协议指定的远程地址,也可以是file://协议指定的本地系统中文件的路径。此方法返回一个Promise ,并在页面完成加载并且 webContents 属性的did-finish-load事件为Emitted时解决。有关更多详细信息,请参阅此链接。

    did-finish-load实例事件属于webContents属性。它在导航完成并且页面完全加载时发出。当页面的微调器停止旋转并且onload事件已被调度时,就会发生这种情况。如果未使用此事件发射器并且调用了webContents.print()方法,则打印的页面将是一个空白文档,因为内容没有在BrowserWindow中完成加载。

    index.html :在该文件中添加以下代码段。



      

    index.js :在该文件中添加以下代码段。

    const electron = require('electron')
    // Importing BrowserWindow from Main
    const BrowserWindow = electron.remote.BrowserWindow;
      
    var url = document.getElementById('url');
    var options = {
        silent: false,
        printBackground: true,
        color: false,
        margin: {
            marginType: 'printableArea'
        },
        landscape: false,
        pagesPerSheet: 1,
        collate: false,
        copies: 1,
        header: 'Header of the Page',
        footer: 'Footer of the Page'
    }
      
    url.addEventListener('click', (event) => {
        // Defining a new BrowserWindow Instance
        let win = new BrowserWindow({
            show: false,
            webPreferences: {
                nodeIntegration: true
            }
        });
        win.loadURL('https://www.google.com/');
      
        win.webContents.on('did-finish-load', () => {
            win.webContents.print(options, (success, failureReason) => {
                if (!success) console.log(failureReason);
                console.log('Print Initiated');
            });
        });
    });
    

    输出:
    打印页