我正在尝试创建一个csv文件,插入我的数据并从浏览器下载。我正在express js后端创建csv文件,并将链接发送到react js前端以通过浏览器下载。
我正在使用快速csv插件将数据写入csv。这是我的密码。
async function dataToCSV(data) {
var fileName = "report.csv";
var ws = await fileSystem.createWriteStream('../' + fileName);
var csv;
await fastcsv.write(data, { headers: true }).on("finish", function () {
console.log(ws);
csv = "<a href='../report.csv' download='report.csv' id='download-link'></a>";
}).pipe(ws);
return csv;
}
在得到这个方法的输出后,我将把它发送到前端。
return dataToCSV(jsonData).then((response) => {
return {
headers,
statusCode: 200,
body: response,
type: 'binary'
};
}).catch((e) => {
return {
headers,
statusCode: 400,
body: {
error: e.message
}
};
})
前端得到如下所示的响应。
<a href='report.csv' download='report.csv' id='download-link'></a>
然后我使用以下代码通过浏览器使用react js下载它。
var div = document.createElement('div');
div.innerHTML = response.trim();
document.body.appendChild(div);
var downloadLink = document.getElementById('download-link');
if (downloadLink !== null) {
downloadLink.click();
}
document.body.removeChild(div);
文件是在后台创建的,我可以确认。但当它从浏览器下载时,它会失败。日志中没有错误。浏览器显示
失败-无文件
我不明白它为什么失败。我认为响应是在创建文件之前发送到前端的,或者它无法识别创建文件的路径。但我不确定。请帮我找到解决方案。
.pipe()
不会返回Promise,因此您的await
不会执行预期操作。如果您想等待流使用Promises完成,请参阅stream.pipeline.
可能还有其他因素在起作用——例如,您的HTTP处理程序看起来一点也不像express
处理程序(即使您的问题包括"express"标记(。如果它是一个无服务器功能(AWS Lambda?(,您可能需要修改您的策略;根据平台的不同,功能可能无法提供文件。
在任何情况下,最好构建一个CSV文件,并使用流将其直接发送到客户端,而无需写入文件系统(尽管在AWS Lambda上的Node中似乎不可能(。如果做不到这一点,总是可以将文件流式传输到云存储解决方案,并为客户端提供预签名的URL。