前段時間,公司有個需求,要實現前端靜默(點擊按鈕直接打印,不須要預覽),本想着直接用window.print()來實現,讓用戶多點擊一下按鈕的事兒,無奈咱們的產品: css
最後只好繼續要網上繼續的遨遊找答案最後發現同事以前用過 clodop.js 來實現前端打印;一頓操做猛如虎以後發現打印出來會有水印,最終也是選擇放棄。html
偶然的機會在Electron文檔中找到了前端
webview.print({
silent Boolean (可選) - 不詢問用戶打印信息,默認爲 false。
})
就開始一頓操做如虎了
複製代碼
目錄結構vue
my-project
├─ .electron-vue
├── package-lock.json
├── package.json
├── src
│ ├── index.ejs
│ ├── main
│ │ ├── index.dev.js
│ │ ├── index.js
│ │ └── server.js
│ └── renderer
│ ├── App.vue
│ ├── components
│ ├── main.js
│ ├── router
│ ├── store
│ └── view
├── static
│ ├── PDFtoPrinter.exe //打印pdf插件
│ ├── config.txt
│ ├── icon.ico
│ ├── icon2.ico
│ ├── pdf
│ │ └── report.pdf //準備打印的pdf
│ └── print.html //準備打印的html
├── test
│ └── e2e
│ ├── index.js
│ ├── specs
│ └── utils.js
└── yarn.lock
複製代碼
動態html 打印node
<!-- print.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>Document</title>
<style>
body,
html {
padding: 0;
margin: 0;
font-size: 30px;
}
/*打印頁樣式*/
@page {
margin: 0px;
}
/*自定義打印樣式,能夠提早放入樣式,減小傳入內容*/
</style>
</head>
<body id="bd"></body>
<script>
const { ipcRenderer } = require('electron')
ipcRenderer.on('webview-print-render', (event, info) => {
// 執行渲染
document.getElementById('bd').innerHTML = info.html
ipcRenderer.sendToHost('webview-print-do')
})
</script>
</html>
複製代碼
<!-- print.vue-->
<template>
<div class="guide-print">
<button @click="print">打印</button>
<webview
id="printWebview"
ref="printWebview"
src="static/print.html"
nodeintegration
/>
</div>
</template>
<script>
import { ipcRenderer } from 'electron'
export default {
data() {
return {
printName:''
}
},
mounted() {
const webview = this.$refs.printWebview
webview.addEventListener('ipc-message', event => {
if (event.channel === 'webview-print-do') {
webview.print(
{
silent: true,
printBackground: true,
deviceName: this.printName
},
status => {
console.log('打印發送到打印機')
}
)
}
})
this.getPrintListHandle()
},
methods: {
print() {
const webview = this.$refs.printWebview
webview.send('webview-print-render', {
printName: this.printName,
html: "<p>我是打印內容</p>"
})
},
//獲取打印機
getPrintListHandle() {
ipcRenderer.send('getPrinterList')
ipcRenderer.once('getPrinterList', (event, data) => {
// 過濾可用打印機
this.printName = data.filter(e => e.isDefault)[0].name
})
}
}
}
</script>
<style lang="scss">
#printWebview {
height: 0;
width: 0;
visibility: hidden;
}
</style>
複製代碼
遠程&本地pdf打印git
安裝依賴 npm i node-pdf-printer
複製代碼
下載打印包 PDFtoPrinter.exegithub
//main.js 本地pdf文件打印
import NodePdfPrinter from 'node-pdf-printer'
let url1 = path.join(__static,'/pdf/test1.pdf')pipe(fs.createWriteStream(pdfPath))
let url2 = path.join(__static,'/pdf/test2.pdf')
NodePdfPrinter.printFiles([url1,url2,...],'你的打印機名字,不填/默認')
複製代碼
//main.js 遠程pdf文件打印
import NodePdfPrinter from 'node-pdf-printer'
import request from 'request'
let url ='http://mozilla.github.io/pdf.js/web/compressed.tracemonkey-pldi-09.pdf'
let pdfPath = path.join(
__static,
'pdf/' + url.slice(url.lastIndexOf('/')+1)
)
//下載遠程pdf資源到/static/pdf目錄
request(url, err => {
if(!err){
NodePdfPrinter.printFiles([pdfPath])
}
}).pipe(fs.createWriteStream(pdfPath))
複製代碼
若是批量下載多個pdf,能夠下載完全部pdf資源在執行NodePdfPrinter.printFiles進行批量打印,打印完成執行刪除本地pdf。web
function deleteDir(url) {
var files = []
if (fs.existsSync(url)) {
//判斷給定的路徑是否存在
files = fs.readdirSync(url) //返回文件和子目錄的數組
files.forEach(function(file, index) {
var curPath = path.join(url, file)
if (fs.statSync(curPath).isDirectory()) {
//同步讀取文件夾文件,若是是文件夾,則函數回調
deleteDir(curPath)
} else {
fs.unlinkSync(curPath) //是指定文件,則刪除
}
})
// fs.rmdirSync(url) //清除文件夾
} else {
console.log('給定的路徑不存在!')
}
}
複製代碼
打包static目錄的文件沒有打包進去
須要在package.json 裏面添加extraResources 額外資源npm
"win": {
"icon": "dist/electron/static/icon2.ico",
"extraResources": [
"./static/*.html",
"./static/*.txt",
"./static/*.exe",
"./static/pdf/*.pdf"
],
}
複製代碼
html打印偶爾遇到圖片沒有打印出來
緣由是document.getElementById('bd').innerHTML = info.html 以後就直接向print.vue通知打印,致使webview沒有徹底加載完成
做者找了很久,沒有找到合適的監聽,目前是在重定向資源的時候作短暫的延時,有知道的小夥伴謝謝分享🙏🙏json
遠程下載pdf沒法放入/static/pdf下
緣由是electron-vue 默認是用asar打包,而asar只能讀取不能寫入,因此須要遠程打印pdf就不能打包成asar
"win": {
"asar": false,
]
複製代碼
還有一些icon 設置、托盤右鍵菜單設置、縮小托盤、閃爍、氣泡提示的坑,就不在這裏贅述了,有問題能夠下方評論討論