Appearance
静默打印
有两种实现打印的方式,一是electron提供的api,另一个是node实现打印
electron自带api打印
electron打印其实就是打印当前页面
js
ipcMain.on('fromRender', (_, params) => {
switch (params.event) {
case 'print': // 接收到来自渲染进程的打印指令
// print参数是可选的,silent:是否静默打印,copies:打印份数
mainWindow.webContents.print({silent:true,copies:1 },(success,failureReason)=>{
if(success){
console.log('打印成功')
}else{
console.log('打印失败',failureReason)
}
})
break
}
})
在实际项目中需要进行小票打印,我的做法是打开一个新窗口,然后将要打印的内容渲染到这个窗口内,然后打印这个窗口。创建打印窗口是非常耗资源的,所以要避免一直创建销毁。比如在登录成功的时候创建、退出登录的时候销毁。
print.js
js
import { BrowserWindow, app } from 'electron'
import path, { dirname } from 'path'
import { fileURLToPath } from 'url'
const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)
let printWin
const otherWindowConfig = {
height: 595,
useContentSize: true,
width: 800,
autoHideMenuBar: false,
minWidth: 100,
show: true, // 是否显示窗口,调试的时候可以设置为true,生产false
webPreferences: {
// contextIsolation: true,
nodeIntegration: true,
}
}
function closePrintWindow() {
if (printWin) {
printWin.destroy()
printWin = null
}
}
function initPrintWindow() {
if (printWin) {
// win.hide() /* 测试*/
printWin.destroy()
}
printWin = new BrowserWindow({
...Object.assign(otherWindowConfig, {})
})
console.log('initPrintWindow',printURLCustom());
printWin.loadURL(printURLCustom())
printWin.setMenu(null)
printWin.on('closed', () => {
printWin = null
})
}
function executePrint(option) {
// 这里可以通过进程通信将要打印的数据发送到打印页面
// 打印页面接收到数据后,再发送打印指令到当前进程
// 这里只是简单示例,直接调用打印
printWin.webContents.print(option,(success,failureReason)=>{
if(success){
console.log('打印成功')
}else{
console.log('打印失败',failureReason)
}
})
}
function getUrl(devPath, proPath, hash) {
const url = app.isPackaged ? new URL('file://') : new URL(`http://localhost:8100/`)
url.pathname = app.isPackaged ? proPath : devPath
url.hash = hash
return url.href
}
const printURLCustom = () => {
const url = getUrl('', path.join(__dirname, '..', 'dist', 'index.html'), `#/print`)
return url
}
export {
initPrintWindow, executePrint, closePrintWindow
}
在主进程index.js中调导出的打印相关方法
js
import { initPrintWindow, executePrint } from './print.js'
// 页面加载完成初始打印窗口
mainWindow.webContents.on('did-finish-load', () => {
// ……
initPrintWindow()
});
// 接收渲染进程的指令
ipcMain.on('fromRender', (_, params) => {
switch (params.event) {
case 'update':
console.log('接收到渲染进程的更新信息', params.args);
break
case 'print':
// print参数是可选的,silent:是否静默打印,copies:打印份数
mainWindow.webContents.print({silent:false,copies:1 },(success,failureReason)=>{
if(success){
console.log('打印成功')
}else{
console.log('打印失败',failureReason)
}
})
break
case 'printReceipt':
// 小票打印
// params.args:
executePrint(params.args)
break
}
})
渲染进程发送打印指令
tsx
const handlePrintReceipt = () => {
if (!isElectron()) return
const option = {
copies: 1,
printerName: '打印机名称',
landscape: false,
margins: { marginType: 'none' },
// dpi: { horizontal: 300, vertical: 300 }
// pageRanges: [{ from: 0, to: 0 }]
// pageSize: { width: 80000, height: 100000 }
}
window.mainAPI.sendToMain({ 'event': 'printReceipt', args: { option}})
}
node实现打印
在node环境中直接发送打印指令到打印机实现打印,和electron框架无关,这也意味着只要支持node环境就可实现打印
示例
js
const { ThermalPrinter, PrinterTypes, CharacterSet, BreakLine } = require('node-thermal-printer');
async function example() {
const printer = new ThermalPrinter({
type: PrinterTypes.EPSON, // 'star' or 'epson'
// interface: 'printer:auto',// 试了,没用
// interface: '//192.168.0.97/GP-L80160 Series 58',
// interface: '//192.168.0.97/XP-80C', // 试了,没用
interface: 'tcp://192.168.0.61:9100', // 打印机的ip
// driver:{},
// options: {
// timeout: 1000,
// },
width: 48, // Number of characters in one line - default: 48
characterSet: CharacterSet.CHINA, // Character set - default: SLOVENIA
breakLine: BreakLine.WORD, // Break line after WORD or CHARACTERS. Disabled with NONE - default: WORD
removeSpecialCharacters: false, // Removes special characters - default: false
lineCharacter: '-', // Use custom character for drawing lines - default: -
});
// printer.alignCenter()
// printer.setTextDoubleWidth()
// await printer.printImage('./img.png'); // 打印图片过大时可能乱码
// printer.setTypeFontB();
// printer.println('Type font B');
// printer.setTypeFontA();
// printer.setTextSize(4, 4);
// printer.println('Type font A');
// printer.println('中文字体啊啊啊啊啊啊啊啊啊发光飞碟更好地给很过分好的');
// printer.printQR('123456',{
// cellSize: 8, // 最大值是8
// correction: 'L',
// model: 20
// })
// printer.cut();
// try {
// await printer.execute();
// console.log('Print success.');
// } catch (error) {
// console.error('Print error:', error);
// }
}
example()