Search code examples
javascriptcsvdatasetblobxlsx

How to convert blob to xlsx or csv?


The frontend of the application having a file download option (which can be in the following format: xlsx, csv, dat). For that, I use fileSaver.js

Everything works fine for the format .dat/.csv but for the .xlsx it does not work the files are corrupted.

I tested the conversion with the following formats :

  • utf8
  • base64
  • binary

Here's how I do :

// /* BACK */ //
// data is 
fs.readFile(filePath, (err, data) {...})

// the api give this answer the important part is "filename" & "data"
{"status":"ok","context":"writing the intermediate file","target":"/temp/","fileName":"name.xlsx","data":{"type":"Buffer","data":[72,82,65,67,67,69,83,83,32,10]}}
// /* FRONT */ //
let json = JSON.stringify(data)
let buffer = Buffer.from(JSON.parse(json).data)
let read = buffer.toString('utf8')
let blob = new Blob([read])
FileSaver.saveAs(blob, fileName)

Solution

  • Ok for anybody who pass in this topic, my solution :

    (keep in mind the real better solution for dl a file : send file in api response with header 'Content-disposition' or use express for that like this)

    The back (Node) work like this :

     fs.readFile(filePath, (err, data) => {
        if (err) {
          console.log(`-------- oups error - read --------`)
          console.log(err)
          res.send({ status: `erreur`, context: `read the source file`, id: err.errno, code: err.code, message: err.message.replace(/\\/g, '/') })
        } else {
          res.send({ status: `ok`, context: `send data file`, target: target, fileName: fileName, data: data })
        } 
      })
    

    Here :

    • target is the path for the front with the name of the file and his extension (/path/name.ext)
    • fileName is juste the name and the extension (name.ext)
    • data is the data send by the readFile ({"type":"Buffer","data":[72,82,65,67,67,69,83,83,32,10]})

    The front (React) work like this :

    fetch(targetUrl)
        .then(res => res.json())
        .then(res => {
          if (res.status !== `ok`) {
            this.setState({
              errorDlFile: true,
              errorDlFile_context: res.context,
              errorDlFile_id: res.id,
              errorDlFile_code: res.code,
              errorDlFile_message: res.message
            })
          } else {  
            const target = res.target
            const fileName = res.fileName
            const data = res.data
            const splitName = res.fileName.split('.')
            const format = splitName[splitName.length-1]
    
            // file saver blob solution
            let json = JSON.stringify(data)
            let buffer = Buffer.from(JSON.parse(json).data)
            let readUTF8 = buffer.toString('utf8')
            let blob = ''
    
            if (format === 'xlsx') {
              blob = new Blob([buffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' })
            } else if (format === 'csv') {
              blob = new Blob([readUTF8], { type: 'application/vnd.ms-excel' })
            } else {
              blob = new Blob([readUTF8])
            }
    
            FileSaver.saveAs(blob, fileName)
    
          }
        })