electron——dialog(實現導出excel)


背景

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

dialog

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

dialog 模塊提供了api來展示原生的系統對話框,例如打開文件框,alert框,所以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 是什么的點擊這里

// 創建一個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.substring(filePath.lastIndexOf('.') + 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,具體原因作者也不太清楚>﹏<,以后知道后會更新的。。。

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

文章原創 轉載附帶原創鏈接

參考

electron-dialog

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM