本文项目基于 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>
``