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" })
// 创建一个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,具体原因作者也不太清楚>﹏<,以后知道后会更新的。。。
以上仅供参考,如有问题欢迎指出,但我不一定改(~ ̄▽ ̄)~