作爲我的第一個Node.js項目,我一直在爲我的工作構建報告應用程序,用戶可以在其中搜索並將結果以CSV格式下載到計算機中。Heroku上的Node.js + Socket.IO - 文件正在下載
爲了實現這一點,我一直在使用Socket.IO將JSON數據傳遞迴我的application.js文件上的一個按鈕單擊事件。從那裏我使用json2csv模塊格式化數據。
這裏就是我遇到的問題...
我知道Heroku的使用短暫的文件存儲(這應該是罰款,因爲我只需要的文件是服務器上的會話反正和補充清理是好的),但我檢查文件是否存在回來陽性,即使我不能看到該文件,當我運行
heroku run bash ls
由於我使用的Socket.IO(據我所知,無論如何)正常的請求和響應回調函數參數不可用。我可以使用
data.setHeader()
這是套接字函數回調而不是response.setHeader()
來設置CSV的標題嗎?我是否需要從套接字中分離出事件監聽器,並直接從app.get
運行它?下面的代碼我有一個從它根據我的搜索事件和格式採用JSON數據:
socket.on('export', function (data) { jsoncsv({data: data, fields: ['foo', 'bar'], fieldNames: ['Foo', 'Bar']}, function(err, csv) { if (err) console.log(err); fs.writeFile('file.csv', csv, function(err) { if (err) console.log(err); console.log('File Created'); }); fs.exists('file.csv', function (err) { if (err) console.log(err); console.log('File Exists, Starting Download...'); var file = fs.createReadStream('file.csv'); file.pipe(data); console.log('File Downloaded'); }); }); });
UPDATE
下面是實際的客戶端代碼我用於構建和發送JSON作爲事件。確切的事件是$('#export').on('click', function() {});
。
server.on('listTags', function (data) {
var from = new Date($('#from').val()), to = new Date($('#to').val()), csvData = [];
var table = $('<table></table>');
$('#data').empty().append(table);
table.append('<tr>'+
'<th>Id</th>' +
'<th>First Name</th>' +
'<th>Last Name</th>' +
'<th>Email</th>' +
'<th>Date Tag Applied</th>' +
'</tr>');
$.each(data, function(i, val) {
var dateCreated = new Date(data[i]['DateCreated']);
if (dateCreated >= from && dateCreated <= to) {
data[i]['DateCreated'] = dateCreated.toLocaleString();
var tableRow =
'<tr>' +
'<td>' + data[i]['ContactId'] + '</td>' +
'<td>' + data[i]['Contact.FirstName'] + '</td>' +
'<td>' + data[i]['Contact.LastName'] + '</td>' +
'<td>' + data[i]['Contact.Email'] + '</td>' +
'<td>' + data[i]['DateCreated'] + '</td>' +
'</tr>';
table.append(tableRow);
csvData.push(data[i]);
}
});
$('.controls').html('<p><button id="export">Export '+ csvData.length +' Records</button></p>');
$('#export').on('click', function() {
server.emit('export', csvData);
});
});
您可以使用http服務器(使用http也可以將搜索查詢發送到服務器)更容易地使用響應頭。作爲一個小貼士:不是創建一個文件,然後從它創建一個讀取流,爲什麼不直接創建一個流,將其傳遞給'data'並將它寫入csv變量? 'var stream = new stream.Writeable(); stream.pipe(數據); stream.write(csv,'utf8',function(){console.log('done')});'[reference](http://nodejs.org/api/stream.html#stream_new_stream_writable_options) – MarijnS95
Thanks for the小費,我不知道這是可能的,所以我會試一試。我是否還需要設置文件的標題?否則,我在開發週期的這個階段使用Socket.IO,儘管我不確定這是否是我需要的。 – ventismith
你如何處理客戶端的下載?如果您使用正確的MIME類型發送文件(在您的案例中爲'text/csv'),瀏覽器就會喜歡它。如果你只是運行一個簡單的網頁,並且如果你的服務器已經有一個http服務器來處理該網頁,我建議使用HTTP。將流傳輸到客戶端非常容易,您還可以對其進行編碼(以節省帶寬)。 – MarijnS95