Can not convert xlsx file into json using javascript - javascript

I am trying to convert xls file into json I can convert it successfully but when I try to convert xlsx file into json I get an error as "Uncaught Header Signature: Expected d0cf11e0a1b11ae1 saw 504b030414000808".
Index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>XL to JSON</title>
<script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript"></script>
<script src=" https://cdnjs.cloudflare.com/ajax/libs/xls/0.7.4-a/xls.js"></script>
</head>
<body>
<input type="file" id="my_file_input" />
<div id='my_file_output'></div>
<script>
var oFileIn;
$(function() {
oFileIn = document.getElementById('my_file_input');
if(oFileIn.addEventListener) {
oFileIn.addEventListener('change', filePicked, false);
}
});
function filePicked(oEvent) {
// Get The File From The Input
var oFile = oEvent.target.files[0];
var sFilename = oFile.name;
// Create A File Reader HTML5
var reader = new FileReader();
// Ready The Event For When A File Gets Selected
reader.onload = function(e) {
var data = e.target.result;
var cfb = XLS.CFB.read(data, {type: 'binary'});
var wb = XLS.parse_xlscfb(cfb);
// Loop Over Each Sheet
wb.SheetNames.forEach(function(sheetName) {
// Obtain The Current Row As CSV
var sCSV = XLS.utils.make_csv(wb.Sheets[sheetName]);
var oJS = XLS.utils.sheet_to_row_object_array(wb.Sheets[sheetName]);
$("#my_file_output").html(sCSV);
console.log(oJS)
});
};
// Tell JS To Start Reading The File.. You could delay this if desired
reader.readAsBinaryString(oFile);
}
</script>
</body>
</html>
Can any one please tell me how should I solve this.I am badly stucked in this problem.Thanks in advance.

You are using the xls library which does not support xlsx files. Please use the updated one:
https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.8.0/xlsx.js
You can find more details and documentation for this here.

It worked with this code:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>JS-XLSX Live Demo</title>
<style>
#b64data
{
width:100%;
}
</style>
<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
<script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript"></script>
</head>
<body>
<b>JS-XLSX (XLSX/XLSB/XLSM/XLS/XML) Live Demo</b><br />
<div id="drop"></div>
<p><input type="file" name="xlfile" id="xlf" /></p>
<br />
<pre id="out"></pre>
<br />
<script src="shim.js"></script>
<script src="jszip.js"></script>
<script src="xlsx.js"></script>
<!-- uncomment the next line here and in xlsxworker.js for ODS support -->
<script src="ods.js"></script>
<script>
var X = XLSX;
var XW = {
/* worker message */
msg: 'xlsx',
/* worker scripts */
rABS: './xlsxworker2.js',
norABS: './xlsxworker1.js',
noxfer: './xlsxworker.js'
};
function fixdata(data)
{
var o = "", l = 0, w = 10240;
for(; l<data.byteLength/w; ++l) o+=String.fromCharCode.apply(null,new Uint8Array(data.slice(l*w,l*w+w)));
o+=String.fromCharCode.apply(null, new Uint8Array(data.slice(l*w)));
return o;
}
function get_radio_value( radioName )
{
var radios = document.getElementsByName( radioName );
for( var i = 0; i < radios.length; i++ )
{
if( radios[i].checked || radios.length === 1 )
{
return radios[i].value;
}
}
}
function to_json(workbook)
{
var result = {};
var result1 = [];
var array1 = [];
var arr =[];
workbook.SheetNames.forEach(function(sheetName)
{
var arr = X.utils.sheet_to_row_object_array(workbook.Sheets[sheetName]);
var array_lenght = arr.length;
for(var i = 0 ;i<array_lenght;i++ )
{
if(arr.length > 0)
{
array1 = arr[i];
result = array1;
result1.push(array1);
}
}
});
var sub_key = [];
for(var ab in result1)
{
var key = ab;
var val = result1[ab];
for(var j in val)
{
sub_key.push(j);
console.log(sub_key);
}
if((sub_key.indexOf("Last Name") && sub_key.indexOf("Email") && sub_key.indexOf("First Name")) > -1)
{
return "right format";
}
else
{
return "wrong format";
}
}
}
function process_wb(wb)
{
var output = "";
switch(get_radio_value("format"))
{
case "json":
output = JSON.stringify(to_json(wb), 2, 2);
break;
default:
output = JSON.stringify(to_json(wb), 2, 2);
}
if(out.innerText === undefined) out.textContent = output;
else out.innerText = output;
if(typeof console !== 'undefined') console.log("output", new Date());
}
var xlf = document.getElementById('xlf');
function handleFile(e)
{
rABS = document.getElementsByName("userabs")[0];
use_worker = document.getElementsByName("useworker")[0];
var files = e.target.files;
var f = files[0];
{
var reader = new FileReader();
var name = f.name;
reader.onload = function(e)
{
if(typeof console !== 'undefined') console.log("onload", new Date());
var data = e.target.result;
if(use_worker)
{
xw(data, process_wb);
}
else
{
var wb;
if(rABS)
{
wb = X.read(data, {type: 'binary'});
} else
{
var arr = fixdata(data);
wb = X.read(btoa(arr), {type: 'base64'});
}
process_wb(wb);
}
};
if(rABS) reader.readAsBinaryString(f);
else reader.readAsArrayBuffer(f);
}
}
if(xlf.addEventListener) xlf.addEventListener('change', handleFile, false);
</script>
</body>
</html>

That answer might work, but I don't think its exactly what you are requesting. In fact, based on your question and the documentation for SheetJS/js-xlsx I would suggest something like this:
function filePicked(oEvent) {
// Get The File From The Input
var oFile = oEvent.target.files[0];
var sFilename = oFile.name;
// Create A File Reader HTML5
var reader = new FileReader();
// Ready The Event For When A File Gets Selected
reader.onload = function(e) {
var data = e.target.result;
var cfb = XLSX.read(data, {type: 'binary'});
console.log(cfb)
cfb.SheetNames.forEach(function(sheetName) {
// Obtain The Current Row As CSV
var sCSV = XLS.utils.make_csv(cfb.Sheets[sheetName]);
var oJS = XLS.utils.sheet_to_json(cfb.Sheets[sheetName]);
$("#my_file_output").html(sCSV);
console.log(oJS)
$scope.oJS = oJS
});
};
// Tell JS To Start Reading The File.. You could delay this if desired
reader.readAsBinaryString(oFile);}
I tried it and it works fine. And whats more important, its a real answer to your question.

<script type="text/javascript">
document.querySelector("html").classList.add('js');
var fileInput = document.querySelector( ".input-file" ),
button = document.querySelector( ".input-file-trigger"),
the_return = document.querySelector(".file-return");
button.addEventListener( "keydown", function( event ) {
if ( event.keyCode == 13 || event.keyCode == 32 ) {
fileInput.focus();
}
});
button.addEventListener( "click", function( event ) {
fileInput.focus();
return false;
});
fileInput.addEventListener( "change", function( event ) {
var oFile = event.target.files[0];
var sFilename = oFile.name;
var reader = new FileReader();
// Ready The Event For When A File Gets Selected
reader.onload = function(e) {
var data = e.target.result;
var cfb = XLSX.read(data, {type: 'binary'});
// Loop Over Each Sheet
cfb.SheetNames.forEach(function(sheetName) {
var sCSV = XLS.utils.make_csv(cfb.Sheets[sheetName]);
var oJS = XLS.utils.sheet_to_json(cfb.Sheets[sheetName]);
alert(oJS);
alert(sCSV);
});
};
// Tell JS To Start Reading The File.. You could delay this if desired
reader.readAsBinaryString(oFile);
});

Related

JS: How to take new image value from input

I'm trying to get an image from input convert it to array as well to display the new image into the imgPicture.src. However, I'm either getting undefined or empty source. Any possible solution? Thank you in advance.
let changePicInput = document.createElement("input");
changePicInput.type = "file";
changePicInput.id = `file-${finalArray[i].Id}`;
changePicInput.style.display = "none";
changePicInput.addEventListener("change", function () {
let arrBinaryFile = [];
let file = document.getElementById(`file-${materialId}`).files[0];
let reader = new FileReader();
// Array
reader.readAsArrayBuffer(file);
reader.onloadend = function (evt) {
if (evt.target.readyState == FileReader.DONE) {
var arrayBuffer = evt.target.result,
array = new Uint8Array(arrayBuffer);
for (var i = 0; i < array.length; i++) {
arrBinaryFile.push(array[i]);
}
}
}
// Display the image rightaway
imgPicture.src = file.value;
});
Hope it helps!
let imgPicture = document.querySelector('#imgPicture'); // Added the line.
let changePicInput = document.createElement("input");
changePicInput.type = "file";
changePicInput.id = `file-565656`; // Changed the line.
changePicInput.style.display = "block"; // Changed the line.
document.body.appendChild(changePicInput); // Added the line.
changePicInput.addEventListener("change", function () {
let arrBinaryFile = [];
let file = document.getElementById(`file-565656`).files[0]; // Changed the line.
let reader = new FileReader();
// Array
reader.readAsArrayBuffer(file);
reader.onloadend = function (evt) {
if (evt.target.readyState == FileReader.DONE) {
var arrayBuffer = evt.target.result,
array = new Uint8Array(arrayBuffer);
for (var i = 0; i < array.length; i++) {
arrBinaryFile.push(array[i]);
}
}
}
// Display the image rightaway
//imgPicture.src = file.value;
imgPicture.src = URL.createObjectURL(file) // Added the line.
console.log(file); // Added the line.
});
<body>
<img id="imgPicture">
</body>

Why does my redirect is not working?

my script calls my redirect function to early, so the last file of a batch upload is failing. I have been search the whole morning an tried different approaches, but without success.
function uploadFile(something, callback) {
var fileInput = $('#fileList1');
//var reader = new FileReader();
console.log(fileInput);
if ( trim( fileInput.val() ).length == 0 ) {
return;
}
var fileList = [];
count = fileInput[0].files.length;
for(i = 0; i < count; i++){
loadFile(fileInput[0].files[i]);
}
function loadFile(file){
var reader = new FileReader();
var fileName = getFileNameWithExtension( file);
var file = file;
while(reader.onprogress){
console.log("reading");
}
reader.onload = function(event) {
var val = reader.result;
var text = val.split(',')[1];
saveFile( fileName, text, parentId );
if (!--count){
redirect();
}
}
reader.onerror = function(event) {
console.error("File could not be read! Code " + reader.error.message);
}
reader.readAsDataURL(file);
}
}
function redirect(){
window.location.href = '/{!tempID}';
return false;
}
Can someone give me a hint?
#
Hello, i have rewritten my methods a bit based on your suggestions. But the redirect is still called to early,...before all uploads are done.
function uploadFile() {
var fileInput = $('#fileList1');
console.log(fileInput);
if ( trim( fileInput.val() ).length == 0 ) {
return;
}
var countTwo = 0;
count = fileInput[0].files.length;
for(var i = 0; i < count; i++){
loadFile(fileInput[0].files[i], function(val){
console.log(val);
if(val === 3){
setTimeout(()=>{redirect();}, 5000);
}
});
}
function loadFile(file, callback){
var reader = new FileReader();
var fileName = getFileNameWithExtension( file);
var file = file;
while(reader.onprogress){
console.log("reading");
}
reader.onload = function(event) {
var val = reader.result;
var text = val.split(',')[1];
saveFile( fileName, text, parentId );
console.log(" ct " + countTwo + " c " + count-1);
countTwo++;
if(!--count) callback(countTwo);
}
reader.onerror = function(event) {
console.error("File could not be read! Code " + reader.error.message);
}
reader.readAsDataURL(file);
}
}
Method 1: (Recommended)
Detect when your uploading ends. And in that callback, call redirect.
Method 2:
// define your TIMEOUT first
setTimeout(()=>{redirect();}, TIMEOUT);
reader.onload = function(event) {
var val = reader.result;
var text = val.split(',')[1];
saveFile( fileName, text, parentId );
if (!--count){
setTimeout(()=>{redirect();}, 0);
}
}

remove blank lines when uploading csv files angular

I got a csv-reader directive and let's user upload a csv file. I noticed that when I upload a file with spaces between words for example:
abc
abc
abc
abc
abc
this gets shown. I want to delete all the blank lines Not sure what to do.
var reader = new FileReader();
reader.onload = function(e) {
var contents = e.target.result;
var rows = contents.split('\n');
// Check if the last row is empty. This works
if(rows[rows.length-1] ===''){
rows.pop()
}
}
// this doesn't work for some reason. It doesn't detect the '' in the middle of the arrays.
for( var i=rows.length-1;i>0;i--){
if(rows[i] === ''){
rows.splice(i,1)
}
}
Try using Array.prototype.filter()
var rows = contents.split('\n').filter(function(str){
return str;
});
From what you have shown it looks like you want to check if each item in the csvModel is an empty string, rather than newValue
Something like:
for( var i=0 ;i< $scope.csvModel.length; i++){
if (csvModel[i] == "") {
$scope.csvModel.splice(i,1);
}
}
var text = [];
var target = $event.target || $event.srcElement;
var files = target.files;
if(Constants.validateHeaderAndRecordLengthFlag){
if(!this._fileUtil.isCSVFile(files[0])){
alert("Please import valid .csv file.");
this.fileReset();
}
}
var input = $event.target;
var reader = new FileReader();
reader.readAsText(input.files[0], 'UTF-8');
reader.onload = (data) => {
let csvData = reader.result;
let csvRecordsArray = csvData.split(/\r\n|\n/);
if (csvRecordsArray[csvRecordsArray.length - 1] === '') {
csvRecordsArray.pop();
}
var headerLength = -1;
if(Constants.isHeaderPresentFlag){
let headersRow = this._fileUtil.getHeaderArray(csvRecordsArray, Constants.tokenDelimeter);
headerLength = headersRow.length;
}
this.csvRecords = this._fileUtil.getDataRecordsArrayFromCSVFile(csvRecordsArray,
headerLength, Constants.validateHeaderAndRecordLengthFlag, Constants.tokenDelimeter);
if(this.csvRecords===null){
this.csvRecords=[];
}
else if(this.csvRecords!==null) {
if ((JSON.stringify(this.csvRecords[0])) === (JSON.stringify(this.csvFormate))) {
alert("format matches");
this.displayCsvContent = true;
for (let i = 0; i < this.csvRecords.length; i++) {
if (i !== 0) {
this.csvRecords[i].push(this.recordInsertedFlag);
}
}
}
else {
alert("format not matches");
}
}
if(this.csvRecords == null){
this.displayCsvContent=false;
//If control reached here it means csv file contains error, reset file.
this.fileReset();
}
};
reader.onerror = function () {
alert('Unable to read ' + input.files[0]);
};

Convert a Fetched data in div from excel to a query

The below code fetches data from a csv and presents in to a div as a text but am trying to convert that in to a query on fetch excel import and print then as a query
Current output when the data is imported from the excel
Example:
column1','column2','column3','column4')
column1','column2','column3','column4')
column1','column2','column3','column4')
column1','column2','column3','column4')
column1','column2','column3','column4')
Expected output
('column1','column2','column3','column4'),
('column1','column2','column3','column4'),
('column1','column2','column3','column4'),
('column1','column2','column3','column4'),
('column1','column2','column3','column4');
JS fiddle demo
HTML:
<input id = "csv" type = "file" />
<div id="result"></div>
JS:
$('#csv').change(function(e) {
if ((window.FileReader) && (e.target.files != undefined)) {
var reader = new FileReader();
reader.onload = function(e) {
var lineSplit = e.target.result.split("\n");
var content = [];
for (var j = 1; j < lineSplit.length; j++) {
var fourColumnsData = lineSplit[j].split(',').slice(0, 4).join("','");
content.push(fourColumnsData);
}
var fileContent = content.join("')<br/>");
$('#result').html(fileContent);
};
reader.readAsText(e.target.files.item(0));
}
});
Try the following
$('#csv').change(function(e) {
if ((window.FileReader) && (e.target.files != undefined)) {
var reader = new FileReader();
reader.onload = function(e) {
var lineSplit = e.target.result.split("\n");
var content = [];
for (var j = 1; j < lineSplit.length; j++) {
if (lineSplit[j].trim().length > 0) {
var fourColumnsData = "('" + lineSplit[j].split(',').slice(0, 4).join("','") + "')";
content.push(fourColumnsData);
}
}
var fileContent = content.join(",");
$('#result').html(fileContent);
};
reader.readAsText(e.target.files.item(0));
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<input id="csv" type="file" />
<div id="result"></div>

Android Web Console: UncaughtReferenceError: Worker is not defined

I'm pretty new about javascript. after a long search I couldn't find why but looks like popular browsers does somework about this definition new Worker("BarcodeWorker.js") as their base js support but Android WebView. Orginal code is from Eddie Larsson barcode reader on github. Thanks.
<!DOCTYPE html>
<meta charset=utf-8>
<html lang="en">
<head>
<title>BarcodeReader</title>
</head>
<body>
<div id="container">
<img width="640" height="480" src="about:blank" alt="" id="picture">
<input id="Take-Picture" type="file" accept="image/*;capture=camera" />
<p id="textbit"></p>
</div>
<script type="text/javascript">
var takePicture = document.querySelector("#Take-Picture"),
showPicture = document.querySelector("#picture");
Result = document.querySelector("#textbit");
Canvas = document.createElement("canvas");
Canvas.width=640;
Canvas.height=480;
var resultArray = [];
ctx = Canvas.getContext("2d");
var workerCount = 0;
function receiveMessage(e) {
if(e.data.success === "log") {
console.log(e.data.result);
return;
}
workerCount--;
if(e.data.success){
var tempArray = e.data.result;
for(var i = 0; i < tempArray.length; i++) {
if(resultArray.indexOf(tempArray[i]) == -1) {
resultArray.push(tempArray[i]);
}
}
Result.innerHTML=resultArray.join("<br />");
}else{
if(resultArray.length === 0 && workerCount === 0) {
Result.innerHTML="Decoding failed.";
}
}
}
//Where the issue starts
var script='';
var DecodeWorker = new Worker("DecoderWorker.js");
var RightWorker = new Worker("DecoderWorker.js");
var LeftWorker = new Worker("DecoderWorker.js");
var FlipWorker = new Worker("DecoderWorker.js");
DecodeWorker.onmessage = receiveMessage;
RightWorker.onmessage = receiveMessage;
LeftWorker.onmessage = receiveMessage;
FlipWorker.onmessage = receiveMessage;
if(takePicture && showPicture) {
takePicture.onchange = function (event) {
var files = event.target.files
if (files && files.length > 0) {
file = files[0];
try {
var URL = window.URL || window.webkitURL;
var imgURL = URL.createObjectURL(file);
showPicture.src = imgURL;
URL.revokeObjectURL(imgURL);
DecodeBar()
}
catch (e) {
try {
var fileReader = new FileReader();
fileReader.onload = function (event) {
showPicture.src = event.target.result;
};
fileReader.readAsDataURL(file);
DecodeBar()
}
catch (e) {
Result.innerHTML = "Neither createObjectURL or FileReader are supported";
}
}
}
};
}
function DecodeBar(){
showPicture.onload = function(){
ctx.drawImage(showPicture,0,0,Canvas.width,Canvas.height);
resultArray = [];
workerCount = 4;
Result.innerHTML="";
DecodeWorker.postMessage({pixels: ctx.getImageData(0,0,Canvas.width,Canvas.height).data, cmd: "normal"});
RightWorker.postMessage({pixels: ctx.getImageData(0,0,Canvas.width,Canvas.height).data, cmd: "right"});
LeftWorker.postMessage({pixels: ctx.getImageData(0,0,Canvas.width,Canvas.height).data, cmd: "left"});
FlipWorker.postMessage({pixels: ctx.getImageData(0,0,Canvas.width,Canvas.height).data, cmd: "flip"});
}
}
</script>
</body>
</html>
It looks like Web Workers aren't available to you, (and aren't available in current versions of Opera Mini and the Android browser [but are in mobile Chrome!]). They're a way to put some resource-intensive tasks in another thread, so your main thread doesn't get held up (useful to prevent the app/page appearing to freeze for a moment).
Luckily, they shouldn't be necessary for your code to work. You'll need to move the javascript from "DecoderWorker.js" into the scope of your page, and rework/remove the message and onmessage events, instead calling the function(s) copied from the worker directly.
UPDATE: Here's a working fiddle to get you started. I just replaced e.data with options and changed the message events to functions:
/* From reader.html */
function receiveMessage(options) {
if(options.success === "log") {
console.log(options.result);
return;
}
workerCount--;
if(options.success){
var tempArray = options.result;
for(var i = 0; i < tempArray.length; i++) {
if(resultArray.indexOf(tempArray[i]) == -1) {
resultArray.push(tempArray[i]);
}
}
Result.innerHTML=resultArray.join("<br />");
}else{
if(resultArray.length === 0 && workerCount === 0) {
Result.innerHTML="Decoding failed.";
}
}
}
function DecodeBar(){
showPicture.onload = function(){
ctx.drawImage(showPicture,0,0,Canvas.width,Canvas.height);
resultArray = [];
workerCount = 4;
Result.innerHTML="";
ReadBarcode({pixels: ctx.getImageData(0,0,Canvas.width,Canvas.height).data, cmd: "normal"}, receiveMessage);
ReadBarcode({pixels: ctx.getImageData(0,0,Canvas.width,Canvas.height).data, cmd: "right"}, receiveMessage);
ReadBarcode({pixels: ctx.getImageData(0,0,Canvas.width,Canvas.height).data, cmd: "left"}, receiveMessage);
ReadBarcode({pixels: ctx.getImageData(0,0,Canvas.width,Canvas.height).data, cmd: "flip"}, receiveMessage);
}
}
/* From the last onmessage handler in DecoderWorker.js */
function ReadBarcode(options, callback) {
Image = {
data: new Uint8ClampedArray(options.pixels),
width: 640,
height: 480
}
var availableFormats = ["Code128","Code93","Code39","EAN-13"];
FormatPriority = [];
var skipList = [];
if(typeof options.priority != 'undefined') {
FormatPriority = options.priority;
}
for(var i = 0; i < availableFormats.length; i++) {
if(FormatPriority.indexOf(availableFormats[i]) == -1) {
FormatPriority.push(availableFormats[i]);
}
}
if(typeof options.skip != 'undefined') {
skipList = options.skip;
}
for(var i = 0; i < skipList.length; i++) {
if(FormatPriority.indexOf(skipList[i]) != -1) {
FormatPriority.splice(FormatPriority.indexOf(skipList[i]),1);
}
}
CreateTable();
switch(options.cmd) {
case "flip":
flipTable();
break;
case "right":
rotateTableRight();
break;
case "left":
rotateTableLeft();
break;
case "normal":
break;
}
var FinalResult = Main();
if(FinalResult.length > 0) {
callback({result: FinalResult, success: true});
} else {
callback({result: FinalResult, success: false});
}
}

Categories

Resources