将冗长的数据下载为CSV文件

时间:2013-09-06 16:28:35

标签: node.js angularjs csv download

我需要将视图中显示的表格内容下载为CSV文件。我有代码来正确格式化表的内容,以便它可以存储为.csv文件(例如,列分隔符是逗号,表的每个记录都在一个新行中)。

所以,在我的控制器中,我有以下代码:

window.location.href = '/download?data=' + encodeURIComponent($scope.csvString);

我将NodeJ用于服务器部分。在这里,我有以下路由处理程序:

app.get('/download', function (req, res) {
    var data = req.query.data;

    res.attachment('data.csv');
    res.setHeader('Content-Type', 'text/csv');
    res.end(data);
});

这完全没问题。下载工作,下载文件中的数据采用完美的CSV格式。没有问题。

当表中记录太多时,即数据量巨大时,会出现问题。因此,查询参数非常庞大,我认为它超出了限制,因此,GET请求返回400(错误请求)错误 - 请注意,根据我的分析,请求永远不会到达服务器,而是我观察到请求使用Chrome开发者工具失败。在浏览器中,网址只是www.my_domain.com/download?data=the_lengthy_data。而已。网页为空/空,没有下载文件。

因此,我想知道如何下载冗长的数据?我遇到的所有示例都执行GET请求,因此我必须将冗长的数据作为查询参数传递。还有其他方法吗?

3 个答案:

答案 0 :(得分:5)

对你的问题不是一个真正的答案,但从它的外观来看,你试图“强制”下载客户端上生成的数据。然后在这种情况下,您可以创建一个数据URI,其中直接包含数据。

你的角度JS模板:

<a href="data:base64,{{btoa(csvString)}}" download>Download CSV</a>

你的控制器:

$scope.btoa = function (val) {
    return btoa(val);
};

因此,您的DOM应如下所示:

<!-- The link contains data to the CSV string "a,b,c" -->
<a href="data:text/csv;base64,YSxiLGM=" download>Download CSV</a>

点击该链接可下载CSV文件。

修改

您还可以使用名为FileSaver.js的库强制下载字符串。

像往常一样,你会获得CSV,但这一次,你会把它转换成BLOB。

var csvBlob = new Blob([$scope.csvString], { type: 'text/csv;charset=utf-8' });

然后,您可以调用FileSaver.js'saveAs函数。

saveAs(csvBlob, 'mydata.csv');

答案 1 :(得分:0)

You're right about the character limit in the URL.通常,冗长的数据会通过正文传递,因为理论上它没有字符限制。

但是,您应该避免尝试在GET请求中传递正文。 The XMLHttpRequest specs on the send method say - &#34;如果请求方法是GET或HEAD,则将数据设置为null。&#34;。

所以我建议你使用POST请求并在体内传递参数。因此,您还需要使用app.post(&#39; download&#39;,...)重写处理程序,然后为这些参数解析request.body。

另外,根据我的理解,您尝试做的事情,POST似乎是更合适的HTTP动词,因为您提供了一个数据块供服务器处理和回传。

答案 2 :(得分:0)

我们需要更改nodejs代码,如下所示。 Nodejs代码

    function downloadableFile(req, res) {
        res.attachment(document.title);
        var bufferStream = new stream.PassThrough();
        // we read the file in buffer.
        bufferStream.end(new Buffer(document.buffer));
        return bufferStream.pipe(res);
    }

Angularjs不理解二进制数据。所以在前端我们可以使用第三方工具,如FileSaver.js&#39;

var csvBlob = new Blob([$ scope.csvString],{type:&#39; text / csv; charset = utf-8&#39;}); saveAs(csvBlob,&#39; mydata.csv&#39;);

或者我们可以像这样使用angularjs代码。 Angularjs Code。

    downloadDocument = function (path,id,type) {

    $http.get(path).then(function (data) {
    if (data.status === 404) {
        mpToastService.showToastHeader('error', 'Error downloading document');
    } else {
        var blob = new Blob([data.data],{
        type: type + ";charset=utf-8;"
        });
        $("#" + id).attr("href", window.URL.createObjectURL(blob));
        document.getElementById(id).click();
    }
    });
    }    

    //In html file, we need to include these two lines.

    <a ng-click="downloadDocument(document.path,document.id,document.mimeType)" >document.title</a>    
    <a id="document.id"></a>

此角度代码将在前端下载二进制数据,然后弹出下载模式,在流行的浏览器中没有任何数据限制。但一般来说,除非客户有特殊要求,否则这不是好的做法。