I. Preliminary implementation

Some time ago, our company had a requirement to realize the front end silence (click the button to print directly, without preview). We wanted to directly use window.print() to achieve this, so that users could click the button more, but we had no choice but to produce our products:

Clodop.js implementation

Finally, I found that my colleague used clodop.js to realize front-end printing. After a fierce operation such as tiger found that there will be a watermark printed, and finally choose to give up.

Three, electron implementation

The chance was found in the Electron file

Webview. print({silent Boolean (Optional) - Does not ask the user to print information. Default is false. }) began a meal operation such as tigerCopy the code
  • The directory structure

    My-project ├─.electron ├─ Package-Lock. json ├─ SRC │ ├─ index.ejS │ ├─ main │ ├─ Index. Dev. Js │ │ ├ ─ ─ index. The js │ │ └ ─ ─ for server js │ └ ─ ─ the renderer │ ├ ─ ─ App. Vue │ ├ ─ ─ components │ ├ ─ ─ main. Js │ ├ ─ ─ the router │ ├ ─ ─ store │ └ ─ ─ the view ├ ─ ─ the static │ ├ ─ ─ PDFtoPrinter. Exe / / print PDF plug-in │ ├ ─ ─ config. TXT │ ├ ─ ─ icon. Ico │ ├ ─ ─ icon2. Ico │ ├ ─ ─ PDF │ │ └ ─ ─ report. The PDF / / ready to print the PDF │ └ ─ ─ the print. The HTML / / ready to print HTML ├ ─ ─test│ └ ─ ─ e2e │ ├ ─ ─ index. The js │ ├ ─ ─ specs │ └ ─ ─ utils. Js └ ─ ─ yarn. The lockCopy the code
  • Dynamic HTML printing

    <! -- print.html --> <! DOCTYPE html> <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="Width = device - width, initial - scale = 1.0" />
        <meta http-equiv="X-UA-Compatible" content="ie=edge"/> <title>Document</title> <style> body, html { padding: 0; margin: 0; font-size: 30px; } /* Print page style */ @page {margin: 0px; </style> </head> <body id="bd"></body>
      
      <script>
        const { ipcRenderer } = require('electron')
        ipcRenderer.on('webview-print-render', (event, info) => {// Execute render document.getelementById ('bd').innerHTML = info.html
            ipcRenderer.sendToHost('webview-print-do')
        })
      </script>
    </html>
    Copy the code
    <! -- print.vue--> <template> <div class="guide-print">
        <button @click="print"> print </button> <webview id="printWebview"
          ref="printWebview"
          src="static/print.html"
          nodeintegration
        />
      </div>
    </template>
    <script>
    import { ipcRenderer } from 'electron'
    export default {
      data() {
        return {
         printName:' '}},mounted() {
        const webview = this.$refs.printWebview
        webview.addEventListener('ipc-message', event => {
          if (event.channel === 'webview-print-do') {
            webview.print(
              {
                silent: true.printBackground: true,
                deviceName: this.printName
              },
              status => {
               console.log('Print to printer')
              }
            )
          }
        })
        this.getPrintListHandle()
      },
      methods: {
        print() {
            const webview = this.$refs.printWebview
            webview.send('webview-print-render', {
              printName: this.printName,
              html: "

    I print content

    "
    })}, // Get the printergetPrintListHandle() { ipcRenderer.send('getPrinterList') ipcRenderer.once('getPrinterList', (event, data) => {// Filter available printer this.printName = data.filter(e => e.isdefault)[0].name})}} </script> <style lang="scss"> #printWebview { height: 0; width: 0; visibility: hidden; } </style> Copy the code
  • Remote & local PDF printing

    Install dependency NPM I node-pdF-printerCopy the code

    Download the print package pdfTopinter.exe

    //main.js local PDF file import NodePdfPrinter from'node-pdf-printer'
    
    let url1 = path.join(__static,'/pdf/test1.pdf')pipe(fs.createWriteStream(pdfPath))
    let url2 = path.join(__static,'/pdf/test2.pdf') NodePdfPrinter.printFiles([url1,url2,...] .'Name of your printer, left blank/default')
    Copy the code
    // import NodePdfPrinter from'node-pdf-printer'
    import request from 'request'
    
    let url ='http://mozilla.github.io/pdf.js/web/compressed.tracemonkey-pldi-09.pdf' 
    let pdfPath = path.join(
        __static,
        'pdf/' + url.slice(url.lastIndexOf('/'Request (url, err => {err => {err => {if(! err){ NodePdfPrinter.printFiles([pdfPath]) } }).pipe(fs.createWriteStream(pdfPath))Copy the code

    If more than batch download PDF, you can download all the PDF resources in performing NodePdfPrinter. PrintFiles for batch printing, print to delete local in PDF.

    function deleteDir(url) {
      var files = []
      if(fs.existssync (url)) {// Determine if a given path exists files = fs.readdirsync (url) // Return an array of files and subdirectories files.foreach (function(file, index) {
          var curPath = path.join(url, file)
          if(fs.statsync (curPath).isdirectory ()) {// Read folder files synchronously, if folder, function callback deleteDir(curPath)}else}}) // fs.rmdirsync (url) // Clear folder}else {
        console.log('The given path does not exist! ')}}Copy the code

Four, pit

  • Package static directory files that are not packaged need to add extraResources to package.json

        "win": {
             "icon": "dist/electron/static/icon2.ico"."extraResources": [
                "./static/*.html"."./static/*.txt"."./static/*.exe"."./static/pdf/*.pdf"],}Copy the code
  • Document.getelementbyid (‘bd’).innerhtml = info.html The author searched for a long time and did not find a suitable monitor. Currently, it is a short delay when redirecting resources. If you know, thank you for sharing 🙏🙏

  • By default, the electron vue is packaged with ASAR, but ASAR can only read but not write. Therefore, remote printing of the PDF cannot be packaged into ASAR

        "win": {
          "asar": false,]Copy the code

    There are also some icon Settings, tray right-click menu Settings, narrow tray, flashing, bubble prompt pit, not here, you can comment on the discussion below