How to download excel files generated by node [Node][Angular] - angularjs

I use the same way it's mentioned in [Node][Angular] How to download excel files generated by node
but still I don't get any popup to open or save. I could see the buffer in the Network window of Chrome.
Any help is appreciated.

On the client side you can use:
$http({method: 'GET', url: '/someUrl'}).
success(function(data, status, headers, config) {
let blob = new Blob([data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
const fileName = `file.xlsx`;
let file = new File([blob], fileName);
let fileUrl = URL.createObjectURL(file);
})
.error(function(data, status, headers, config){
});
I used File because it allows you to pass filename. You could skip this part and pass Blob to URL.createObjectURL. It opens window with download. Assuming your server code is correct. But if you see buffer in Chrome than it sends something.
For server side I usually use express res.sendFile. It needs you to create a file so you gave to clean up.

Related

large files failing download in nodejs

I have a service that builds a csv file, and returns it to the user. Currently using expressjs v4.14, nodejs v8.7.0. My problem is that I get a download failed due to 'network error' in chrome when I call the service for it to create a large csv file. With smaller files, the service works fine. I can also browse to the /temp/ folder, and the entire expected file exists. In each case of 'things i tried', I was able to download smaller files but not the large ones.
Service:
download.post('/csv', (req, res, next) => {
res.status(200).header('Content-Type', 'text/csv');
const newUUID = uuid.v1();
let ws: WriteStream = fs.createWriteStream(`${__dirname}/../../temp/${newUUID}.csv`);
ws.on('finish', () => {
res.download(`${__dirname}/../../temp/${newUUID}.csv`);
});
//csv file built here
ws.write('huge stuff easily 50k rows and 10 mb file');
ws.end();
});
Chrome Error:
Chrome's network tab and developer console do not give me any indication of what happened. This download popup is all I get. I cleared everything in cookies/cache just in case and it did not help.
Things I tried:
writing chunks directly to response stream.
using readable stream https://nodejs.org/api/stream.html#stream_readable_streams , converting String into bytes and piping it.
creating a file locally (writestream) and streaming it back (readstream pipe into res)
res.download(file) after writestream creating local file ended
Update:
Ended up trying the service from postman and it worked, so I think it is an angularjs issue.
Angularjs
$http({
cache: false,
url: "/download/csv",
headers: {
'accept': 'text/csv'
},
method: 'POST',
data: {
rows: rows,
title: title ? title : ''
}
}).success(function (data, status, headers, config) {
var anchor = angular.element('<a/>');
anchor.attr({
href: 'data:attachment/csv;charset=utf-8,' + encodeURI(data),
target: '_blank',
download: 'csv_info.csv'
})[0].click();
}).error(function (data, status, headers, config) {
});
Turned out to be a limitation from href attribute from the anchor tag created in angularjs. This was solved using FileSaver:
$http({
cache: false,
url: "/download/csv",
headers: {
'accept': 'text/csv'
},
method: 'POST',
data: {
rows: rows,
title: title ? title : ''
}
}).success(function (data, status, headers, config) {
var file = new File([data], "info.csv", {type: "text/csv;charset=utf-8"});
saveAs(file);
}).error(function (data, status, headers, config) {
});

can not upload the file with its extension and original path name using Multer and Node.js

I have one issue while uploading the file using Multer module from Node.js.I am explaining my code below.
server.js:
var multer = require('multer');
var upload = multer({ dest: './upload/' });
var cpUpload = upload.fields([{ name: 'images', maxCount: 1}]);
var app=express();
var server=http.createServer(app);
var admin=require('./route/route.js');
app.post('/uploadAll',cpUpload,function(req, res, next){
console.log('fiels',req);
})
supplierController.js:
var file=fileURL;
var curnum=(Math.random() * new Date().getTime()).toString(36).replace(/\./g, '');
var newPicpath=curnum+"_"+ file.name;
file.name=newPicpath;
console.log('file',file);
$scope.upload=Upload.upload({
url: '/uploadAll',
method:'POST',
data:{
images: file,
},
headers : {
'Content-Type': 'multipart/form-data'
},
}).success(function(data, status, headers, config) {
}).error(function(data, status) {
console.log('err file',data);
})
inside console message i am getting the below file data.
Blob
$ngfName:"vse123ertgf_1.jpg"
name:"vse123ertgf_1.jpg"
size:8607
type:"image/jpeg"
Here you can check my file name is containing one random number with it.When i am uploading the file the file is uploaded inside the given folder but taking another random number(i.e-75149c6770ea216b5ad8aafa7698539d) as its name and without extension(i.e-.jpg or png).Here also i am getting the error response inside error function in client side.I am using ng-file-upload to upload the file.Here i need the file should upload inside the required folder using its original name what its taking in client side.Please help me to resolve this issue.
Satya. The issue you are facing is very common. Please read the following post for some beautiful insight. I had the same issue and I resolved it using this post. For further issue please comment below, will help you out.

How to post a request and download file to disk with angular?

In angular, I want to download a text file containing a csv of userdata. Usually I have a form with a post action, but I want the user to stay on the same page, but return the csv data without any page referesh. The following is my post command:
$http({
url: "api/getUserData",
method: "POST",
data:{user_id:app.user_id}
}).success(function(data, status, headers, config) {
// data gets returned here
}).error(function(data, status, headers, config) {
$scope.status = status;
});
My problem is, the "data" that comes back from the post is a csv file. how can I get the data to actually "download" to the user's computer instead of living in the javascript? Is this even possible?
Here is the link to solution. It uses HTML5 FileSaver API to save the file as BLOB
You can do this :
Create temporary anchor ,
encode, your data & name your file using download attribute,
and then, fire a click event on it.
finally, remove the inserted element .
$http({
url: "api/getUserData",
method: "POST",
data:{user_id:app.user_id}
}).success(function(data, status, headers, config) {
// data gets returned here
var anchor = angular.element('<a/>');
angular.element(document.body).append(anchor); // Attach to document
anchor.attr({
href: 'data:attachment/csv;charset=utf-8,' + encodeURI(data),
target: '_blank',
download: 'myFileName.csv'
})[0].click(); // fire a click event.
anchor.remove(); // Clean it now ...
}).error(function(data, status, headers, config) {
$scope.status = status;
});

angular http get, download file from spring mvc server

I'm using apache commons IOUtils copy method to send file from server to angularjs.
This is my controller :
#RequestMapping(value="/download", method = RequestMethod.GET)
public void downloadFile(HttpServletResponse response) {
response.setContentType("image/jpg");
try {
File file = new File(filePath);
InputStream inputStream = new FileInputStream(file);
IOUtils.copy(inputStream, response.getOutputStream());
} catch (...) {
.......
}
In angularJs controller :
$http({
method: 'GET',
url: '.../download',
headers: {'Content-Type': 'image/jpg'}
})
.success(function(data, status){
console.log(data);
var blob = new Blob([data], {type: 'image/jpg'});
saveAs(blob, 'test.jpg');
})
.error(function(data, status){
....
})
When I download the file in the client side, I can't read it. When I open it with notepad++ I find that special characters are modified.
For example, when I open the original file with Notpad++, I get a line like this :
òŽsCJVäl·²HWƒ…;¹(òÈ$ÓÒ«Á‘{S€~9ÎsŠÒogk
The same line, when I open the downloaded file with notepad++ becomes :
��sCJV�l��HW��;�(��$�Ӂҫ��{S�~9�s��ogk
However, when I put the download link (localhost/myApplication/download) directly in a browser, it works correctly. Files are supposed to be encrypted and authorization is needed to download a file, so I have to use angular HTTP get.
Any help would be appreciated.
I had to add responseType to HTTP get request :
$http({
method: 'GET',
url: '.../download',
responseType: 'arraybuffer'
})
.success(function(data, status){
console.log(data);
var blob = new Blob([data], {type: 'image/jpg'});
saveAs(blob, 'test.jpg');
})
.error(function(data, status){
....
})
Now it is working.

download .zip file from server in nodejs

I am using MEAN, in which I want to allow user to download zip file from server.
So basically I have to do following things:
Create csv files from certain data.
Store that file into some directory.
Compress these file to zip.
When a user clicks on the button, zipped file should be downloaded and readable.
I have achieved 1,2,3 completely, and 4 partially. In this I have been able to successfully download zip file, but this file is in corrupted format and I am not able to read this file.
My code for download functionality is here:
html:
Download CSV Reports
angular part:
$scope.downloadFiles = function() {
$http({
method: 'GET',
url: '/download/csv/files'
}).
success(function(data, status, headers, config) {
var anchor = angular.element('<a/>');
anchor.attr({
href: 'data:attachment' + encodeURI(data),
target: '_blank',
download: 'filename.zip'
})[0].click();
}).
error(function(data, status, headers, config) {
alertify.error(data);
});
};
NodeJS:
var path = require('path'),
fs = require('fs');
exports.downaloadAllCsv = function(req, res) {
var file = 'local path to my zip file',
filename = path.basename(file);
res.setHeader('Content-disposition', 'attachment; filename=' + filename);
res.setHeader('Content-type:',' application/zip');
var filestream = fs.createReadStream(file);
filestream.pipe(res);
};
I used an npm library called express-zip (found here: https://www.npmjs.com/package/express-zip)
Using Node 4.X and Express 4.X, I can download a zip file from my browser. Getting it to work through Angular is what lead me to my own question:
Client download of a server generated zip file
Given all of that, here is my server code that worked:
Node (4.X) code with express-zip:
router.get('/bulkdownload',function(req,resp){
var titles = req.query.titles || [];
if ( titles.length > 0 ){
utils.getFileLocations(titles).
then(function(files){
let filename = '/tmp/zipfile.zip';
// .zip sets Content-Type and Content-disposition
resp.zip(files,filename);
},
_errorCb)
}
});
The utils.getFileLocations(titles) returns a promise where files is an array like this:
[{path: '/path/to/file/file.abc',name:'file.abc'},{...},{...},...]
My .zip file is not corrupted, and is readable.

Resources