ExpressJS - 在服务器端生成 CSV 文件并启用从客户端下载



我正在使用ExpressJS开发一个Web应用程序。

页面上有一个"创建"按钮。我想要实现的是,当单击按钮时,它会向服务器端发送 Post/Get 请求,然后服务器端触发一个生成 CSV 文件并将其发送回客户端进行下载的过程。

我正在考虑使用json2csv.

客户端:

$.ajax({
type: "POST",
url: "/incidents/createTable",
success: function() {
// HOW TO GET THE RETURNED DATA TO A DOWNLOADABLE FILE?
}
});

服务器端和incidents路由器(下面的代码片段是从json2csv官方npmjs页面复制的):

const { AsyncParser } = require('json2csv');
// THIS FUNCTION SHOULD GENERATE A CSV FILE IN MEMORY
router.post("/createTable", async function(req, res, next) {
console.log("flag 1");  // For flagging
const fields = ['field1', 'field2', 'field3'];
const opts = { fields };
const transformOpts = { highWaterMark: 8192 };
const asyncParser = new AsyncParser(opts, transformOpts);
console.log("flag 2");  // For flagging
let csv = '';
asyncParser.processor
.on('data', chunk => (csv += chunk.toString()))
.on('end', () => res.send(csv))
.on('error', err => console.error(err));
});

当我运行 Web 应用程序并单击"创建"按钮时,服务器挂在那里,它通过了"标志 2",从未通过asyncParser.processor。在客户端,POST 请求也挂在那里,没有状态代码。

经过大量挖掘,终于想出了一个解决方案。

服务器端:

var stream = require('stream');
//...
router.post("/createTable", async function(req, res, next) {
var fileContents = Buffer.from(JSON.stringify({
sampleTime: '1450632410296',
sampleData: '1234567890'
}));
var readStream = new stream.PassThrough();
readStream.end(fileContents);
res.set('Content-disposition', 'attachment; filename=' + "download.csv");
res.set('Content-Type', 'text/csv');
readStream.pipe(res);
});

客户端:

$.ajax({
type: "POST",
url: "/incidents/createTable",
success: function(result) {
var blob=new Blob([result], {type: 'text/csv'});
var link=document.createElement('a');
link.style = "display: none";
document.body.appendChild(link);
var url = window.URL.createObjectURL(blob);
link.href = url;
console.log(url);
link.download="download.csv";
link.click();
window.URL.revokeObjectURL(url);
}
});

您缺少一个部分,即提供数据。解析器不会做任何事情,直到你这样做。这也是一个请求,因为res.send永远不会被触及。

直接从文档中:

asyncParser.input.push(data); // This data might come from an HTTP request, etc.
asyncParser.input.push(null); // Sending `null` to a stream signal that no more data is expected and ends it.

这是将生成的完整代码

"field1","field2","field3"
1,2,3

在 GET/createTable 上

const { AsyncParser } = require('json2csv');
const express = require('express');
const app = express();
app.get("/createTable", async function(req, res, next) {
console.log("flag 1");  // For flagging
const fields = ['field1', 'field2', 'field3'];
const opts = { fields };
const transformOpts = { highWaterMark: 8192 };
const asyncParser = new AsyncParser(opts, transformOpts);
console.log("flag 2");  // For flagging
let csv = '';
asyncParser.processor
.on('data', chunk => (csv += chunk.toString()))
.on('end', () => res.send(csv))
.on('error', err => console.error(err));
asyncParser.input.push('{ "field1": 1, "field2": 2, "field3": 3 }');
asyncParser.input.push(null); // Sending `null` to a stream signal that no more data is expected and ends it.
});
app.listen(3000);

最新更新