Electron 靜默打印


源碼

打印HTML格式

main進程中

const path = require('path')
const {BrowserWindow, app, ipcMain} = require('electron')

const isPrdEnv = process.env.NODE_ENV === 'production'
const staticPath = isPrdEnv ? './static' : '../../../../static' // 根據當前代碼的js相對static文件夾路徑

let printWindow = null
const url = `file://${path.resolve(__dirname, `${staticPath}/print.html`)}`

app.whenReady().then(() => {
    printWindow = new BrowserWindow({
        show: false,
        webPreferences: {
            nodeIntegration: true,
            contextIsolation: false
        }
    })
    printWindow.loadURL(url)
})

/**
 * 靜默打印html
 * @Param content Html字符串
 * @Param deviceName 打印機名稱
 * @return promise
 * */
const htmlToPrint = (content, deviceName, margin) => {
    return new Promise((resolve, reject) => {
        if (!printWindow) return reject('請等待控件加載完成后重試')
        const htmlPrintingListener = () => {
            printWindow.webContents.print({
                silent: true,
                printBackground: false,
                deviceName
            }, (success, failureReason) => {
                ipcMain.removeListener('htmlPrinting', htmlPrintingListener)
                if (success) resolve(true)
                else reject('打印失敗')
            })
        }

        printWindow.webContents.send('htmlPrint', { content, margin, deviceName })
        ipcMain.on('htmlPrinting', htmlPrintingListener)
    })
}


export default htmlToPrint

static文件夾下新建print.html鍵入以下代碼

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Document</title>
</head>

<body>
<div id='container'></div>
</body>
<script>
    //引入ipcRenderer對象
    const { ipcRenderer } = require('electron')
    ipcRenderer.on('htmlPrint', (e, content) => { //接收響應
        document.querySelector('#container').innerHTML = content
        ipcRenderer.send('htmlPrinting') //向webview所在頁面的進程傳達消息
    })
</script>
</html>

打印網絡PDF

打印本地PDF同理更簡單, 未作兼容性處理,詳細請看這篇文章,這里需要借助一個第三方軟件SumatraPDF 去官網下壓縮包解壓后放到static文件夾下就行

main進程中


const path = require('path')
const https = require('https')
const fs = require('fs')
const cp = require('child_process')

const isPrdEnv = process.env.NODE_ENV === 'production'
const staticPath = isPrdEnv ? './static' : '../../../../static' // 根據當前代碼的js相對static文件夾路徑

/*
* 處理await 的異常捕獲
* */
const awaitWrapper = promise => promise.then(result => [null, result]).catch(error => [error, null])

/*
* 生成隨機字符串
* */
const randomString = () => Math.random().toString(36).slice(-6)

/*
* 獲取網絡pdf的buffer
* */
const getFileBuffer = url => {
    return new Promise(((resolve, reject) => {
        https.get(url, response => {
            const chunks = []
            let size = 0
            response.on('data', chunk => {
                chunks.push(chunk)
                size += chunk.length
            })
            response.on('end', () => {
                const buffer = Buffer.concat(chunks, size)
                resolve(buffer)
            })
        })
    }))
}

/*
* 將buffer保存為本地臨時文件
* */
const savePdf = buffer => {
    return new Promise((resolve, reject) => {
        const pdfUrl = path.resolve(__dirname, `${staticPath}/${randomString()}.pdf`)
        fs.writeFile(pdfUrl, buffer, {encoding: 'utf8'}, err => {
            if (err) {
                reject('緩存pdf打印文件失敗')
            } else {
                resolve(pdfUrl)
            }
        })
    })
}

/*
* 調用SumatraPDF 執行pdf打印
* */
const executePrint = (pdfPath, deviceName) => {
    return new Promise((resolve, reject) => {
        cp.exec(`SumatraPDF.exe -print-to "${deviceName}"  "${pdfPath}"`,
            {
                windowsHide: true,
                cwd: path.resolve(__dirname, staticPath)
            },
            e => {
                if (e) {
                    reject(`${url}在${deviceName}上打印失敗`)
                } else {
                    resolve(true)
                }
                /* 打印完成后刪除創建的臨時文件 */
                fs.unlink(pdfPath, Function.prototype)
            })
    })
}

/*
* 靜默打印pdf
* */
const pdfToPrint = (url, deviceName) => {
    return new Promise(async (resolve, reject) => {
        /* 根據url獲取buffer並返回,如果獲取失敗就直接reject */
        const [bufferError, buffer] = await awaitWrapper(getFileBuffer(url))
        if (bufferError) return reject('獲取網絡pdf文件信息失敗')
        /* 根據buffer將文件緩存到本地並返回臨時pdf文件路徑,如果存儲失敗就直接reject */
        const [pdfPathError, pdfPath] = await awaitWrapper(savePdf(buffer))
        if (pdfPathError) return reject(pdfPathError)
        /* 根據臨時pdf文件路徑 和打印機名稱來執行打印*/
        const [execPrintError, printResult] = await awaitWrapper(executePrint(pdfPath, deviceName))
        if (execPrintError) {
            reject(execPrintError)
        } else {
            resolve(printResult)
        }
    })
}

關鍵事項

package.json中

1.打包static目錄的文件沒有打包進去,需要在package.json 里面添加extraResources 額外資源
2.打包后遠程下載pdf無法放入/static下,原因是electron-vue 默認是用asar打包,而asar只能讀取不能寫入,所以需要遠程打印pdf就不能打包成asar

   "win": {
         "icon": "dist/electron/static/icon2.ico",
         "extraResources": [
            "./static/*.html",
            "./static/*.txt",
            "./static/*.exe",
            "./static/*.pdf"
         ],
         "asar": false
    }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM