我需要将视图中显示的表格内容下载为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请求,因此我必须将冗长的数据作为查询参数传递。还有其他方法吗?
答案 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>
此角度代码将在前端下载二进制数据,然后弹出下载模式,在流行的浏览器中没有任何数据限制。但一般来说,除非客户有特殊要求,否则这不是好的做法。