使用 node.js 和 node-csv-parser(节点模块)提示 csv 文件下载为弹出窗口

Posted

技术标签:

【中文标题】使用 node.js 和 node-csv-parser(节点模块)提示 csv 文件下载为弹出窗口【英文标题】:Prompt a csv file to download as pop up using node.js and node-csv-parser (node module) 【发布时间】:2012-10-15 17:33:17 【问题描述】:

最近我开始使用 node.js。在我的一个项目中完成要求时,我遇到了一个问题,我应该能够动态地将一些数据写入 csv 文件,并让它作为弹出窗口提示用户下载(带有保存和取消选项 - 就像我们通常一样看)。谷歌搜索了一段时间后,我决定使用 csv npm 模块https://github.com/wdavidw/node-csv-parser。我能够将数据写入文件并使用此模块保存。我想在保存/不保存文件的情况下提示保存此文件的弹出窗口。

我的代码看起来像这样:

    // Sample Data 
    var data = [["id", "subject1", "subject2", "subject3"], ["jack", 85, 90, 68], ["sam", 77, 89, 69]]

    // Server Side Code    
    var csv = require('../../node_modules/csv');            
    var fs = require('fs');

    createCSV = function(data, callback) 
        csv().from(data).to(fs.createWriteStream('D:/test.csv')) // writing to a file           
    

    // Client side call sample
    $("#exportToCSV").click(function() 
        callToServer.createCSV(data);
       return false;
    );

就编写 csv 文件而言,这很好用。

我想立即提示用户下载此文件。 如果可以在不保存文件的情况下完成此操作,那就太好了。 如何像在 php 中那样设置 content-type 和 content-disposition

非常感谢任何帮助。 -谢谢

【问题讨论】:

【参考方案1】:

Manish Kumar 的回答很到位 - 只是想包含一个 Express 4 语法变体来完成此任务:

function(req, res) 
  var csv = GET_CSV_DATA // Not including for example.

  res.setHeader('Content-disposition', 'attachment; filename=testing.csv');
  res.set('Content-Type', 'text/csv');
  res.status(200).send(csv);


【讨论】:

我觉得将setHeaderset 混合在一起会让人感到困惑和不一致。即使他们做同样的事情,他们来自不同的地方。使用 setHeader() 来自 NodeJS 的 http 模块。如果你使用res.set,那就是来自Express框架;如果你给它一个对象,它允许设置多个标题:res.set( 'Content-Disposition': 'attachment; filename=testing.csv', 'Content-Type': 'text/csv' )【参考方案2】:

我是这样做的:

http.createServer(function(request, response) 
    response.setHeader('Content-disposition', 'attachment; filename=testing.csv');
    response.writeHead(200, 
        'Content-Type': 'text/csv'
    );

    csv().from(data).to(response)

)
.listen(3000);

【讨论】:

请注意,完成上述服务器代码后,将客户端 location.href 链接到节点请求 url [无需 ajax 调用]。 Express 4 语法快速说明: res.setHeader('Content-disposition', 'attachment; filename=testing.csv'); res.set('Content-Type', 'text/csv'); res.status(200).send(csv); 没有 csv 库,也没有 express,而不是 csv() 行,你可以做 response.write(myCSVText);共鸣.end();【参考方案3】:

以下解决方案适用于 Express

express是进化的,不用设置附件和内容类型头,直接使用附件apihttp://expressjs.com/4x/api.html#res.attachment

注意:attachment() 不传输文件,它只是在标题中设置文件名。

response.attachment('testing.csv');
csv().from(data).to(response);

【讨论】:

【参考方案4】:

Express-csv 是一个很棒的模块,用于将 csv 内容写入来自 node.js 服务器的流,它将作为响应发送给客户端(并作为文件下载)。非常容易使用。

app.get('/', function(req, res) 
  res.csv([
    ["a", "b", "c"]
  , ["d", "e", "f"]
  ]);
);

文档:https://www.npmjs.com/package/express-csv

当你传递一个对象时,你需要显式地添加标题(如果你想要的话)。这是我使用npm mysql的示例

router.route('/api/report')
    .get(function(req, res) 
            query = connection.query('select * from table where table_id=1;', function(err, rows, fields) 
                if (err) 
                    res.send(err);
                
                var headers = ;
                for (key in rows[0]) 
                    headers[key] = key;
                
                rows.unshift(headers);
                res.csv(rows);
            );
    );

【讨论】:

【参考方案5】:

看看这个答案:Nodejs send file in response

基本上,您不必将文件保存到硬盘上。相反,请尝试将其直接发送到response。如果你使用的是 Express 之类的东西,那么它看起来像这样:

var csv = require('csv');
req.get('/getCsv', function (req, res) 
    csv().from(req.body).to(res);
);

【讨论】:

我用的不是express,只是node.js的一个自定义框架 无论哪种方式,http 模块都会使用相同参数 function (request, response) 的回调来响应请求。我认为您应该能够将 CSV 的结果直接发送到response

以上是关于使用 node.js 和 node-csv-parser(节点模块)提示 csv 文件下载为弹出窗口的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Node.js 将 JSON 数据从 Node.js 发送和获取到 HTML

使用 Angular.js 和 Node.js 构建实时应用程序的更好方法是啥?

使用 node.JS 和 Socket.IO 的路径和其他问题

node.js 的 BDD 和 TDD?

使用 jsdom 和 node.js 发布表单

使用骨干网和 node.js 进行 CSRF 防御