Фронтендовая тихая печать реализует коллекцию html и pdf

Electron

1. Начальная реализация

Некоторое время назад у компании была потребность добиться тишины во внешнем интерфейсе (нажмите кнопку, чтобы распечатать напрямую, предварительный просмотр не требуется), я подумал об использовании окна. :

   В итоге пришлось продолжать путешествовать по интернету, чтобы найти ответ

Во-вторых, реализация clodop.js

   Наконец обнаружил, что мой коллега использовал его раньшеclodop.jsЧтобы добиться предварительной печати, после жесткой работы я обнаружил, что на отпечатке будет водяной знак, и, наконец, решил сдаться.

3. Электронная реализация

СлучайноЭлектронная документациянайти в

    webview.print({
        silent Boolean (可选) - 不询问用户打印信息,默认为 false。
    })
    就开始一顿操作如虎了
  • Структура каталогов

    my-project
    ├─ .electron-vue
    ├── package-lock.json
    ├── package.json
    ├── src
    │   ├── index.ejs
    │   ├── main
    │   │   ├── index.dev.js
    │   │   ├── index.js
    │   │   └── server.js
    │   └── renderer
    │       ├── App.vue
    │       ├── components
    │       ├── main.js
    │       ├── router
    │       ├── store
    │       └── view
    ├── static
    │   ├── PDFtoPrinter.exe //打印pdf插件
    │   ├── config.txt
    │   ├── icon.ico
    │   ├── icon2.ico
    │   ├── pdf
    │   │   └── report.pdf  //准备打印的pdf
    │   └── print.html   //准备打印的html
    ├── test
    │   └── e2e
    │       ├── index.js
    │       ├── specs
    │       └── utils.js
    └── yarn.lock
    
  • динамическая печать html

    <!-- 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;
          }
          /*打印页样式*/
          @page {
            margin: 0px;
          }
          /*自定义打印样式,可以提前放入样式,减少传入内容*/
        </style>
      </head>
    
      <body id="bd"></body>
      
      <script>
        const { ipcRenderer } = require('electron')
        ipcRenderer.on('webview-print-render', (event, info) => {
            // 执行渲染
            document.getElementById('bd').innerHTML = info.html
            ipcRenderer.sendToHost('webview-print-do')
        })
      </script>
    </html>
    
    <!-- print.vue-->
    <template>
      <div class="guide-print">
        <button @click="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('打印发送到打印机')
              }
            )
          }
        })
        this.getPrintListHandle()
      },
      methods: {
        print() {
            const webview = this.$refs.printWebview
            webview.send('webview-print-render', {
              printName: this.printName,
              html: "<p>我是打印内容</p>"
            })
        },
         //获取打印机
        getPrintListHandle() {
          ipcRenderer.send('getPrinterList')
          ipcRenderer.once('getPrinterList', (event, data) => {
            // 过滤可用打印机
            this.printName = data.filter(e => e.isDefault)[0].name
          })
        }
      }
    }
    </script>
    <style lang="scss">
    #printWebview {
      height: 0;
      width: 0;
      visibility: hidden;
    }
    </style>
    
  • Удаленная и локальная печать PDF

    安装依赖    npm  i node-pdf-printer
    

    Скачать пакет для печатиPDFtoPrinter.exe

    //main.js 本地pdf文件打印
    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,...],'你的打印机名字,不填/默认')
    
    //main.js 远程pdf文件打印
    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('/')+1)
      )
      //下载远程pdf资源到/static/pdf目录
    request(url, err => {
        if(!err){
             NodePdfPrinter.printFiles([pdfPath])
        }
    }).pipe(fs.createWriteStream(pdfPath))
    

    Если вы загружаете несколько PDF-файлов в пакетном режиме, вы можете выполнить NodePdfPrinter.printFiles для пакетной печати после загрузки всех ресурсов PDF и удалить локальные PDF-файлы после печати.

    function deleteDir(url) {
      var files = []
      if (fs.existsSync(url)) {
        //判断给定的路径是否存在
        files = fs.readdirSync(url) //返回文件和子目录的数组
        files.forEach(function(file, index) {
          var curPath = path.join(url, file)
          if (fs.statSync(curPath).isDirectory()) {
            //同步读取文件夹文件,如果是文件夹,则函数回调
            deleteDir(curPath)
          } else {
            fs.unlinkSync(curPath) //是指定文件,则删除
          }
        })
        // fs.rmdirSync(url) //清除文件夹
      } else {
        console.log('给定的路径不存在!')
      }
    }
    

В-четвертых, яма

  • Файлы в статическом каталоге пакета не упакованы
       Необходимо добавить дополнительные ресурсы extraResources в package.json

        "win": {
             "icon": "dist/electron/static/icon2.ico",
             "extraResources": [
                "./static/*.html",
                "./static/*.txt",
                "./static/*.exe",
                "./static/pdf/*.pdf"
             ],
        }
    
  • Печать HTML иногда сталкивается с тем, что изображение не распечатывается
      Причина в том, что после document.getElementById('bd').innerHTML = info.html, print.vue уведомляется непосредственно о печати, в результате чего веб-просмотр загружается не полностью.
    Автор долго искал, но не нашел подходящего монитора.В настоящее время небольшая задержка при перенаправлении ресурсов.Знающие это спасибо, что поделились 🙏🙏

  • Удаленная загрузка PDF не может быть помещена в папку /static/pdf
      Причина в том, что электрон-вью упакован с асаром по умолчанию, а асар можно только читать, но не записывать, поэтому его нельзя запаковать в асар, если нужно печатать pdf удаленно

        "win": {
          "asar": false,
        ]
    

    Есть также некоторые настройки значков, настройки контекстного меню в трее, сжатие лотков, мигание и всплывающие подсказки, поэтому я не буду повторять их здесь.Если у вас есть какие-либо вопросы, вы можете прокомментировать и обсудить ниже.