如何将Blob转换为xlsx或csv?

4
应用程序的前端有一个文件下载选项(可使用以下格式:xlsx、csv、dat)。 为此,我使用 fileSaver.js
对于格式为.dat/.csv的文件,一切正常,但对于.xlsx格式,文件会损坏。
我测试了以下格式进行转换:
- utf8 - base64 - 二进制
以下是我的做法:
// /* 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)
3个回答

1

对于任何通过此主题的人,我的解决方案:

(请记住下载文件的实际更好解决方案:使用带有标题“Content-disposition”的API响应发送文件,或者像这样使用express)

后端(Node)的工作方式如下:

 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 })
    } 
  })

这里:

  • target 是前端文件的路径和名称及其扩展名(/path/name.ext
  • fileName 只是名称和扩展名(name.ext
  • data 是由 readFile 发送的数据({"type":"Buffer","data":[72,82,65,67,67,69,83,83,32,10]}

前端(React)的工作方式如下:

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)

      }
    })

1
"csv" 的字符集内容类型为 text/csv - ArifMustafa

0

@Hadock 如果你想下载扩展名为 .csv 的文件,则需要传递文件类型,例如

let blob = new Blob([csv], { type: 'application/vnd.ms-excel' });

而不是

let blob = new Blob([read])

别忘了带上文件名和扩展名(test.csv)。

对于 Excel 文件,我使用了不同的插件 exceljs demo


它适用于 .csv,但不适用于 .xlsx。我在帖子中添加了一些细节,例如后端发送的 JSON。我看了你的例子,但我不明白应该如何将数据存储在文件中。 - Hadock
@Hadock 创建一个 Plunker,我会帮助你生成 Excel 文件。 - Rishabh Garg

0

你不能直接将JSON数据保存到.xlsx文件中,但可以使用类似于“sheetjs”(https://sheetjs.com/)的库将JSON数据转换为Excel格式。

var ws_name = filename;//"SheetJS";
var wb = new Workbook(), ws = sheet_from_array_of_arrays(data);
/* add worksheet to workbook */
wb.SheetNames.push(ws_name);
wb.Sheets[ws_name] = ws;
var wbout = XLSX.write(wb, { bookType: 'xlsx', bookSST: true, type: 'binary' });
saveAs(new Blob([s2ab(wbout)], { type: "application/octet-stream" }), filename + ".xlsx")

为什么我无法导入“sheet_from_array_of_arrays”和“s2ab”,而且在SheetJS文档中也找不到它们? - Hadock
好的,正确的路径是“XLSX.utils.sheet_add_aoa(data)”和“XLSX.utils.s2ab(wbout)”。无论如何,我的数据不是“aoa”,而是一个缓冲区“[72,82,65,67,67,69,83,83,32,10]”。 - Hadock

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接