electron——dialog(實現導出excel)

背景

前端點擊導出excel按鈕後,請求完須要導出的數據後發送給主進程electron,由主進程保存到本地前端

dialog

顯示用於打開和保存文件、警報等的本機系統對話框。node

dialog 模塊提供了api來展現原生的系統對話框,例如打開文件框,alert框,因此web應用能夠給用戶帶來跟系統應用相同的體驗.web

let win = ...;  // BrowserWindow in which to show the dialog
const dialog = require('electron').dialog;
console.log(dialog.showOpenDialog({ properties: [ 'openFile', 'openDirectory', 'multiSelections' ]}));

前端代碼(渲染進程)

// 引入ipcRenderer模塊
const { ipcRenderer } = require('electron')
// 表格數據擬定爲 data
let excelModel = new Blob([data], { type: "application/octet-stream" })

不知道 Blob 是什麼的點擊這裏api

// 建立一個FileReader的實例
let reader  = new FileReader()
// 開始讀取指定的Blob中的內容。一旦完成,result屬性中將包含一個data: URL格式的Base64字符串以表示所讀取文件的內容。
reader.readAsDataURL(excelModel)
// 處理 load 事件。該事件在讀取操做完成時觸發
reader.addEventListener("loadend", function() {
  // reader.result 包含被轉化爲類型數組 typed array 的 blob
  // 向主進程發送下載excel消息
  ipcRenderer.send("saveDialog", {
    baseCode: reader.result,
    fileType: 'excel',
    fileName: '封神榜'
  })
  // 接收主進程發送回來的下載成功回調
  ipcRenderer.once('succeedDialog', event => {
    // 成功回調
  })
  // 接收主進程發送回來的下載失敗回調
  ipcRenderer.once('defeatedDialog', event => {
   // 失敗回調
  })

})

不知道 FileReader 是什麼的點擊這裏數組

electron代碼(主進程)

// 建立BrowserWindow實例
let win = new BrowserWindow(browser)
// 引入dialog、ipcMain、fs模塊
const { dialog, ipcMain } = require('electron')
const fs = require('fs')
// 定義文件下載擴展名選擇
const extensionType = {
  // 圖片
  images: [
    { name: '.jpg', extensions: ['jpg'] },
    { name: '.png', extensions: ['png'] },
    { name: '.gif', extensions: ['gif'] },
  ],
  // Excel
  excel: [
    { name: '.xlsx', extensions: ['xlsx'] },
    { name: '.xls', extensions: ['xls'] },
  ]
}
//在主線程下,經過ipcMain對象監聽渲染線程傳過來的saveDialog事件
ipcMain.on('saveDialog', (event, arg) => {
  // 打開彈窗
  dialog.showSaveDialog(win, {
   // 在 Windows 和 Linux 上, 打開對話框不能同時是文件選擇器和目錄選擇器, 所以若是在這些平臺上將 properties 設置爲["openFile"、"openDirectory"], 則將顯示爲目錄選擇器。
    properties: ['openFile', 'openDirectory'],
    // 默認狀況下使用的絕對目錄路徑、絕對文件路徑、文件名
    defaultPath: arg.fileName,
    // 文件下載擴展名
    filters: [
      ...extensionType[arg.fileType]
    ],
   // 點擊保存回調
  }, filePath  =>{
    // filePath存在則爲保存路徑 否爲undefined
    // 去掉頭部無用字段並將base64轉碼成buffer
    let dataBuffer = Buffer.from(arg.baseCode.split('base64,')[1], 'base64')
    // 檢測文件擴展名是否正確
    let typeFlag = extensionType[arg.fileType].some(item => {
      if(filePath) {
        return item.extensions[0] === filePath.split('.')[1]
      } else {
        return false
      }
    })
    if(typeFlag){
      fs.writeFile(filePath, dataBuffer, err => {
        // 失敗
        if (err) {
          // 向渲染進程發送消息通知失敗
          win.webContents.send('defeatedDialog')
        }
      })
      // 成功 向渲染進程發送消息通知成功
      win.webContents.send('succeedDialog')
      // 判斷是否存在保存路徑
    } else if(filePath !== undefined){
      dialog.showMessageBox({
        type: 'error',
        title: '系統提示',
        message: '系統檢測出文件類型異常,請檢查並從新選擇或填寫'
      })
    }
  })
})

之因此在肯定後再次對文件的擴展名進行判斷,是由於傳入excel的文件擴展名仍然能夠保存其餘擴展名,如.jpg,具體緣由做者也不太清楚>﹏<,之後知道後會更新的。。。app

以上僅供參考,若有問題歡迎指出,但我不必定改(~ ̄▽ ̄)~electron

參考

electron-dialogui

electron中recorderJs導出blob對象,並使用node保存到本地.net

相關文章
相關標籤/搜索