打印 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
}