document.getElementById("uploadExcel").addEventListener("click", function () {
$("#uploadExcel").attr('disabled', true);
$('#loader').show();
if (selectedFile) {
var fileReader = new FileReader();
alert("2");
fileReader.onload = function (event) {
alert(event);
var data = event.target.result;
alert("3");
var workbook = XLSX.read(data, {
type: "binary", cellDates: true, dateNF: 'mm/dd/yyyy;#'
});
alert("4");
workbook.SheetNames.forEach(sheet => {
alert("5");
let rowObject = XLSX.utils.sheet_to_row_object_array(
workbook.Sheets[sheet]
);
let jsonObject = JSON.stringify(rowObject);
alert("Get Data");
getData(jsonObject);
//document.getElementById("jsonData").innerHTML = jsonObject;
});
};
alert("6");
fileReader.readAsBinaryString(selectedFile);
} else {
alert("error");
}
});
Now let me explain what is happening:
The page loads and I select the file to upload, it goes through even if it has excel errors, it will take the file and read it, convert it and throw errors.
So then I change that excel file to be error-free and try to click the upload button again, but this time the code enters the above function, and it won't go past fileReader.onload = function (event) it alerts "2" and then stops working.
Can you please tell me why is this happening and how to avoid this without a page reload, because if I do a page reload everything works as expected.
Thanks
I curently develop an app in javascript and I want to use cordova or phonegap to adapt my code to android, Iphone, etc. But in my app I save my file with this function :
function save(){
var myFileJSON = JSON.stringify(myFile);
try{
var blob = new Blob([myFileJSON], {type: "text/plain;charset=utf-8"});
saveAs(blob, "myFileJSON.txt");
} catch (e){
console.log('bug');
}
}
So with my phone application I want to save my file in a specific folder. Can I catch the save event and, for exemple, redirect immediately the path?
function saveCourseToFile() {
console.log("checkpoint 1");
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, onFSSuccess, onFSError);
}
function onFSSuccess(fileSystem) {
console.log("checkpoint 2");
console.log("Opened file system: " + fileSystem.name);
fileSystem.root.getFile("readme.txt", {create:true, exclusive:false}, gotFileEntry, onFSError);
}
function gotFileEntry(fileEntry) {
console.log("checkpoint 3");
fileEntry.createWriter(gotFileWriter, onFSError);
}
function gotFileWriter(writer) {
writer.onwrite = function(evt) {
console.log("checkpoint 4: write success!");
};
writer.write("test test test");
}
You can also check this link for your reference.
How can I convert a file (png/jpg/word/excel etc) to base64 format if I have url of the file (in the browser's sandboxed LocalFileSystem) which is already there in client system using javascript.
I had tried using creating canvas(image).
I also tried file control.
I don't want to use any control as we have url of the file in the sqllite db.
I tried
function UploadAttachmentfile() {
try {
if(objAttachment.length >0)
{
var ctn = objAttachment.length;
for (var j = 0; j < ctn; j++) {
var row = objAttachment[j].IMGS; \\image
var fname = row.split('\\').pop().split('/').pop();
alert(fname);
window.requestFileSystem(LocalFileSystem.TEMPORARY, 0, function (fs) {
alert('request file system');
fs.root.getDirectory("Foldername", null, function (entry) {
alert('ENTRY : '+entry);
entry.getFile(fname, null, function (fileEntry) {
fileEntry.file(gotFile, fail);
}, fail);
}, fail);
}, fail);
function gotFile(file) {
readDataUrl(file);
}
function readDataUrl(file) {
var reader = new FileReader();
reader.onloadend = function (evt) {
alert("Read as data URL");
alert("target result :"+evt.target.result);
};
reader.readAsDataURL(file);
}
function fail(evt) {
alert('fail');
alert(evt.target.error.code);
}
}
}
}
catch (err) {
}
}
But it always alert fail only.
If you want to get the file on the user's computer WITHOUT the user selecting it (EVERY SESSION AGAIN), then, you can not do it (thank <enter deity here>). I highly reccomend to read this answer linked here for a complete and up-to-date explenation.
If however your user selects the file during his session via an file-input enabled element, then it is simple:
Assuming you've got the url using createObjectURL() after the user selected the file(s), then you simply use the file-reader's readAsDataURL( fileObject || local URL ) method:
fileReader.readAsDataURL( fileObject );
That will encode it to base64.
EDIT:
turns out you are developing for mobile phone using Cordova (I've added that tag to your Question). However that's still based on the file-api and has the same .readAsDataURL() method: see documentation here. It contains simple examples and notes on different mobile platforms!
Also, it seems you are trying to get a file from the LocalFileSystem interface of the File System API (that gives you access to the browser's sandboxed file system). So the other answer I linked to doesn't apply (much).
The following example (modified from the documentation linked above) should get you started:
<!DOCTYPE html>
<html>
<head>
<title>FileReader Example</title>
<script type="text/javascript" charset="utf-8" src="cordova-2.5.0.js"></script>
<script type="text/javascript" charset="utf-8">
// Wait for Cordova to load
//
function onLoad() {
document.addEventListener("deviceready", onDeviceReady, false);
}
// Cordova is ready
//
function onDeviceReady() {
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, gotFS, fail);
}
function gotFS(fileSystem) {
fileSystem.root.getFile("readme.txt", null, gotFileEntry, fail);
}
function gotFileEntry(fileEntry) {
fileEntry.file(gotFile, fail);
}
function gotFile(file){
readDataUrl(file);
}
function readDataUrl(file) {
var reader = new FileReader();
reader.onloadend = function(evt) {
console.log("Read as data URL");
console.log(evt.target.result);
};
reader.readAsDataURL(file);
}
function fail(evt) {
console.log(evt.target.error.code);
}
</script>
</head>
<body>
<h1>Example</h1>
<p>Read File</p>
</body>
</html>
From here on, you change the console.log(evt.target.result); part: instead of writing the base64 output to the console, you send that string back to the server (again using AJAX, etc.)
Done :)
I tried to write a bit of code to retrieve an image file (from Wikimedia Commons), store it locally and then display it. Here my code:
<!DOCTYPE html>
<html>
<head>
<script>
window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;
function onError(e) {
console.log('Error', e);
}
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://upload.wikimedia.org/wikipedia/fr/2/26/10_francs_Mathieu_1987_F365-28_revers.jpg', true);
xhr.responseType = 'blob';
xhr.onload = function(e) {
window.requestFileSystem(PERSISTENT, 1024 * 1024, function(fs) {alert(fs.root.name);}, onError);
window.requestFileSystem(PERSISTENT, 1024 * 1024, function(fs) {
fs.root.getFile('image.jpg', {create: true}, function(fileEntry) {
fileEntry.createWriter(function(writer) {
writer.onwrite = function(e) {};
writer.onerror = function(e) {};
var blob = new Blob([xhr.response], {type: 'image/jpeg'});
writer.write(blob);
}, onError);
}, onError);
}, onError);
window.requestFileSystem(PERSISTENT, 1024 * 1024, function(fs) {
fs.root.getFile('image.jpg', {create: false}, function(fileEntry) {
fileEntry.file(function(file) {
var reader = new FileReader();
reader.onloadend = function(event) {
var img = document.createElement("img");
img.src = event.target.result;
document.body.parentNode.insertBefore(img, document.body.nextSibling);
};
reader.readAsDataURL(file);
}, onError);
}, onError);
}, onError);
};
xhr.send();
</script>
</head>
<body>
</body>
</html>
Nothing is displayed. Chrome's console doesn't display any error message, so I have no idea why it's not working. Any clue?
Edit :
I have just seen I actually get a FileError, code 10, which means QUOTA_EXCEEDED_ERR, even if I start my Google Chrome with these parameters:
"C:\Program Files\Google\Chrome\Application\chrome.exe" --allow-file-access-from-files --unlimited-quota-for-files
Actually, I get the same error with or without the --unlimited-quota-for-files parameter, which is weird. But I get a File Error 2 without --allow-file-access-from-files
In answer to your questions about why launching with "--unlimited-quota-for-files" won't work, I think you're confusing two different things. That parameter simply removed the quota limit, it does not automatically pre-approve scripts to usurp space in the sandbox without permission. If you were using "temporary" file system request, then it would allocate it without prompt (see link at the end of my answer).
But as you experienced by needing to call the requestQuota() method, Chrome will not allow the allocation of persistent file system storage without explicit user permission. There are a few reasons for this, but security as the best: namely that if Chrome were to allocate persistent file system storage on demand (without user knowledge) to any script that asked for it, then a malicious script could quick easily fill a user's hard drive, crash Chrome memory due to many thousands of objects, and cause general mayhem. Such a vulnerability could also trigger buffer overflows by hammering the memory like that.
Bottom line: Chrome only allows persistent file system storage with user approval. More from Google: Managing HTML5 Offline Storage:Persistent storage
If anyone stumbles across this the --unlimited-quota-for-files is no longer a valid flag. However, there is a list of current chromium flags maintained here.
--unlimited-storage would be the new flag to run, I believe.
Overrides per-origin quota settings to unlimited storage for any apps/origins. This should be used only for testing purpose.
I think you had to update to the quota request because the flag didn't override anything (but I don't actually know when the flag itself was deprecated). Because it didn't work as it previously did (assuming your code either worked before, or you got it from a tutorial) I think the browser fell-back on the quota system when the overide didn't happen and saw the quota was exceeded with what you were doing, thus throwing the exception.
You got the File Error without the --allow-file-access-from-files because it'd be a security issue if the browser was allowed to access those files under normal operation, hence the File Error should've been of type SECURITY_ERR.
The information in the following link is old, but the tactic is similar to the code in question(the flag being --unlimited-storage now instead).See this article for more details.
All said, In an actual application the Quota request is a must and the OP's solution at the time of this writing contained the correct code. Currently the javascript for the quota and fs request would look as follows:
navigator.webkitPersistentStorage.requestQuota(1024*1024, function(mB){
window.requestFileSystem(PERSISTENT, mB, function(fs){
//fs write/read, ect. code goes here. Or set a global variable to the value fs
globalFS = fs; //to be accessed later in code, so you don't have to keep requesting.
}, onError);
}, onError);
I added a call to window.webkitStorageInfo.requestQuota, and now it works. I can't get why it is necessary, as I started Chrome with the --unlimited-quota-for-files option.
Here the working code:
<!DOCTYPE html>
<html>
<head>
<script>
window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;
function onError(e) {
console.log('Error', e);
}
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://upload.wikimedia.org/wikipedia/fr/2/26/10_francs_Mathieu_1987_F365-28_revers.jpg', true);
xhr.responseType = 'blob';
xhr.onload = function(e) {
window.webkitStorageInfo.requestQuota(PERSISTENT, 1024*1024, function(grantedBytes) {
window.requestFileSystem(PERSISTENT, 1024 * 1024, function(fs) {
fs.root.getFile('image.jpg', {create: true}, function(fileEntry) {
fileEntry.createWriter(function(writer) {
writer.onwrite = function(e) {};
writer.onerror = function(e) {};
var blob = new Blob([xhr.response], {type: 'image/jpeg'});
writer.write(blob);
}, function(e) {
console.log('Error', e);
});
}, function(e) {
console.log('Error', e);
});
}, function(e) {
console.log('Error', e);
});
}, function(e) {
console.log('Error', e);
});
window.requestFileSystem(PERSISTENT, 1024 * 1024, function(fs) {
fs.root.getFile('image.jpg', {create: false}, function(fileEntry) {
fileEntry.file(function(file) {
var reader = new FileReader();
reader.onloadend = function(event) {
var img = document.createElement("img");
img.src = event.target.result;
document.body.parentNode.insertBefore(img, document.body.nextSibling);
};
reader.readAsDataURL(file);
}, function(e) {
console.log('Error', e);
});
}, function(e) {
console.log('Error', e);
});
}, function(e) {
console.log('Error', e);
});
};
xhr.send();
</script>
</head>
<body>
</body>
</html>
I wrote a code I think it should work, but it doesn't :(
//FILE READER
function fileReaderHelper(){
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fileSystem){
fileSystem.root.getFile("readme.txt", null, function(fileEntry){
fileEntry.file(function(file){
reader.onloadend = function(evt) {
alert("read success");
alert(evt.target.result);
};
reader.readAsText(file);
}, failFile);
}, failFile);
}, failFile);
}
Can anyone see the mistake, or know why not wokrs?
I found the problem.
I forgot this line:
var reader = new FileReader();