前端點擊導出excel按鈕後,請求完須要導出的數據後發送給主進程electron,由主進程保存到本地前端
顯示用於打開和保存文件、警報等的本機系統對話框。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" })
// 建立一個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 => { // 失敗回調 }) })
// 建立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