electron+vue3 客户端打印 - 掘金

说真的,刚接触electron,踩了不少的坑,不同版本的electron配置不一样的!!导致在百度过程中,参照他们的写法,往往没起作用,最后发现是版本不一致导致的!EXE安装包放在文章后面。

  1. 背景 项目中有需要用到打印标签这种功能,市面上能满足web端静默打印只有LODOP这个插件。在测试过程中,发现LODOP对兼容处理的不是很好,如果电脑的IE不是11版本(狗头,你可能会说现在谁还用IE,公司这边很多客户的电脑系统还停留在xp或win7上o(╥﹏╥)o),传的HTML给LODOP来打印,往往布局会错乱,对css的圆角属性没起作用,只能用svg代替;如果要做到兼容,可以把html先转成img,然后调用LODOP的ADD_PRINT_IMAGE方法,但是打印出来会失真,你可能会说可以先把图片放大再打印,这个是可以,但是会很大,打印很慢。然后看到了electron,也是用js编写,也可以获取到打印机,也可以静默打印,好像能满足这边的需求,入坑!!
  2. 代码片段 element-plus(1.0.2-beta.55)+ vue(3.0.0)+ ws(7.5.3) + electron(13.0.0) + electron-devtools-installer(3.1.0)

以上是我用到的版本,electron的版本最好对上,要不会碰到各种问题!!

为什么要用到ws?这里内容主要是用WebSocket来传输打印的,所以这里搭建了一个WebSocketServer;ws地址:ws://127.0.0.1:15978。 先看一下效果图:

image.png

image.png

image.png

09929f6ca44e45054f3b539f52bc3dc.jpg

electron很多坑就在入口文件配置这里,不同版本有点不一样的

首先创建窗口:

new BrowserWindow({
    width: 800,
    height: 600,
    icon: ".\\src\\assets\\img\\logo.png",
    autoHideMenuBar: true, //是否隐藏菜单栏
    webPreferences: {
            contextIsolation: false,
            nodeIntegration: true,
            webSecurity: false, // 取消跨域限制
            webviewTag: true, // 是否启用 <webview> tag标签
            enableRemoteModule: true,
    },
});
复制代码

第一个坑:icon参数,路径问题 看了网上一些教程,可以把ison配置在package.json里面,但是我这个版本怎么试都没有效果;如果放到BrowserWindow里面,没有双斜杆打包不会显示;这里的vue脚手架是用4点多版本搭建的,最后摸索出,可以把icon放到vue.config.js,打包之后果然生效:

pluginOptions: {
    electronBuilder: {
      builderOptions: {
        appId: 'electron-app',
        productName: 'huanggua',
        win: {
          icon: 'public/favicon.ico'
        },
        nsis: {
          oneClick: false, // 是否一键安装
          allowToChangeInstallationDirectory: true // 允许修改安装目录
        }
      }
    },
}
复制代码

第二个坑:页面是否能调用node的一些方法和electron方法,这里有两个个关键参数nodeIntegration和contextIsolation 这里如果nodeIntegration不设置为true,contextIsolation不设置为false,页面用window.require('electron')回发生报错,参考了文档,那时候这里搞了半天才弄好,也不算是坑吧,没怎么看文档。。。

第三个坑:enableRemoteModule参数,不同版本有差异

第四个坑:webview标签,首先要在主窗口把标签开启,这个标签里面要调用electron方法,还要在标签加上nodeintegration和contextIsolation参数,要不在主窗口加上都没用:

<webview style="height: 100%;" ref="printWebview" src="print.html" nodeintegration webpreferences="contextIsolation=false" />
复制代码

打印模块

1、获取打印机列表

background.js

ipcMain.on('getPrinterList', (event) => {
    //主线程获取打印机列表
    const list = browerWin.webContents.getPrinters();
    //通过webContents发送事件到渲染线程,同时将打印机列表也传过去
    browerWin.webContents.send('getPrinterList', list);
});
复制代码

print.vue

const getIpcRendererPrinter = () => {
        //渲染线程主动发送getPrinterList事件到主线程请求打印机列表
        ipcRenderer.send('getPrinterList');
        //监听主线程获取到打印机列表后的回调
        ipcRenderer.once('getPrinterList', (event, data) => {
                //data就是打印机列表
                console.log(data);
                printList.value = data || [];
                const localPrintName = localStorage.getItem('localPrintName');
                if (data && data.length && !localPrintName) {
                        leftForm.printer = data[0].displayName;
                        localStorage.setItem('localPrintName', data[0].displayName);
                }
                if (localPrintName) {
                        leftForm.printer = localPrintName;
                }
                console.log(leftForm);
                console.log(printList);
        });
}
复制代码

这里只要原理是把打印的内容HTML放到webview里面,然后调用打印

printWebview.value.print({
    //是否是静默打印
    silent: true,
    // printBackground: true,
    //打印机的名称,就是本文一开始获得的打印机列表其中一个
    deviceName: printer,
})
.then(data => {
    console.log('webview success', data);
    ipcRenderer.send('printSucces', true);
})
.catch(e => {
    console.log('webview error', e);
    ipcRenderer.send('printSucces', false);
});
复制代码
  1. 如何调用 首先安装软件,下载地址: pan.baidu.com/s/1IdM5OzqI… 提取码: 2p5q

页面调用: 安装软件完毕,打开软件

html,内容可以自定义

<div
  class="body-right-preview"
  :style="{
    width: canvasDesignConfig.width + canvasDesignConfig.unit,
    height: canvasDesignConfig.height + canvasDesignConfig.unit,
  }"
>
  <previewDesign
    :designConfig="canvasDesignConfig"
    :fillData="fillData"
    ref="printDesign"
  />
</div>
复制代码

js,链接WebSocket

const _this = this
const clientWebsock = new WebSocket(`ws://127.0.0.1:15978`);
clientWebsock.onmessage = function(e) {
console.log("接受消息:", e);
if (e && e.data && count > 0) {
  count = count - 1;
  _this.electronPrint("again");
}
};
clientWebsock.onclose = function(e) {
console.log("连接关闭", e);
};
clientWebsock.onopen = function() {
console.log("连接成功");
};
// 连接发生错误的回调方法
clientWebsock.onerror = function(e) {
console.log("连接错误", e);
};
this.clientWebsock = clientWebsock
复制代码

打印

const printDesignRef = this.$refs.printDesign;
const htmlContent = printDesignRef.$el.outerHTML
this.clientWebsock.send(htmlContent);
复制代码

注:该软件不做商业使用


原网址: 访问
创建于: 2023-08-09 19:07:38
目录: default
标签: 无

请先后发表评论
  • 最新评论
  • 总共0条评论