背景
前端點擊導出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" })
// 創建一個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 => {
// 失敗回調
})
})
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,具體原因作者也不太清楚>﹏<,以后知道后會更新的。。。
以上僅供參考,如有問題歡迎指出,但我不一定改(~ ̄▽ ̄)~