NodeJS - 提示下载CSV文件

时间:2016-07-20 10:52:00

标签: node.js csv

我正在努力 - 在执行了一些承诺后 - 将CSV结果与状态响应一起提供详细信息。

响应确实为我提供了CSV的数据,但我似乎无法让浏览器将此数据下载到CSV文件中。

router.post('/getSalesOrders', function (request, response) {
    var data = request.body;
    salesOrderActions.retrieveSalesOrders(data) //
        .then(function (result) {
            response.setHeader('Content-disposition', 'attachment; filename=testing.csv');
            response.set('Content-Type', 'text/csv');
            response.json(result[0].message).send(result[0].file);
        })
        .catch(function (err) {
            console.log(err);
            if (err.statusCode) {
                response.json(err);
            }
            else {
                var error = output.getCriticalErrorResult(c.titles.SERVICE_CRITICAL_ERROR, c.messages.UNKNOWN_ERROR, err.message);
                response.json(error);
            }
        });
});

我的结果对象是在salesOrderActions

中创建的

我在这里使用npm package json2csv

var fields = ['id',.....];
var csv = csvParser({ data: unmatchedLines, fields: fields });

return {
     file: csv,
     message:
         output.getSuccessResult(
             titles.SALES_ORDER_SUCCESS_RETRIEVAL,
             salesDataForModel.identifier
         )
}

我对浏览器的回复如下: enter image description here enter image description here

所以我的消息似乎没有被发送似乎我确实获得了CSV数据,但没有作为要下载的文件。 我该如何管理?

作为旁注,我的前端是React

修改

使用octed标头的响应:

enter image description here enter image description here

3 个答案:

答案 0 :(得分:1)

试试这段代码:

router.post('/getSalesOrders', function (request, response) {
    var data = request.body;
    var fs = require('fs');

   salesOrderActions.retrieveSalesOrders(data) //
    .then(function (result) {
       //**********
        var file = "testing.csv";
        response.setHeader('Content-disposition', 'attachment; filename=testing.csv');
        response.set('Content-Type', 'text/csv');
        var filestream = fs.createReadStream(file);
        filestream.pipe(res);
       //*********
    })
    .catch(function (err) {
        console.log(err);
        if (err.statusCode) {
            response.json(err);
        }
        else {
            var error = output.getCriticalErrorResult(c.titles.SERVICE_CRITICAL_ERROR, c.messages.UNKNOWN_ERROR, err.message);
            response.json(error);
        }
    });
});

答案 1 :(得分:1)

尝试:

  • 在Content-Disposition之前发送Content-Type
  • 引用文件名:filename =“testing.csv”

HTTP标头也不区分大小写,所以它不应该有所作为,但你应该编写Content-Disposition(大写字母D)。

response.set('Content-Type', 'text/csv');

response.setHeader('Content-Disposition', 'attachment; filename="testing.csv"');

如果这不起作用,您可以将Content-Type更改为application / octet-stream

这总是迫使浏览器下载从服务器发送的数据。

答案 2 :(得分:0)

实际上事实证明这是因为我正在做一个Ajax请求,它没有 - 默认情况下 - 提示浏览器下载任何文件。

我最后做了什么:

router.post('/getSalesOrders', function (request, response) {
    var data = request.body;
    salesOrderActions.retrieveSalesOrders(data)
        .then(function (result) {
            response.json(result);
        })
        .catch(function (err) {
            //...
        });
});

然后在我的前端,收到结果时:

salesOrderService.retrieveSalesOrderData()
.then(function (result) {
    self.convertAndDownloadCsv(result.unmatchedLines);
});

convertAndDownloadCsv: function (data) {
    if (data && data.length > 0) {
        var csvData = csvProcessor({ //using csv2json node js package
            data: data,
            quotes: '',
            del: ';'
        });
        var filename = "unmatchedLinesFromSalesOrders.csv";
        var blob = new Blob([csvData], { type: 'text/csv;charset=utf-8;' });
        if (navigator.msSaveBlob) { // IE 10+
            navigator.msSaveBlob(blob, filename);
        } else {
            var link = document.createElement("a");
            if (link.download !== undefined) { // feature detection
                // Browsers that support HTML5 download attribute
                var url = URL.createObjectURL(blob);
                link.setAttribute("href", url);
                link.setAttribute("download", filename);
                link.style.visibility = 'hidden';
                document.body.appendChild(link);
                link.click();
                document.body.removeChild(link);
            }
        }
    }
}

More info can be found here