当前位置: 移动技术网 > IT编程>开发语言>JavaScript > electron——dialog(实现导出excel)

electron——dialog(实现导出excel)

2019年11月26日  | 移动技术网IT编程  | 我要评论

背景

前端点击导出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.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,具体原因作者也不太清楚>﹏<,以后知道后会更新的。。。

以上仅供参考,如有问题欢迎指出,但我不一定改(~ ̄▽ ̄)~

参考

electron-dialog

electron中recorderjs导出blob对象,并使用node保存到本地

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网