前端点击导出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