我正在创建一个允许用户上传CSV的应用程序。 CSV只是逗号分隔的文件。
在前端,我通过PUT请求将文件发送到后端:
Reactjs | fileupload_frontend.js
sendFile = () => {
const data = new FormData();
data.append('file', this.myCSV_file);
axios.post('/parse-csv', data)
.then(response => console.log('File sent to server for parsing')
.catch(error => console.log(error);
}
上面的代码已成功将上传的CSV(信息)发送到我的服务器,该服务器正在/parse-csv
端点进行监听。
我正在使用csv-parser
npm软件包来解决此问题。
Nodejs | fileupload_backend.js
const csv = require('csv-parser');
const fs = require('fs');
const results = [];
app.post('/parse-csv', (request, response) => {
fs.createReadStream(request.files.file.data) { // this is a buffer on the req obj
.pipe(csv())
.on('data', results.push())
.on('end', (results) => {
console.log(results);
}
}
}
作为参考,从前端到后端的请求对象如下:
Request from upload { name: 'data.csv',
data: <Buffer 22 89 56 24 5y 86 k9 22 . ... >,
encoding: '7bit',
truncated: false,
mimetype: 'text/csv',
md5: [Function: md5],
mv: [Function: mv] }
每个请求都出错,并显示一条消息,该消息似乎与我的标题行(csv文件中的第一行)相关,并显示一条消息:
错误:ENOENT:没有这样的文件或目录,请在“我的,标题,行,引用,此处”打开
...然后数据如下所示。
我是否必须将CSV文件保存在某个目录中,然后首先对其进行解析?我只是在寻找一种将CSV解析为json的方法,因此我可以将每一行作为条目插入到数据库中。
答案 0 :(得分:1)
看看下面的软件包https://www.npmjs.com/package/xlsx。它将使您可以互换地解析csv和大多数电子表格文件格式。
您可以通过以下方式使用它:
const XLSX = require('xlsx')
const workbook = XLSX.readFile(source_file_path)
const sheetName = workbook.SheetNames[0]
const sheet = workbook.Sheets[sheetName]
const obj = XLSX.utils.sheet_to_json(sheet)
这应适用于库支持的任何电子表格格式。
这确实意味着必须将文件保存在目录结构中的某个位置,以使XLSX.readFile
正常工作。
答案 1 :(得分:1)
fs.createReadStream接受路径作为其参数,该参数可以是字符串,Buffer或URL。
自从传递Buffer
以来,它会尝试打开Buffer
作为路径,因此会出错
错误:ENOENT:没有这样的文件或目录,请在“我的,标题,行,引用,此处”打开
您需要先通过Buffer创建流,然后再将其通过管道传输到CSV分析器。 有多种解决方法。实现使用缓冲区的可读流是其中之一。 例如
const { Readable } = require('stream');
class BufferStream extends Readable {
constructor(opts) {
super(opts);
this.buf = opts.buf;
}
_read(size) {
this.push(this.buf);
this.push(null); // signal end of stream
}
}
现在实现请求处理程序以使用此类。
app.post('/parse-csv', (request, response) => {
const results = [];
const bufStream = new BufferStream(request.files.file.data);
bufStream.pipe(csv())
.on('data', (data) => results.push(data))
.on('end', (results) => {
console.log(JSON.stringify(results));
response.sendStatus(200);
}
}
}