In my webpage, a user is supposed to upload a zipped file. Within the zipped file are multiple xlsx files. I am using below code for reading ZIP file , It works great on Chrome but when I am trying to run on IE11 it says, could not find resolve for null object or reference
var JSZip = require('JSZip');
fs.readFile{ filePath, function(err, data) {
if (!err) {
var zip = new JSZip();
zip.loadAsync(data).then(function(contents) {
Object.keys(contents.files).forEach(function(filename) {
zip.file(filename).async('nodebuffer').then(function(content) {
var dest = path + filename;
fs.writeFileSync(dest, content);
});
});
});
}
});
When I try to debug it is not going inside loadAync function.
Related
I'm trying to download an excel file with the click of a button in my web application. I can see the data come across from my api request, but when I download the file and try to open it I either get a:
"We found a problem with some content in ... Do you want us to try to recover as much as possible" YES => "This file is corrupt and cannot be opened"
or
"... the file format or file extension is not valid. Verify that theh file has not been corrupted..."
If I open the original file saved it works fine so it's not the file. I think the problem is somewhere in the React Code.
I've looked at a lot of other questions on Stack Overflow about this same topic but none of the answers seem to be working for me.
React
React.useEffect(() => {
if (template && downloadBtn.current != null) {
axios
.get<Blob>(
`/template`,
{ params: { filename: template } }
// responseType: 'blob' or "arraybuffer" don't work for me
)
.then((resp) => {
console.log(resp.data);
var blob = new Blob([resp.data], {
type: resp.headers['content-type'] // tried keeping and removing this
}); // removing this assuming resp.data is already a blob didn't work
console.log(blob); // PK ... b���C���h����ؒ )���G+N�
const url = window.URL.createObjectURL(blob);
console.log(url); // blob:http://localhost:3000/29fd5f64-da6a-4b9c-b4a4-76cce1d691c8
if (downloadBtn.current != null) {
downloadBtn.current.download = template;
downloadBtn.current.href = url;
}
});
}
}, [template, downloadBtn.current]);
Flask
#app.route('/template', methods=['GET'])
def template():
filename = getRouteData(['filename']) # helper function I wrote to get request.body data
print(os.path.join(
app.config['templates_folder'], filename), file=sys.stderr)
return send_file(os.path.join(app.config['templates_folder'], filename))
# adding as_attachment=True doesn't work for me either
# file path is correct
I have a react app that contacts a backend dotnet controller to download various types of files. When I download most files everything works fine and the files are correct. When I download a json file, the file contains only [object Object]. Below is the code in the call method.
public downloadFile = async (fileId: number) => {
const response = await HttpUtility.postFileDownload<any>(DOWNLOAD_URL + fileId, {})
let fileName = response.headers['content-disposition'].split('filename=')[1].split('\'')[2]
if (fileName === undefined) {
fileName = `file-id-${fileId}-${moment().format()}`
}
fileDownload(response.data, fileName, response.headers['content-type'])
}
When, I look at the dev tools in Chrome, the response looks correct. Any pointers on what I need to do to correct this?
This May works
fileDownload(JSON.stringify(response.data), fileName, response.headers['content-type'])
This question has been asked a fair bit before, but none of the solutions I've seen seem to work, potentially because of the way I stream the file back to the browser. The CSV I ultimately want is in a private S3 bucket and because of security middleware, I have to get it via a NodeJS endpoint. The code for the API is below.
exports.download = function(req, res) {
var recording = req.vsRecording,
s3 = new AWS.S3();
if(recording.data_uri){
try{
res.set('Content-Type', 'application/octet-stream');
var fileStream = s3.getObject({Bucket: 'processing-dispatched', Key: recording._id + '/aggregated.csv'}).createReadStream();
fileStream.pipe(res);
}
catch(err){
res.status(500).json({error: err});
}
}
else {
res.status(500).json({error: 'Recording does not have a report file.'});
}
};
This works perfectly and I can get the content of the file back to the browser. When it goes wrong is trying to get that content into be opened as a file download. Is there a special way to handle downloading streams?
The closest I've got is this code on the client, which sometimes seems to work on localhost if I turn my adblocker off - but does not work in production.
$scope.download = function(){
Report.download($state.params.recordingId).then(function(data){
var csvContent = "data:text/csv;charset=utf-8," + data.toString();
var encodedUri = encodeURI(csvContent);
window.open(encodedUri);
});
Report.download is just an angular service wrapper around my Node endpoint, it returns a promise and resolves the content of the file in the data variable.
reason might be the browser blocking the new window.
Allow all sites to show pop-ups in browser setting.
you can try thing in different ways create a file in node with fs and return url to the Front-end
or
you can Try the following code
$scope.download = function() {
Report.download($state.params.recordingId).then(function(data) {
var csvContent = "data:text/csv;charset=utf-8," + data.toString();
var a = document.createElement('a');
a.href = "data:application/csv;charset=utf-8," + csvContent;
a.setAttribute('download', "abc.csv");
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
});
}
Here is the thing:-
I have over a thousand images saved locally in my mac. I have a landing page that mocks an ecommerce deal site. It would be tedious to have to manually type in the src url in the img tag for a thousand pictures. Thus, i thought i could somehow have this images dumped in a cloud storage or something and use REST api get method to extract these images in a response.data. Then assign it to a $scope variable and use ng-repeat to bind the images in my landing page view. Is this possible? If not, what are the alternatives? SQL database?
Appreciate your help. P.S. I am totally a beginner at web development.
Install node.js. It's Javascript for a server which should make it pretty easy since you already know Javascript.
On a Mac, you can install node like this:
brew install node
Use this node.js code (credit to codepedia.com, tweaked a little by me):
//include http, fs and url module
var http = require('http'),
fs = require('fs'),
path = require('path'),
url = require('url');
imageDir = './images/';
//create http server listening on port 3333
http.createServer(function (req, res) {
//use the url to parse the requested url and get the image name
var query = url.parse(req.url,true).query;
pic = query.image;
if (typeof pic === 'undefined') {
getImages(imageDir, function (err, files) {
var imageList = JSON.stringify(files);
res.writeHead(200, {'Content-type':'application/json'});
res.end(imageList);
});
} else {
//read the image using fs and send the image content back in the response
fs.readFile(imageDir + pic, function (err, content) {
if (err) {
res.writeHead(400, {'Content-type':'text/html'})
console.log(err);
res.end("No such image");
} else {
//specify the content type in the response will be an image
res.writeHead(200,{'Content-type':'image/jpg'});
res.end(content, "binary");
}
});
}
}).listen(3333);
console.log("Server running at http://localhost:3333/");
//get the list of jpg files in the image dir
function getImages(imageDir, callback) {
var fileType = '.jpg',
files = [], i;
fs.readdir(imageDir, function (err, list) {
for(i=0; i<list.length; i++) {
if(path.extname(list[i]) === fileType) {
files.push(list[i]); //store the file name into the array files
}
}
callback(err, files);
});
}
Run this from the command line to start you new image server (assuming you named the file "server.js"):
node server.js
You should see this text appear on the command line:
Server running at http://localhost:3333/
You can quickly test it by going to this address in your browser and you should see a JSON object showing you an array of all the filenames in the "./images" directory. By the way, this program assumes you're putting the images folder in the same directory as "server.js". You can put the images directory anywhere and just change the path of the variable "imageDir".
Now you can load the list of files from Angular using this code in your controller:
$http.get("http://localhost:3333", function(data) {
$scope.images = data;
});
In your view, you can now use an ng-repeat like this to display all the images:
<div ng-repeat="image in images" style="padding: 8px">
<img src="http://localhost:3333/image={{ image }}">
</div>
Note: this will work if you run it locally on your Mac or if you upload all the images to a server on which you can use Node.js.
In my project i just wanted to implement upload and download features. I have done upload functionality with AngularJS and Node.js. But here the problem is to upload a file(.pdf, all image formats) into somewhere in the system. Say for example, my project is located in D drive. Though i have to upload a file into C drive or some other drive in my computer and i have done it successfully. But when i try to read the file location from Node.js and pass the path to angular, everything is ok and file is downloaded in the browser. when i try to open a downloaded file it sends back a response - fatal error/ nothing to show. I have tried with blob only when i send a filestream instead a path to Angular.
The code is as follows
var file = new Blob([data], {type: 'application/pdf'});
var fileURL = URL.createObjectURL(file);
window.open(fileURL);
where data is a file stream response from the server.
not my code but try this to save a BLOB:
var saveData = (function () {
var a = document.createElement("a");
document.body.appendChild(a);
a.style = "display: none";
return function (data, fileName) {
var json = JSON.stringify(data),
blob = new Blob([json], {type: "octet/stream"}),
url = window.URL.createObjectURL(blob);
a.href = url;
a.download = fileName;
a.click();
window.URL.revokeObjectURL(url);
};
}());
var data = { x: 42, s: "hello, world", d: new Date() },
fileName = "my-download.json";
saveData(data, fileName);
Source: http://jsfiddle.net/koldev/cw7w5/
If you want to force the download of a linked file you could use the HTML5 a option download
<a download="filename_for_download" href="path/to/the/file"> Clicking o will force a download</a>
Some more information: https://developers.google.com/web/updates/2011/08/Downloading-resources-in-HTML5-a-download?hl=en
keep the (not existing) support of older browsers in mind
One Note: Your upload process ("to upload a file into C drive or some other drive in my computer") sounds like it may be improved or rethought.