最近接到的需求中有在electron中實(shí)現(xiàn)打印pdf文件的功能先慷。從網(wǎng)上找了很多第三方工具骡男,基本上是在頁(yè)面中打開pdf,然后打印web頁(yè)面恃锉。這固然可以實(shí)現(xiàn)打印功能,但是打印的實(shí)際上只是個(gè)web頁(yè)面呕臂,而非真正的pdf源文件破托。
該方法實(shí)際上是通過(guò)node執(zhí)行命令來(lái)調(diào)用SumatraPDF從而打印pdf文件,所以我們需要把SumatraPDF目錄直接放在項(xiàng)目static(vue-cli3為public)目錄下
完整需求為通過(guò)接口獲取pdf文件流歧蒋,打印pdf土砂。(這里只講了打印pdf部分)
完整思路如下:
1.渲染進(jìn)程調(diào)接口獲取pdf文件流
import QS from 'qs'
const download = (url, query, cb, type) => {
var xhr = new XMLHttpRequest()
xhr.open(
"GET",
`${axios.defaults.baseURL}${url}?${QS.stringify(query)}`,
true
)
xhr.responseType = "blob"
xhr.setRequestHeader("Access-Token", sessionStorage.getItem("token"))
xhr.onload = function() {
if (this.status == 200) {
var blob = new Blob([this.response], {
type: "application/pdf;charset=utf-8",
})
//生成URL
let href = window.URL.createObjectURL(blob)
if (cb) {
// 有回調(diào),根據(jù)type在回調(diào)中傳入blob對(duì)象或url
if (type == "blob") {
cb(blob)
} else {
cb(href)
}
} else {
// 無(wú)回調(diào)谜洽,直接導(dǎo)出下載
let link = document.createElement("a")
link.download = "波形.pdf"
link.href = href
link.click()
}
}
}
xhr.send()
}
const printReport = (p, cb, type = "url") => download(`report/worklist/print`, p, cb, type)
2.將pdf文件流轉(zhuǎn)為Buffer格式(先轉(zhuǎn)為blob對(duì)象萝映,然后通過(guò)FileReader轉(zhuǎn)為Buffer)
exportReport(
{},
(blob) => {
let self = this
let reader = new FileReader()
reader.readAsDataURL(blob)
reader.addEventListener('loadend', () => {
// 通知主進(jìn)程打印
ipc.send('printPDF', {
baseCode: Buffer.from(reader.result.split('base64,')[1], 'base64'),
})
})
},
'blob'
)
3.渲染進(jìn)程與主進(jìn)程通信,發(fā)送Buffer到主進(jìn)程阐虚。主進(jìn)程通過(guò)fs模塊將pdf保存到本地序臂,通過(guò)child_process執(zhí)行SumatraPDF打印命令,完成打印
const cp = require('child_process');
const path = require("path");
const fs = require('fs');
const { app, ipcMain: ipc } = require("electron");
ipc.on('printPDF', (e, arg) => {
const writeFile = () => {
fs.writeFile('./data/waveform.pdf', arg.baseCode, { encoding: 'utf8' }, err => {
// 失敗
if (err) {
// 向渲染進(jìn)程發(fā)送消息通知失敗
e.reply('defeatedDialog', err)
} else {
let pdfUrl = path.join(app.getAppPath(), process.env.NODE_ENV === 'development' ? '../data/waveform.pdf' : '../../data/waveform.pdf')
switch (process.platform) {
case 'darwin':
case 'linux':
cp.exec(
`SumatraPDF.exe -print-to-default "${pdfUrl}"`,
{
windowsHide: true,
cwd: path.join(app.getAppPath(), process.env.NODE_ENV === 'development' ? '../static/SumatraPDF' : './app/static/SumatraPDF'),
},
e => {
if (e) {
throw e
}
}
)
break
case 'win32':
cp.exec(
`SumatraPDF.exe -print-to-default "${pdfUrl}"`,
{
windowsHide: true,
cwd: path.join(app.getAppPath(), process.env.NODE_ENV === 'development' ? '../static/SumatraPDF' : './app/static/SumatraPDF'),
},
e => {
fs.unlink(pdfUrl, e => {})
if (e) {
throw e
}
}
)
break
default:
throw new Error('Platform not supported.')
}
}
})
}
if (fs.existsSync('./data')) {
writeFile()
} else {
fs.mkdir('./data', { recursive: true }, err => {
if (err) {
throw err
} else {
writeFile()
}
})
}
})
代碼給大家貼出來(lái)了实束,有問(wèn)題或有改進(jìn)建議的小伙伴可以留言奥秆,我看到后會(huì)回復(fù)大家
附SumatraPDF文檔:https://www.sumatrapdfreader.org/docs/Command-line-arguments.html