I have tried to read excel file to follow the following tutorial.
http://code.psjinx.com/xlsx.js/
But I have failed to read excel file for undefine situation in the following highlighted line.... I have tried it in IE11.
var reader = new FileReader();
reader.onload = function(e) {
var data = e.target.result;
var workbook = XLSX.read(data, {
type: 'binary'
});
obj.sheets = XLSXReader.utils.parseWorkbook(workbook, readCells, toJSON);
handler(obj);
}
**reader.readAsBinaryString(file)**;
The following answer describe, if you are going to load xlsx file from server. For uploading there is another code.
OPTION 1: This is a procedure, which works in Alasql library:
See files: 15utility.js and 84from.js for example
readBinaryFile(filename,true,function(a){
var workbook = X.read(data,{type:'binary'});
// do what you need with parsed xlsx
});
// Read Binary reading procedure
// path - path to the file
// asy - true - async / false - sync
var readBinaryFile = utils.loadBinaryFile = function(path, asy, success, error) {
if(typeof exports == 'object') {
// For Node.js
var fs = require('fs');
var data = fs.readFileSync(path);
var arr = new Array();
for(var i = 0; i != data.length; ++i) arr[i] = String.fromCharCode(data[i]);
success(arr.join(""));
} else {
// For browser
var xhr = new XMLHttpRequest();
xhr.open("GET", path, asy); // Async
xhr.responseType = "arraybuffer";
xhr.onload = function() {
var data = new Uint8Array(xhr.response);
var arr = new Array();
for(var i = 0; i != data.length; ++i) arr[i] = String.fromCharCode(data[i]);
success(arr.join(""));
};
xhr.send();
};
};
OPTION 2: you can use Alasql library itself, which, probably, can be easier option.
alasql('SELECT * FROM XLSX("myfile.xlsx",{headers:true,sheetid:"Sheet2",range:"A1:D100"})',
[],function(data) {
console.log(res);
});
See the example here (simple Excel reading demo) or here (d3.js demo from Excel).
Related
I am trying to perform SHA256 hash on a file content using javascript.
I get the file using the following function
var fileReader = new FileReader();
var fileByteArray = [];
fileReader.onload = function(evt) {
if (evt.target.readyState == FileReader.DONE) {
var arrayBuffer = evt.target.result,
array = new Uint8Array(arrayBuffer);
fileHash = generateHashOfFileContent(array);
console.log('fileHash1: ' + fileHash);
}
}
fileReader.readAsArrayBuffer(this.files[0]);
And the hash function is
function generateHashOfFileContent(fileData){
var bitArray = sjcl.hash.sha256.hash(fileData);
var digest_sha256 = sjcl.codec.hex.fromBits(bitArray);
console.log("Sha256 "+digest_sha256);
return digest_sha256;
}
But it produce wrong hash data when I select a binary file
I can only produce actual hash using a text file and change the fileReader.readAsArrayBuffer(this.files[0]); -------> fileReader.readAsText(this.files[0]);
Can someone help me to figure out the problem
You should convert your TypedArray to bitArray:
var fileReader = new FileReader();
var fileByteArray = [];
fileReader.onload = function(evt) {
if (evt.target.readyState == FileReader.DONE) {
var arrayBuffer = evt.target.result,
array = new Uint8Array(arrayBuffer);
let bitArray = sjcl.codec.bytes.toBits(array)
fileHash = generateHashOfFileContent(bitArray);
console.log('fileHash1: ' + fileHash);
}
}
fileReader.readAsArrayBuffer(this.files[0]);
See https://github.com/bitwiseshiftleft/sjcl/wiki/Codecs
I want to read xlsx file but what i want is just to read first three records because as you know if i read all the records, the browser will crash. I need your help to find a way to just read first three records (rows)
P.S: I don't want to save data in memory while parsing xlsx file
i am using this right now :
fileChange(event) {
const fileList: FileList = event.target.files;
if (fileList.length > 0) {
const file: File = fileList[0];
const reader = new FileReader();
reader.onload = e => {
const arrayBuffer = reader.result,
data = new Uint8Array(arrayBuffer),
arr = new Array();
for (let i = 0; i !== data.length; ++i) {
arr[i] = String.fromCharCode(data[i]);
}
const bstr = arr.join("");
const workbook: XLSX.WorkBook = XLSX.read(bstr, { type: "binary" });
const firstSheetName: string = workbook.SheetNames[0];
const worksheet: XLSX.WorkSheet = workbook.Sheets[firstSheetName];
this.setXlsxData(XLSX.utils.sheet_to_json(worksheet));
};
reader.readAsArrayBuffer(file);
}
}
setXlsxData(data: Array<any>) {
this.headers = Object.keys(data[0]);
this.xlsxData = data;
}
try this library. I have written & read some xlsx files, it works smoothly.
(Apologies, I couldnt write this in comment, can't comment)
https://www.npmjs.com/package/xlsx
I'm trying to upload multiple attachments.
First I'm getting attachments from user interface, then I'm converting them into JSON , then I need to make a server call.
In this I'm using FileReader.
//showing ajax loader
component.set("v.showLoadingSpinner", true);
//getting attached files
var files = component.find("fileId").get("v.files");
var details = {}; //JS Object need to send server
details.files = [];
for (var i = 0; i < files.length; i++)
{
(function(file) {
var name = file.name;
var reader = new FileReader();
reader.fName = files[i]['name'];
reader.fType = files[i]['type'];
reader.i = i;
reader.onload = function(e) {
var fileContents = reader.result;
var base64 = 'base64,';
var dataStart = fileContents.indexOf(base64) + base64.length;
fileContents = fileContents.substring(dataStart);
var startPosition = 0;
var endPosition = Math.min(fileContents.length, startPosition + 750000);
var getchunk = fileContents.substring(startPosition, endPosition);
var fDetails = {};
fDetails.fileName = reader.fName;
fDetails.base64Data = encodeURIComponent(getchunk);
fDetails.contentType = reader.fType;
details.files.push(fDetails);
}
reader.readAsDataURL(file);
})(files[i]);
// I want to make a server call here with data in "details" object.
console.log(details);
But I'm not getting data in above console log.
Please help me to achieve this.
You can use promises :
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
https://davidwalsh.name/promises
https://developers.google.com/web/fundamentals/primers/promises
Also jQuery provide $.when() function :
https://api.jquery.com/jquery.when/
And with promisejs you can do something like this :
function readJSON(filename){
return new Promise(function (fulfill, reject){
readFile(filename, 'utf8').done(function (res){
try {
fulfill(JSON.parse(res));
} catch (ex) {
reject(ex);
}
}, reject);
});
}
I am trying to make a java script web resource for dynamics CRM that essentially lets a user chose a file to upload and then stores it onto the annotation entity. I know the general procedure to do this however it keeps uploading empty files. The data is not getting converted to base 64 using the base 64 function. I am having a hard time using the File reader function to convert the file uploaded into base 64. The dataURL variable keeps returning empty. Can someone help me convert the chosen file to base 64? this does not have to be dynamics specific I think its a general java script html problem. I think i am using the File reader function wrong.
Thank you
function uploadFile(event) {
var input = event.target;
var file = input.files[0];
//var file = document.getElementById("myFile").files[0];
var str;
var reader = new FileReader();
reader.onload = function() {
var dataURL = reader.result;
str = _arrayBufferToBase64(dataURL);
};
reader.readAsDataURL(input.files[0]);
var id = window.parent.Xrm.Page.data.entity.getId();
var nam = window.parent.Xrm.Page.data.entity.getEntityName();
var entity = {};
entity.Subject = "first new annotation3";
entity.NoteText = "way to go you just made a new annotation";
entity.DocumentBody = str;
entity.FileName = file.name;
entity.MimeType = file.type;
entity.ObjectId = {
Id: id,
LogicalName: nam
};
SDK.REST.createRecord(entity, "Annotation", SucessCallback2, errorCallback2);
}
function _arrayBufferToBase64(buffer) { // Convert Array Buffer to Base 64 string
var binary = '';
var bytes = new Uint8Array(buffer);
var len = bytes.byteLength;
for (var i = 0; i < len; i++) {
binary += String.fromCharCode(bytes[i]);
}
return window.btoa(binary);
}
<
input type = "file"
id = "myFile"
placeholder = "Choose File"
onchange = "uploadFile(event)" >
i figured it out, for anyone else having a similar issue. It turns out that you cant take the data outside the onload function, you have to pass the data out to another function using a callback function. See below.
function uploadFile(event)
{
var input = event.target;
var file = input.files[0];
//var file = document.getElementById("myFile").files[0];
var str;
var reader = new FileReader();
reader.onload = function(eve){
var theResult = reader.result;
str = _arrayBufferToBase64(theResult);
AttachFileFunction(file.name,file.type,str);
};
reader.readAsArrayBuffer(file);
I am trying to upload multiple images. So I read that I can generate a temporary url and send them with ajax.
The idea is push the url created with filereader into an array and the send with ajax but the url's are not pushed properly. When I see the result I got like an empty array:
But if I click the arrow I can see the url's inside
But them seems Inaccessible.
This is my code:
$('form').on('submit',function(e) {
e.preventDefault();
var filesToUpload = document.getElementById("myFile");
var files = filesToUpload.files;
var fd = new FormData();
var arr = [];
if (FileReader && files && files.length) {
for (i=0; i< files.length; i++){
(function(file) {
var name = file.name;
var fr = new FileReader();
fr.onload = function () {
arr.push(fr.result);
}
fr.readAsDataURL(file);
})(files[i]);
}
console.log(arr);
}
});
The final idea is convert to string JSON.stringify(arr) and then parse in php json_decode($_POST['arr']).
Of course this is not working because JSON.stringify(arr) gets empty.
Maybe the following simple solution works for you? I placed your console.log() and your ajax call into the fr.onload() method but fire it only, after your results array has been filled up with all values:
$('form').on('submit',function(e) {
e.preventDefault();
var filesToUpload = document.getElementById("myFile");
var files = filesToUpload.files;
var fd = new FormData();
var arr = [];
if (FileReader && files && files.length) {
for (var i=0; i< files.length; i++){
(function(file) {
var name = file.name;
var fr = new FileReader();
fr.onload = function () {
arr.push(fr.result);
if(arr.length==files.length) {
console.log(arr);
// place your ajax call here!
}
}
fr.readAsDataURL(file);
})(files[i]);
}
}
});