使用Electron 静默打印

本文项目基于 electron-vue
思路:在主线程单独开出一个打印的窗口(可以将该窗口隐藏),通过window的webcontent对象进行打印
项目地址

1. 主进程文件 main/index.js

'use strict'

import path from 'path'
import { app, BrowserWindow, ipcMain, Menu } from 'electron'
const electron = require('electron')
/**
 * Set `__static` path to static files in production
 * https://simulatedgreg.gitbooks.io/electron-vue/content/en/using-static-assets.html
 */
if (process.env.NODE_ENV !== 'development') {
  global.__static = require('path').join(__dirname, '/static').replace(/\\/g, '\\\\')
}

let mainWindow
const winURL = process.env.NODE_ENV === 'development'
  ? `http://localhost:9081`
  : `file://${__dirname}/index.html`

function createWindow () {
  /**
   * Initial window options
   */
  mainWindow = new BrowserWindow({
    useContentSize: true,
    width: 1200,
    height: 768,
    minWidth: 1200,
    minHeight: 675,
    show: true,
    center: true,
    webPreferences: {
      webSecurity: false
    }
  })
  // 隐藏菜单栏
  Menu.setApplicationMenu(null)
  mainWindow.loadURL(winURL)
  mainWindow.on('closed', () => {
    mainWindow = null
    if (printWindow) {
      printWindow.close()
    }
  })
  createPrintWindow()
}

app.on('ready', createWindow)

app.on('will-quit', function () {
  electron.globalShortcut.unregisterAll()
})

app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit()
  }
})

app.on('activate', () => {
  if (mainWindow === null) {
    createWindow()
  }
})
// 创建打印窗体
let printWindow
function createPrintWindow() {
  printWindow = new BrowserWindow({
    show: true,
    width: 800,
    height: 600,
    webPreferences: {
      nodeIntegration: true
    }
  })
  const fileUrl = path.join(__static, 'printer.html')
  printWindow.loadFile(fileUrl)
  initPrinters()
}
// 打印窗体事件
function initPrinters() {
  // 获取打印机列表
  ipcMain.on('get-printers', (event, data) => {
    const printers = printWindow.webContents.getPrinters()
    mainWindow.webContents.send('get-printers', printers)
  })
  // 获取渲染进程传递过来的打印指令
  ipcMain.on('do-print', (event, data) => {
    const list = mainWindow.webContents.getPrinters()
    const defaultPrinter = list.find(x => x.status === 0 && x.isDefault)
    const dataResult = {
      html: data.html,
      deviceName: data.printerName || defaultPrinter.name
    }
    // 发送指令到printer.html
    printWindow.webContents.send('render-print', dataResult)
  })
  // 从printer.html传递过来的指令
  ipcMain.on('print-do', (e, data) => {
    printWindow.webContents.print({
      silent: true,
      printBackground: false,
      deviceName: data
    })
  })
}

2. static文件下新建printer.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>打印</title>
</head>
<style>
  @page{
    padding: 0;
    margin: 0px 16px 0px 0px;
  }
  @media print {
    body {
      font-size: 10px;
    }
  }
  *{
    padding: 0;
    margin: 0;
  }
  .flex {
    display: flex;
  }
  .flex-center {
    display: flex;
    justify-content: center;
    align-items: center;
  }
  .flex-between {
    display: flex;
    justify-content: space-between;
  }
</style>
<body>
</body>
<script>
  const { ipcRenderer } = require('electron')
  // 监听从主进程打印窗体webContents传递过来的打印事件
  ipcRenderer.on('render-print', (event, info) => {
    document.body.innerHTML = info.html
    // 页面html渲染后发送事件到主进程
    ipcRenderer.send('print-do', info.deviceName)
  })
</script>
</html>

3. vue页面中使用

<template>
  <div>
    <el-form>
      <el-form-item label="打印机列表">
        <el-select v-model="selectedPrinterName">
          <el-option
            v-for="item of printerList"
            :key="item.name"
            :value="item.name"
            :title="item.name"
          >
          </el-option>
        </el-select>
        <el-button @click="print">打印</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>
<script>
import { ipcRenderer } from 'electron'
export default {
  data() {
    return {
      printerList: [],
      selectedPrinterName: ''
    }
  },
  mounted() {
    this.getPrinters()
    ipcRenderer.on('get-printers', (event, list) => {
      console.log('list', list)
      this.printerList = list
    })
  },
  methods: {
    getPrinters() {
      ipcRenderer.send('get-printers')
    },
    async print() {
      const tempalteHtml = '<div style="height: 20px; width: 100%;">测试打印</div>'
      ipcRenderer.send('do-print', {
        printerName: this.selectedPrinterName,
        html: tempalteHtml
      })
    }
  }
}
</script>
``
上一篇:卸载 Navicat!事实已证明,正版客户端,它更牛逼……


下一篇:datagrip增加elasticsearch连接driver