需求: 支持无感打印pdf文件, 支持mac, win两个终端
说明: 一般打印机不支持直接打印word文件, 而电脑上的在word文档中打印其实也是内部转成了pdf才能打印的, 所以如果你的需求要支持打印word, 可以让后端作为中间人, 先把word转化为pdf, 再打印
在网上看了很多相关的经验, 都是找的第三方的工具, 例如SumatraPDF, 但是这个工具不支持mac端, 直接pass, 有的是直接在页面上打开pdf, 从而打印web页面, 如果pdf文件一旦过大, 就没办法打印全部了, 隐患太大
方案: 通过pdf.js在print.html预览, 监听渲染完成后实现静默打印
// main.js
// 打印方法
function printHandle ({ BrowserWindow, arg, socket, printInfo, urlData, mainWindow }) {
const printWin = new BrowserWindow({
webPreferences: {
//关闭web权限检查,允许跨域
webSecurity: false,
// 是否启用Node 环境
nodeIntegration: true,
enableRemoteModule: true,
contextIsolation: false,
plugins: true,
images: true,
allowRunningInsecureContent: true,
webviewTag: true,
navigateOnDragDrop: true,
zoomFactor: 1.0
},
minWidth: 1580,
minHeight: 720,
backgroundColor: '#f5f5f5',
frame: false,
show: false
})
// 因为拿到的是文件服务上的地址, 所以先获取pdf二进制内容
require('http').get('文件服务上的远程pdf地址', { encoding: null }, res => {
let img = []
let size = 0
res.on('data', chunk => {
img.push(chunk)
size += chunk.length
})
res.on('end', () => {
const buffer = Buffer.concat(img, size)
// 获取到内容啦, 写文件
fs.writeFile(path.join(app.getPath('userData'), 'print.pdf'), buffer, function (err) {
// 如果err为true,则文件写入失败,并返回失败信息
if (err) {
return socket.emit('print-succ', { code: 1000, message: '打印失败, 请重试', data: err })
}
// 只触发一次的事件
// 监听print.html页面渲染pdf完成事件
ipcMain.once('getLandscape', (winEvent, bool, pageNum) => {
printInfo.landscape = bool
console.log(pageNum, bool)
printWin.webContents.print(
{
silent: true, // 是否不向用户询问设置
printBackground: false, // 打印网页的背景颜色和图像
deviceName: electronStore.get('printName'), // 打印设备的名称
pageSize: 'A4',
landscape: printInfo.landscape, // 是否横向打印
margins: {
marginType: 'printableArea' // 可打印区域
}
},
(success, failureReason) => {
const result = {
code: success ? 0 : 1000,
message: !failureReason ? '已将数据发送给打印机, 请关注打印机状态。' : '打印失败'
}
socket.emit('print-succ', result)
fs.unlinkSync(path.join(app.getPath('userData'), 'print.pdf'))
printWin.destroy() // 打印完成后终止程序
}
)
})
// 暂时解决打印程序卡死问题
setTimeout(() => {
if (printInfo.isPrint == true) {
printInfo.isPrint = false
if (printWin) printWin.destroy()
socket.emit('print-succ', { code: 1000, message: '打印超时! 请关注打印机状态' })
}
}, 25000)
// 加载静态文件中的print页面
printWin.loadURL(path.join(`${__static}`, 'print.html'))
})
})
})
}
Document