Browse Source

预览PDF文件
Signed-off-by: Caner <40012261+Canees@users.noreply.github.com>

Caner 3 years ago
parent
commit
4ef899d0e9
8 changed files with 469 additions and 372 deletions
  1. 3 4
      README.md
  2. 40 16
      main.js
  3. 2 1
      package.json
  4. 1 3
      src/pages/index/views/Lithology.vue
  5. 32 27
      src/pages/print/App.vue
  6. 24 0
      src/pages/print/components/loading.vue
  7. 9 9
      vite.config.js
  8. 358 312
      yarn.lock

+ 3 - 4
README.md

@@ -3,12 +3,11 @@
 总体思路是用vue写了仿谷歌的打印组件,api使用el的BrowserWindow实例的webContents.print,使用printopdf来达到预览功能。
 ```
 
-# TODO:
+# TODO:(渲染进程与主进程之间交互)
 ```
-1. 生成PDF文件|数据回传打印组件
-2. 打印组件优化参数
-3. 打印组件预览PDF文件
 4. 打印功能API对接
+5. 打印参数调整->预览PDF
+
 ```
 
 

+ 40 - 16
main.js

@@ -1,6 +1,8 @@
 const {
   app, BrowserWindow, Menu, ipcMain
 } = require('electron')// 引入electron
+const path = require('path')
+const fs = require('fs')
 
 class InitWin {
   constructor() {
@@ -9,6 +11,7 @@ class InitWin {
     this.loadingWin = null
     this.mainWin = null
     this.printWin = null
+    this.filePath = path.join(__dirname, './dist/print.pdf')
     this.on()
   }
 
@@ -93,17 +96,30 @@ class InitWin {
   }
 
   /**
-   * 发送打印机列表
-   * @param {Obj} win 窗口对象
-   * @param {String} eventName 需要发送事件名称
+   * 保存打印文件默认保存在dist中
+   * @param {object} win
+   * @param {object} option
    */
-  async getPrintList(win) {
-    try {
-      const list = await win.webContents.getPrintersAsync()
-      win.webContents.send('getPrintList', list)
-    } catch (error) {
-      console.log('请升级electron版本')
+  async SavePrintData(win, option) {
+    if (!option || !Object.keys(option).length) {
+      option = {
+        marginsType: 1, // 默认边距
+        pageSize: 'A4',
+        printBackground: true, // 文件中包含 CSS 背景
+        printSelectionOnly: false,
+        landscape: false// 纵向模式
+      }
     }
+    const buffer = await win.webContents.printToPDF(option)
+    return new Promise((resolve, reject) => {
+      fs.writeFile(this.filePath, buffer, (err) => {
+        if (err) {
+          console.log('save error')
+          return reject(err)
+        }
+        return resolve(this.filePath)
+      })
+    })
   }
 
   /**
@@ -121,13 +137,21 @@ class InitWin {
       })
 
       // 监听打开print
-      ipcMain.on('openPrint', async (event, data) => {
-        // TODO: 页面数据生成PDF
-
-        // 回传打印机列表
-        await this.getPrintList(this.printWin)
-        this.printWin.show()
-        console.log('open', data)
+      ipcMain.on('openPrint', async (event) => {
+        try {
+          // 获取当前BW实例打印机列表
+          const currentWin = event.sender.getOwnerBrowserWindow()
+          const list = await currentWin.webContents.getPrintersAsync()
+          this.printWin.webContents.send('getData', list)
+          this.printWin.show()
+          // 转成PDF文件
+          const filePath = await this.SavePrintData(currentWin)
+          // 渲染进程加载PDF
+          this.printWin.webContents.send('loadingPDF', filePath)
+        } catch (error) {
+          console.log(error)
+          this.printWin.webContents.send('loadingPDF', '')
+        }
       })
 
       // 监听关闭print

+ 2 - 1
package.json

@@ -49,6 +49,7 @@
     }
   },
   "dependencies": {
-    "vue-calendar-component": "^2.8.2"
+    "vue-calendar-component": "^2.8.2",
+    "vue-pdf-embed": "^1.1.4"
   }
 }

+ 1 - 3
src/pages/index/views/Lithology.vue

@@ -20,9 +20,7 @@ export default {
       // 通知主进程开启打印窗口
       const electron = window.$electron || null
       if (electron) {
-        const w = window.innerWidth
-        const h = window.innerHeight
-        electron.ipcRenderer.send('openPrint', { w, h })
+        electron.ipcRenderer.send('openPrint')
       }
     }
   }

+ 32 - 27
src/pages/print/App.vue

@@ -1,7 +1,11 @@
 <template>
   <div id="app">
     <div class="left">
-      test
+      <VuePdfEmbed
+        v-if="loadingPDF"
+        :source="loadingPDF"
+      />
+      <Loading v-else />
     </div>
     <div>
       <div class="right">
@@ -26,22 +30,6 @@
             </Select>
           </div>
         </div>
-        <!-- <div>
-          <span>页面</span>
-          <div>
-            <Select
-              v-model="selectData.pagesPerSheet"
-            >
-              <Option
-                v-for="item in pagesPerSheet"
-                :key="item.value"
-                :value="item.value"
-              >
-                {{ item.label }}
-              </Option>
-            </Select>
-          </div>
-        </div> -->
         <div>
           <span>份数</span>
           <div>
@@ -197,16 +185,17 @@
   </div>
 </template>
 <script>
+import VuePdfEmbed from 'vue-pdf-embed/dist/vue2-pdf-embed'
+import Loading from './components/loading.vue'
 export default {
+  components: {
+    VuePdfEmbed,
+    Loading
+  },
   data() {
     return {
       // 打印机列表
-      deviceName: [
-        {
-          label: '11111111111111111111111111111111111',
-          value: 0
-        }
-      ],
+      deviceName: [ ],
       // 工作表的页数
       pagesPerSheet: [
         {
@@ -332,7 +321,8 @@ export default {
         pageSize: 'A4', // 纸张尺寸
         duplexMode: 'shortEdge'// 双面打印
       },
-      duplex: false
+      duplex: false,
+      loadingPDF: ''
     }
   },
   methods: {
@@ -345,9 +335,11 @@ export default {
     }
   },
   mounted() {
-    const { ipcRenderer } = window.$electron || null
-    if (ipcRenderer) {
-      ipcRenderer.on('getPrintList', (event, list) => {
+    this.loadingPDF = ''
+    const electron = window.$electron || null
+    if (electron) {
+      // 监听打印机数据
+      electron.ipcRenderer.on('getData', (event, list) => {
         const arr = []
         let isDefault = ''
         for (let k = 0; k < list.length; k++) {
@@ -361,6 +353,11 @@ export default {
         this.deviceName = arr
         this.selectData.deviceName = isDefault
       })
+      // 监听PDF文件准备完成
+      electron.ipcRenderer.on('loadingPDF', (event, filePath) => {
+        this.loadingPDF = filePath
+        console.log(66, filePath)
+      })
     }
   }
 }
@@ -375,12 +372,20 @@ export default {
   display: flex;
   font-size: 15px;
   color: black;
+  width: 970px;
   .left{
     width: 560px;
     height: 760px;
     background: rgb(218, 220, 224);
     overflow-y: scroll;
     overflow-x: hidden;
+    position: relative;
+    /deep/ .loader{
+      position: absolute;
+      top: 45%;
+      left: 45%;
+      transform: translate(-45%,-45%);
+    }
   }
   .right{
     width: 410px;

+ 24 - 0
src/pages/print/components/loading.vue

@@ -0,0 +1,24 @@
+<template>
+  <div class="loader" />
+</template>
+<style scoped>
+.loader {
+  border: 5px solid #f3f3f3;
+  border-radius: 50%;
+  border-top: 5px solid #3498db;
+  width: 30px;
+  height: 30px;
+  -webkit-animation: spin 2s linear infinite;
+  animation: spin 2s linear infinite;
+}
+
+@-webkit-keyframes spin {
+  0% { -webkit-transform: rotate(0deg); }
+  100% { -webkit-transform: rotate(360deg); }
+}
+
+@keyframes spin {
+  0% { transform: rotate(0deg); }
+  100% { transform: rotate(360deg); }
+}
+</style>

+ 9 - 9
vite.config.js

@@ -40,13 +40,13 @@ export default ({ mode }) => defineConfig({
       '@': path.resolve(__dirname, './src')
     }
   },
-  plugins: [createVuePlugin(), viteCompression({ disable: true }),eslint({ fix: true })],
+  plugins: [ createVuePlugin(), viteCompression({ disable: true }), eslint({ fix: true }) ],
   server: {
     host: 'localhost',
     port: 6547,
     open: true,
     strictPort: false,
-    https: false,
+    https: false
     // 反向代理
     // proxy: {
     //   '/': {
@@ -59,22 +59,22 @@ export default ({ mode }) => defineConfig({
   build: {
     rollupOptions: {
       input: entryConfig(),
-      output: { //静态资源分类打包
+      output: { // 静态资源分类打包
         chunkFileNames: 'js/[name]-[hash].js',
         entryFileNames: 'js/[name]-[hash].js',
         assetFileNames: 'assets/[name]-[hash].[ext]'
       }
     },
-    terserOptions: { //去掉打印
+    terserOptions: { // 去掉打印
       compress: {
         drop_console: true,
-        drop_debugger: true,
-      },
-    },
+        drop_debugger: true
+      }
+    }
   },
-  define: { //环境变量配置
+  define: { // 环境变量配置
     'process.env': {
-      'SERVERURL': mode === 'development' ? 'http://127.0.0.1:5000':'http://127.0.0.1:5000'
+      SERVERURL: mode === 'development' ? 'http://127.0.0.1:5000' : 'http://127.0.0.1:5000'
     }
   }
 })

File diff suppressed because it is too large
+ 358 - 312
yarn.lock


Some files were not shown because too many files changed in this diff