Electronic -- dialog (to export excel)

Keywords: Javascript Excel Windows Linux

background

After the front end clicks the export excel button, it requests the data to be exported and sends it to the main process, electron, which saves it locally

dialog

Displays native system dialog boxes for opening and saving files, alarms, and so on.

The dialog module provides an api to show the native system dialog box, such as open file box and alert box, so web application can bring the same experience as system application to users

let win = ...;  // BrowserWindow in which to show the dialog
const dialog = require('electron').dialog;
console.log(dialog.showOpenDialog({ properties: [ 'openFile', 'openDirectory', 'multiSelections' ]}));

Front end code (rendering process)

// Introducing ipcRenderer module
const { ipcRenderer } = require('electron')
// Table data is proposed as data
let excelModel = new Blob([data], { type: "application/octet-stream" })

I don't know what Blob is. Click here

// Create an instance of FileReader
let reader  = new FileReader()
// Starts reading from the specified Blob. Once completed, the result property will contain a Base64 string in the format of data: URL to represent the contents of the read file.
reader.readAsDataURL(excelModel)
// Handle the load event. This event is triggered when the read operation completes
reader.addEventListener("loadend", function() {
  // reader.result contains blob s converted to type array
  // Send download excel message to main process
  ipcRenderer.send("saveDialog", {
    baseCode: reader.result,
    fileType: 'excel',
    fileName: 'Fengshen Bang'
  })
  // Receive the download success callback sent back by the main process
  ipcRenderer.once('succeedDialog', event => {
    // Successful callback
  })
  // Receive the download failure callback sent back by the main process
  ipcRenderer.once('defeatedDialog', event => {
   // Failed callback
  })

})

I don't know what FileReader is. Click here

electron code (main process)

// Create BrowserWindow instance
let win = new BrowserWindow(browser)
// Introduce dialog, ipcMain and fs modules
const { dialog, ipcMain } = require('electron')
const fs = require('fs')
// Define file download extension selection
const extensionType = {
  // picture
  images: [
    { name: '.jpg', extensions: ['jpg'] },
    { name: '.png', extensions: ['png'] },
    { name: '.gif', extensions: ['gif'] },
  ],
  // Excel
  excel: [
    { name: '.xlsx', extensions: ['xlsx'] },
    { name: '.xls', extensions: ['xls'] },
  ]
}
//Under the main thread, listen for the saveDialog event from the rendering thread through the ipcMain object
ipcMain.on('saveDialog', (event, arg) => {
  // Open the window
  dialog.showSaveDialog(win, {
   // On Windows and Linux, the open dialog box cannot be both a file selector and a directory selector, so if you set properties to ["openFile", "openDirectory"] on these platforms, it will be displayed as a directory selector.
    properties: ['openFile', 'openDirectory'],
    // Absolute directory path, absolute file path, and file name used by default
    defaultPath: arg.fileName,
    // File download extension
    filters: [
      ...extensionType[arg.fileType]
    ],
   // Click Save callback
  }, filePath  =>{
    // Save path if filePath exists or undefined
    // Remove the useless fields in the header and transcode base64 to buffer
    let dataBuffer = Buffer.from(arg.baseCode.split('base64,')[1], 'base64')
    // Check if the file extension is correct
    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 => {
        // fail
        if (err) {
          // Failed to send message notification to rendering process
          win.webContents.send('defeatedDialog')
        }
      })
      // Successfully sent message notification to rendering process
      win.webContents.send('succeedDialog')
      // Determine whether there is a saving path
    } else if(filePath !== undefined){
      dialog.showMessageBox({
        type: 'error',
        title: 'System hint',
        message: 'The system has detected that the file type is abnormal. Please check and re select or fill in'
      })
    }
  })
})

The reason why the extension of the file is judged again after confirmation is that the extension of the file passed into excel can still save other extensions, such as. jpg. The specific reason is not clear to the author. It will be updated later...

The above is for reference only. If you have any questions, please point out, but I don't necessarily change (~ ▽) ~

Reference resources

electron-dialog

recorderJs in electron exports the blob object and uses node to save it locally

Posted by new_to_php2004 on Tue, 26 Nov 2019 11:03:24 -0800