背景
使用 electron 静默打印二维码。
框架
- electron-forge
- webpack
- TypeScript
一、使用electron-pos-printer(不推荐)
准备
- @electron/remote
- electron-pos-printer
安装
npm install @electron/remote --save
npm install electron-pos-printer --save
效果如下:
"dependencies": {
...
"@electron/remote": "^2.0.8",
"electron-pos-printer": "^1.2.4",
}
操作
1. index.ts 页面修改
import { app, BrowserWindow, ipcMain } from 'electron';
import * as _electronRemote from '@electron/remote/main';
...
const createWindow = (): void => {
...
_electronRemote.initialize();
_electronRemote.enable(mainWindow.webContents);
...
//获得打印机列表
ipcMain.on('allPrinters', async (event) => {
const printers = await mainWindow.webContents.getPrintersAsync();
event.sender.send('printers', printers);
});
};
2. preload.ts 页面修改
import { ipcRenderer, contextBridge, PrinterInfo } from 'electron';
import { toPrint } from './lib/print'
let printers:PrinterInfo[] = [];
ipcRenderer.send('allPrinters');
ipcRenderer.on('printers', (event, _printers) => {
printers = _printers;
});
function print (value: string, printerName?:string): void {
toPrint(value, printers.some((printer)=>{return printer.name==printerName}) ? printerName : '');
}
contextBridge.exposeInMainWorld('electronAPI', {
print: print
});
3. lib/print.ts 页面修改
// 打印
import { PosPrintData, PosPrintOptions } from 'electron-pos-printer';
import * as remote from '@electron/remote';
const { PosPrinter } = remote.require("electron-pos-printer");
let printOptions: PosPrintOptions = {
preview: false, // 打印预览
width: '90px', // 宽度
margin: '0 0 0 0', // 外边距
printerName: '', // 打印机名称
timeOutPerLine: 400, //超时时间
pageSize: { height: 301000, width: 71000 } // 页面大小
}
/**
* 去打印
* value:二维码数据
*/
function toPrint (value: string, printerName: string) {
const silent = !!printerName;
const data: PosPrintData[] = [
{
type: 'qrCode',
value,
height: '90',
width: '90',
displayValue: true,
style: `margin-left:20px;`,
}
];
printOptions = { ...printOptions, printerName, silent }
PosPrinter.print(data, printOptions)
.then(() => {
console.log('打印成功');
})
.catch((error: any) => {
console.error('打印错误', error);
})
}
export { toPrint }
4. window.d.ts 页面修改
增加全局变量
export interface IElectronAPI {
getPrint?: function,
}
declare global {
interface Window {
electronAPI: IElectronAPI
}
}
5. electron-pos-printer bug 修改
以上的代码写完了后发现点击打印TimedOut,在node_modules/electron-pos-printer/pos-printer.js的91行修改代码如下:
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
}
6.总结
以上方法完成打印,但是remote已经被electron遗弃,electron-pos-printer还有已知的bug,所以不推荐大家使用。下面介绍我总结的方法。
二、使用webContents.print
思想
创建一个打印窗口,打印完后关掉。
1. index.ts 修改
// 打印
ipcMain.on('toPrint', (event, url, printerName) => {
const printWindow = new BrowserWindow({
height: 10,
width: 10,
webPreferences: {
preload: MAIN_WINDOW_PRELOAD_WEBPACK_ENTRY,
nodeIntegration: true, // 允许浏览器环境使用Node API
},
});
printWindow.loadURL(`${EDC_URL}${url}`);
printWindow.once('ready-to-show', () => {
printWindow.webContents.print({
silent: true,
deviceName: printerName
}, (success, errorType) => {
if (!success) console.log(errorType);
printWindow.close();
});
});
});
2. preload.ts 修改
import { ipcRenderer, contextBridge, PrinterInfo } from 'electron';
let printers:PrinterInfo[] = [];
ipcRenderer.send('allPrinters');
ipcRenderer.on('printers', (event, _printers) => {
printers = _printers;
});
function print (url: string, printerName?:string): void {
ipcRenderer.send('toPrint', url, printers.some((printer)=>{return printer.name==printerName}) ? printerName : '');
}
contextBridge.exposeInMainWorld('electronAPI', {
print: print
});