最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

electron實現(xiàn)打印功能支持靜默打印、無感打印

 更新時間:2023年12月20日 08:58:07   作者:Congwei12138  
使用electron開發(fā)應(yīng)用遇到了打印小票的功能,實現(xiàn)途中還是幾經(jīng)波折,下面這篇文章主要給大家介紹了關(guān)于electron實現(xiàn)打印功能支持靜默打印、無感打印的相關(guān)資料,需要的朋友可以參考下

實現(xiàn)思路

業(yè)務(wù)上目前有兩種打印的方法:

  • webview標簽:electron提供webview用于在一個獨立的 frame 和進程里顯示外部 web 內(nèi)容。但是在Electron >= 5中是禁用該標簽的,所以就直接放棄它。
  • webContent.print方法:webCompent是主進程用來渲染和控制網(wǎng)頁的對象,而它的print方法是用來打印渲染進程中的網(wǎng)頁內(nèi)容。這里我們選擇這個方法。

總體思路大概為:

  • 在頁面點擊打印按鈕,發(fā)布訂閱去創(chuàng)建一個隱藏的新窗口,窗口內(nèi)容就是我們要打印的內(nèi)容。利用新窗口展示的路徑的hash和打印頁面路由相互匹配實現(xiàn)指定打印內(nèi)容。
  • 在打印頁面初始化后,需要窗口去掉標題的按鈕,防止亂入到打印頁面。然后在根據(jù)路由傳遞的參數(shù)查找數(shù)據(jù)渲染頁面。 再然后發(fā)布printHandlePrint事件進行打印并設(shè)置靜默打印和去除邊距。最后打印完成發(fā)布destroyPrintWindow事件銷毀新窗口。

實現(xiàn)

1、創(chuàng)建打印方法

使用ipcMain.handle向主進程訂閱打印相關(guān)事件。其中printHandlePrint訂閱就是調(diào)用打印機的方法。最重要的是openPrintWindow訂閱,它的內(nèi)部去調(diào)用了openPrintWindow方法,它的用處就是用于創(chuàng)建一個新的BrowserWindow窗口,將要打印的內(nèi)容放進新窗口中,這樣我們就可以實現(xiàn)打印指定內(nèi)容的功能。destroyPrintWindow訂閱作用于銷毀創(chuàng)建的新窗口。

可以看到openPrintWindow會接受兩個參數(shù),第一個參數(shù)是事件對象,第二個參數(shù)是發(fā)布事件時傳遞的參數(shù),而這個參數(shù)最終會通過路由的方式傳遞到打印的新窗口中。實現(xiàn)渲染進程和渲染進程的偽通信。

方法寫好之后記得要在app.whenReady()后調(diào)用這個方法。

// printHandle.ts
let win: BrowserWindow;
export function usePrintHandle() {
  // 獲取系統(tǒng)打印機詳情
  ipcMain.handle("getPrinters", async (event) => {
    return await event.sender.getPrintersAsync();
  });
  // 調(diào)用打印機打印
  ipcMain.handle(
    "printHandlePrint",
    async (event, options: WebContentsPrintOptions) => {
      return new Promise((resolve) => {
        event.sender.print(
          options,
          (success: boolean, failureReason: string) => {
            resolve({ success, failureReason });
          }
        );
      });
    }
  );
  // 創(chuàng)建打印界面
  ipcMain.handle("openPrintWindow", (_, id) => {
    // id 用于傳遞的參數(shù)
    openPrintWindow(id);
  });
  // 銷毀打印界面
  ipcMain.handle("destroyPrintWindow", () => {
    if (win) win.destroy();
  });
}
?
// index.ts
app.whenReady().then(()=>{
  usePrintHandle();
})

2、創(chuàng)建新的BrowserWindow窗口

首先這個創(chuàng)建新窗口的函數(shù)會在openPrintWindow訂閱中觸發(fā),也就是在點擊了打印按鈕時觸發(fā)。所以會判斷時候存在這個新窗口,如果存在就要隱藏并銷毀掉,這樣可以保證我們每次點擊打印按鈕時都會是最新的隱藏的窗口。

然后需要在ready-to-show事件中將新窗口隱藏掉,這樣做的好處是這個新窗口一直都是隱藏的,從而實現(xiàn)無感打印。

最后有一個問題就是如何將打印的數(shù)據(jù)添加到新的窗口中,可以通過新窗口實例對象的loadURL方法,這個方法傳遞一個我們要展示內(nèi)容的路徑。printURLCustom方法中可以看到路徑就是項目打包根頁面,而后面的hash就是我們路由的hash模式路由。 所以我們可以寫一個print組件,然后為這個組件增加print路由。這樣我們打開的新窗口顯示就是print組件的內(nèi)容。

openPrintWindow訂閱的參數(shù)會作為路由的query參數(shù)拼接到路徑上面,print組件就可以拿到點擊組件打印傳遞的參數(shù)。

// router.ts
{path: "/print",name: "打印",component: () => import("@renderer/views/print/index.vue")},
// path.ts
/**
 * 獲取真正的地址
 *
 * @param {string} devPath 開發(fā)環(huán)境路徑
 * @param {string} proPath 生產(chǎn)環(huán)境路徑
 * @param {string} [hash=""] hash值
 * @param {string} [search=""] search值
 * @return {*}  {string} 地址
 */
function getUrl(
  devPath: string,
  proPath: string,
  hash: string = "",
  search: string = ""
): string {
  const url = isDev
    ? new URL(`http://localhost:${process.env.PORT}`)
    : new URL("file://");
  url.pathname = isDev ? devPath : proPath;
  url.hash = hash;
  url.search = search;
  return url.href;
}
export const printURLCustom = (id) =>
  getUrl("",join(__dirname, "..", "renderer", "index.html"),`#/print?id=${id}`);
?
// printHandle.ts
let win: BrowserWindow;
const otherWindowConfig: BrowserWindowConstructorOptions = {
  height: 595,
  useContentSize: true,
  width: 1140,
  autoHideMenuBar: true,
  minWidth: 842,
  frame: false,
  show: false,
  webPreferences: {
    contextIsolation: false,
    nodeIntegration: true,
    webSecurity: false,
    // 如果是開發(fā)模式可以使用devTools
    devTools: process.env.NODE_ENV === "development",
    // 在macos中啟用橡皮動畫
    scrollBounce: process.platform === "darwin",
  },
};
export function openPrintWindow(id) {
  if (win) {
    win.hide(); /*測試*/
    win.destroy();
    return;
  }
  win = new BrowserWindow({
    titleBarStyle: "hidden",
    ...Object.assign(otherWindowConfig, {}),
  });
  win.loadURL(printURLCustom(id));
  win.setMenu(null);
  win.on("ready-to-show", () => {
    win.hide();
  });
  win.on("closed", () => {
    win = null;
  });
}
?

3、創(chuàng)建點擊打印組件

這里是通過ipcRenderer渲染進程攜帶參數(shù)發(fā)布openPrintWindow事件。這里需要注意的是ipcRenderer要使用commonjs引入,否則會報錯TypeError: path.join is not a function. 但是瀏覽器不支持commonjs,所以非常不建議在瀏覽器上跑這個項目。

<template>
    <div @click=print>打印</div>
</template>
<script lang="ts" setup>
  const { ipcRenderer } = require("electron"); // 瀏覽器環(huán)境報錯
  const onPrint = async () => {
    await ipcRenderer.invoke("openPrintWindow", 123123); // 創(chuàng)建新窗口并傳遞數(shù)據(jù)
  };
</script>

4、創(chuàng)建打印組件

在打印新窗口時雖然設(shè)置了frame:false,但是標題的關(guān)閉、最小化這些按鈕還存在,導(dǎo)致打印也會把按鈕打印到頁面。我沒有找到完美的解決辦法,所以直接刪除了DOM。

參數(shù)可以通過route.query拿到點擊打印按鈕傳遞的參數(shù)。

通過ipcRenderer渲染進程發(fā)布printHandlePrint事件,傳遞參數(shù)為的打印機配置。其中啟用了靜默打印和去除打印頁面邊距。

靜默打印是指用默認的打印機打印出所有頁并且不希望彈出對話框進行設(shè)置,所以在打印的時候要設(shè)置好系統(tǒng)默認打印機。

最后在打印完成時發(fā)布destroyPrintWindow事件,銷毀掉打印新窗口。

<template>
    <div>我要被打印了</div>
</template>
<script lang="ts" setup>
  import { useRoute } from "vue-router";
  import { ref, onMounted  } from "vue";
  
  const { ipcRenderer } = require("electron"); // 瀏覽器環(huán)境報錯
  
  const route = useRoute();
  const id = route.query.id as string; // 接收參數(shù)
?
  onMounted(async () => {
    const windowTitle = window.document.querySelector(".window-title ");
    windowTitle && windowTitle.remove(); // 刪除頂部標題關(guān)閉按鈕
    // await getDataApi(id); // 獲取數(shù)據(jù)
    try {
      await ipcRenderer.invoke("printHandlePrint", {
        silent: true, // 靜默打印
        margins: { marginType: "none" }, // 網(wǎng)頁的邊距
      }); 
    } catch (error) {
    } finally {
      await ipcRenderer.invoke("destroyPrintWindow"); // 打印完成銷毀新窗口
    }
  });
</script>

總結(jié) 

到此這篇關(guān)于electron實現(xiàn)打印功能支持靜默打印、無感打印的文章就介紹到這了,更多相關(guān)electron打印功能內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Vue.js?中的父子組件通信方式實例教程

    Vue.js?中的父子組件通信方式實例教程

    在 Vue.js 中,父子組件通信是非常重要的,在本文中,我們討論了 Vue.js 中父子組件通信的幾種方式,包括使用 props 傳遞數(shù)據(jù)、使用 Sync 修飾符實現(xiàn)雙向綁定、使用自定義事件傳遞數(shù)據(jù)、使用 $refs 訪問子組件實例以及使用 $children 和 $parent 訪問父子組件實例
    2023-09-09
  • vue-cli3.X快速創(chuàng)建項目的方法步驟

    vue-cli3.X快速創(chuàng)建項目的方法步驟

    這篇文章主要介紹了vue-cli3.X快速創(chuàng)建項目的方法步驟,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11
  • ant?design?vue的table取消自帶分頁問題

    ant?design?vue的table取消自帶分頁問題

    這篇文章主要介紹了ant?design?vue的table取消自帶分頁問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • vue3+vite使用History路由模式打包部署項目的步驟及注意事項

    vue3+vite使用History路由模式打包部署項目的步驟及注意事項

    這篇文章主要介紹了vue3+vite使用History路由模式打包部署項目的步驟及注意事項,配置過程包括在Vue項目中設(shè)置路由模式、調(diào)整打包配置以及Nginx服務(wù)器的配置,正確的部署配置能夠確保應(yīng)用順利運行,提升用戶體驗,需要的朋友可以參考下
    2024-10-10
  • Vue Router的懶加載路徑的解決方法

    Vue Router的懶加載路徑的解決方法

    這篇文章主要介紹了Vue Router的懶加載路徑的解決方法,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下
    2018-06-06
  • 讓webpack+vue-cil項目不再自動打開瀏覽器的方法

    讓webpack+vue-cil項目不再自動打開瀏覽器的方法

    今天小編就為大家分享一篇讓webpack+vue-cil項目不再自動打開瀏覽器的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-09-09
  • vue2?element-ui?el-checkbox視圖不更新問題及解決

    vue2?element-ui?el-checkbox視圖不更新問題及解決

    作者在開發(fā)過程中遇到了視圖不更新的問題,最終通過改變一個無關(guān)緊要的響應(yīng)式數(shù)據(jù)來解決,讓視圖發(fā)生改變
    2024-12-12
  • vue輕松實現(xiàn)水印效果

    vue輕松實現(xiàn)水印效果

    這篇文章主要為大家詳細介紹了vue輕松實現(xiàn)水印效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • vue Element-ui input 遠程搜索與修改建議顯示模版的示例代碼

    vue Element-ui input 遠程搜索與修改建議顯示模版的示例代碼

    本文分為html,js和css代碼給大家詳細介紹了vue Element-ui input 遠程搜索與修改建議顯示模版功能,感興趣的朋友一起看看吧
    2017-10-10
  • 在Vue中使用mockjs代碼實例

    在Vue中使用mockjs代碼實例

    這篇文章主要介紹了在Vue中使用mockjs代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-11-11

最新評論

东乡族自治县| 樟树市| 大兴区| 观塘区| 腾冲县| 寻乌县| 博乐市| 南充市| 新建县| 高雄市| 祁阳县| 玉林市| 鄄城县| 阜宁县| 揭阳市| 沐川县| 铁岭县| 中卫市| 尖扎县| 嘉峪关市| 巴林右旗| 屯留县| 通榆县| 安多县| 永安市| 金阳县| 静安区| 万山特区| 新蔡县| 调兵山市| 璧山县| 怀仁县| 延吉市| 化州市| 承德县| 新丰县| 江达县| 平湖市| 邵阳县| 永川市| 苏尼特左旗|