Import xlsx file into html page via javascript - javascript

I want to read the data of a specific xlsx file into javascript to show them on a .html page.
For that i downloaded sheetjs. A .xlsx parser.
But now I realized that you kinda must choose a file in the html site to read it. But I only want to use one file the whole time. Also the html site will only run local. So is there any way to get going with setting up a absolute path in the js to the file. So something like
file= "C:\test.xlsx"
Code example from the documemtary:
function handleFile(e) {
var files = e.target.files;
var i,f;
for (i = 0, f = files[i]; i != files.length; ++i) {
var reader = new FileReader();
var name = f.name;
reader.onload = function(e) {
var data = e.target.result;
var workbook = XLSX.read(data, {type: 'binary'});
/* DO SOMETHING WITH workbook HERE */
};
reader.readAsBinaryString(f);
}
}
input_dom_element.addEventListener('change', handleFile, false);

Related

Save file using File Reader - Jquery

I am using html File input to attach multiple files.
I am using below code to loop throw all files and save to database. but it's saving only last attached file to database multiple times.
If I attach file 1 , file 2 . File 2 is saved to database 2 times. /n
If I attach file 1 , file 2 ,file 3. File 3 is saved to database 3 times.
for (let i = 0; i < FileList.length; i++)
{
var artworkFileName = FileList[i].name;
var artworkMimeType = FileList[i].type;
var file = FileList[i];
if (file) {
// Read the file
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function (e) {
var artworkDocumentbodyContents = e.target.result;
artworkDocumentbodyContents = artworkDocumentbodyContents.substring(artworkDocumentbodyContents.indexOf(',') + 1);
UploadFileAPI(artworkDocumentbodyContents, artworkFileName, artworkMimeType,varQues,IsAllSubmit,varSaveButton,);// To save the files to Database(dataverse table)
};
} }
Any suggestions.

Convert binary file to JavaScript string and then to Uint8Array

I'm trying to create a web application that can be used via a file:// URI. This means that I can't use AJAX to load binary files (without turning off security features in the browser, which I don't want to do as a matter of principle).
The application uses a SQLite database. I want to provide the database to a sql.js constructor, which requires it in Uint8Array format.
Since I can't use AJAX to load the database file, I could instead load it with <input type="file"> and FileReader.prototype.readAsArrayBuffer and convert the ArrayBuffer to a Uint8Array. And that's working with the following code:
input.addEventListener('change', function (changeEvent) {
var file = changeEvent.currentTarget.files[0];
var reader = new FileReader();
reader.addEventListener('load', function (loadEvent) {
var buffer = loadEvent.target.result;
var uint8Array = new Uint8Array(buffer);
var db = new sql.Database(uint8Array);
});
reader.readAsArrayBuffer(file);
});
However, <input type="file"> requires user interaction, which is tedious.
I thought I might be able to work around the no-AJAX limitation by using a build tool to convert my database file to a JavaScript object / string and generate a ".js" file providing the file contents, and then convert the file contents to a Uint8Array, somehow.
Psuedocode:
// In Node.js:
var fs = require('fs');
var sqliteDb = fs.readFileSync('path/to/sqlite.db');
var string = convertBufferToJsStringSomehow(sqliteDb);
fs.writeFileSync('build/db.js', 'var dbString = "' + string + '";');
// In the browser (assume "build/db.js" has been loaded via a <script> tag):
var uint8Array = convertStringToUint8ArraySomehow(dbString);
var db = new sql.Database(uint8Array);
In Node.js, I've tried the following:
var TextEncoder = require('text-encoding').TextEncoder;
var TextDecoder = require('text-encoding').TextEncoder;
var sql = require('sql.js');
var string = new TextDecoder('utf-8').decode(fs.readFileSync('path/to/sqlite.db'));
// At this point, I would write `string` to a ".js" file, but for
// the sake of determining if converting back to a Uint8Array
// would work, I'll continue in Node.js...
var uint8array = new TextEncoder().encode(string);
var db = new sql.Database(uint8array);
db.exec('SELECT * FROM tablename');
But when I do that, I get the error "Error: database disk image is malformed".
What am I doing wrong? Is this even possible? The database disk image isn't "malformed" when I load the same file via FileReader.
Using the following code, I was able to transfer the database file's contents to the browser:
// In Node.js:
var fs = require('fs');
var base64 = fs.readFileSync('path/to/sqlite.db', 'base64');
fs.writeFileSync('build/db.js', 'var dbString = "' + base64 + '";');
// In the browser (assume "build/db.js" has been loaded via a <script> tag):
function base64ToUint8Array (string) {
var raw = atob(string);
var rawLength = raw.length;
var array = new Uint8Array(new ArrayBuffer(rawLength));
for (var i = 0; i < rawLength; i += 1) {
array[i] = raw.charCodeAt(i);
}
return array;
}
var db = new sql.Database(base64ToUint8Array(dbString));
console.log(db.exec('SELECT * FROM tablename'));
And that's working with the following code:
input.addEventListener('change', function (changeEvent) {
var file = changeEvent.currentTarget.files[0];
var reader = new FileReader();
reader.addEventListener('load', function (loadEvent) {
var buffer = loadEvent.target.result;
var uint8Array = new Uint8Array(buffer);
var db = new sql.Database(uint8Array);
});
reader.readAsArrayBuffer(file);
});
However, <input type="file"> requires user interaction, which is
tedious.
Using current working approach would be less tedious than attempting to create workarounds. If user intends to use application, user can select file from their filesystem to run application.

Excel to JSON javascript code?

I want to convert excel sheet data to json. It has to be dynamic, so there is an upload button where user uploads the excel sheet and the data is then converted into json. Could you please provide me the javascript code? I tried SheetJS but couldn't figure out. I would prefer something straight forward :)
I really appreciate your help!
NOTE: Not 100% Cross Browser
Check browser compatibility # http://caniuse.com/#search=FileReader
as you will see people have had issues with the not so common browsers, But this could come down to the version of the browser.. I always recommend using something like caniuse to see what generation of browser is supported... This is only a working answer for the user, not a final copy and paste code for people to just use..
The Fiddle: http://jsfiddle.net/d2atnbrt/3/
THE HTML CODE:
<input type="file" id="my_file_input" />
<div id='my_file_output'></div>
THE JS CODE:
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);
}
This also requires https://cdnjs.cloudflare.com/ajax/libs/xls/0.7.4-a/xls.js to convert to a readable format, i've also used jquery only for changing the div contents and for the dom ready event.. so jquery is not needed
This is as basic as i could get it,
EDIT - Generating A Table
The Fiddle: http://jsfiddle.net/d2atnbrt/5/
This second fiddle shows an example of generating your own table, the key here is using sheet_to_json to get the data in the correct format for JS use..
One or two comments in the second fiddle might be incorrect as modified version of the first fiddle.. the CSV comment is at least
Test XLS File: http://www.whitehouse.gov/sites/default/files/omb/budget/fy2014/assets/receipts.xls
This does not cover XLSX files thought, it should be fairly easy to adjust for them using their examples.
js-xlsx library makes it easy to convert Excel/CSV files into JSON objects.
Download the xlsx.full.min.js file from here.
Write below code on your HTML page
Edit the referenced js file link (xlsx.full.min.js) and link of Excel file
<!doctype html>
<html>
<head>
<title>Excel to JSON Demo</title>
<script src="xlsx.full.min.js"></script>
</head>
<body>
<script>
/* set up XMLHttpRequest */
var url = "http://myclassbook.org/wp-content/uploads/2017/12/Test.xlsx";
var oReq = new XMLHttpRequest();
oReq.open("GET", url, true);
oReq.responseType = "arraybuffer";
oReq.onload = function(e) {
var arraybuffer = oReq.response;
/* convert data to binary string */
var data = new Uint8Array(arraybuffer);
var arr = new Array();
for (var i = 0; i != data.length; ++i) arr[i] = String.fromCharCode(data[i]);
var bstr = arr.join("");
/* Call XLSX */
var workbook = XLSX.read(bstr, {
type: "binary"
});
/* DO SOMETHING WITH workbook HERE */
var first_sheet_name = workbook.SheetNames[0];
/* Get worksheet */
var worksheet = workbook.Sheets[first_sheet_name];
console.log(XLSX.utils.sheet_to_json(worksheet, {
raw: true
}));
}
oReq.send();
</script>
</body>
</html>
Input:
Output:
The answers are working fine with xls format but, in my case, it didn't work for xlsx format. Thus I added some code here. it works both xls and xlsx format.
I took the sample from the official sample link.
Hope it may help !
function fileReader(oEvent) {
var oFile = oEvent.target.files[0];
var sFilename = oFile.name;
var reader = new FileReader();
var result = {};
reader.onload = function (e) {
var data = e.target.result;
data = new Uint8Array(data);
var workbook = XLSX.read(data, {type: 'array'});
console.log(workbook);
var result = {};
workbook.SheetNames.forEach(function (sheetName) {
var roa = XLSX.utils.sheet_to_json(workbook.Sheets[sheetName], {header: 1});
if (roa.length) result[sheetName] = roa;
});
// see the result, caution: it works after reader event is done.
console.log(result);
};
reader.readAsArrayBuffer(oFile);
}
// Add your id of "File Input"
$('#fileUpload').change(function(ev) {
// Do something
fileReader(ev);
}
#Kwang-Chun Kang Thanks Kang a lot! I found the solution is working and very helpful, it really save my day.
For me I am trying to create a React.js component that convert *.xlsx to json object when user upload the excel file to a html input tag.
First I need to install XLSX package with:
npm install xlsx --save
Then in my component code, import with:
import XLSX from 'xlsx'
The component UI should look like this:
<input
accept=".xlsx"
type="file"
onChange={this.fileReader}
/>
It calls a function fileReader(), which is exactly same as the solution provided.
To learn more about fileReader API, I found this blog to be helpful:
https://blog.teamtreehouse.com/reading-files-using-the-html5-filereader-api
This is my expansion on https://stackoverflow.com/a/52237535/5079799
While it was working/great example, I'm not using an input form, but fetching from a URL and I have other things to do after fething workbook so I needed to wrap the onload into a promise.
See --> adjust onload function to be used with async/await
Here is what I ended up w/
async function Outside_Test(){
var reso = await Get_JSON()
console.log('reso_out')
console.log(reso)
}
async function Get_JSON() {
var url = "http://MyworkbookURL"
var workbook = await Get_XLSX_As_Workbook_From_URL(url)
/* DO SOMETHING WITH workbook HERE */
var first_sheet_name = workbook.SheetNames[0];
/* Get worksheet */
var worksheet = workbook.Sheets[first_sheet_name];
var reso = (XLSX.utils.sheet_to_json(worksheet, {
raw: true
}));
return reso
}
async function Get_XLSX_As_Workbook_From_URL(url) {
const arrayBuffer = await new Promise((resolve, reject) => {
var oReq = new XMLHttpRequest();
oReq.open("GET", url, true);
oReq.responseType = "arraybuffer";
oReq.onload = () => resolve(oReq.response);
oReq.onerror = reject;
oReq.send();
});
var data = new Uint8Array(arrayBuffer);
var arr = new Array();
for (var i = 0; i != data.length; ++i) arr[i] = String.fromCharCode(data[i]);
var bstr = arr.join("");
var workbook = XLSX.read(bstr, {
type: "binary"
});
return workbook
}

javascript to read file selects a file but doesn't read it

My script selects a file... but doesn't read it. I've been banging my head on it but can't make it work. It's part of my studies, I'm a greenhorn and I'm lost.
function readBlob() {
var files = document.getElementById('files').files;
if (!files.length) {
alert('Please select a file!');
return;
var file = files[0];
var start = 0;
var stop = file.size;
var reader = new FileReader();
if (file.webkitSlice) {
var blob = file.webkitSlice(start, stop);
//Creates new blob if using google chrome
} else if (file.mozSlice) {
var blob = file.mozSlice(start, stop);
//Creates new blob if using mozilla firefox
}
//read the contents of the file in as text into the blob
reader.readAsText(blob);
reader.onloadend = function(evt) {
if (evt.target.readyState == FileReader.DONE) {
document.getElementById('byte_content').textContent =
evt.target.result;
}
};
}
}
Seems like a simple syntax error to me, but maybe just an error inserting it into stack overflow. The entire thing, the slicing of the file, the insertion into the document, everything, is inside of the if (!files.length) statement. Therefore, the script only executes when there is no file (catching on to the problem yet :) but it is actually meant to do the opposite. All of the important stuff is supposed to be outside of the if statement.

HTML5 File API: get File object within FileReader callback

With the new File API in Javascript you can read files in Javascript to create dataURLs to show clientside pictures clientside. I'm wondering if you can reach the File object within the FileReader's onload callback.
I will illustrate this with an example:
var div = document.createElement('div');
div.ondrop = function(e) {
e.preventDefault();
e.stopPropagation();
var files = e.dataTransfer.files;
for ( var i=0; i<files.length; i++ ) {
var file = files[i]; // this is the file I want!!
var filereader = new FileReader();
filereader.onload = function(e) {
this; // the FileReader object
e.target; // the same FileReader object
this.result; // the dataURL, something like data:image/jpeg;base64,.....
var img = document.createElement('img');
img.src = this.result;
img.title = file.fileName; // This won't be working
document.appendChild(img);
}
}
return false;
}
What I could do - what I do right now - is wrap the contents of the for loop in a function and execute it to create a new scope and keep a file in that scope like so:
for ( var i=0; i<files.length; i++ ) {
var _file = files[i]; // this is the file I want!!
(function(file) {
// do FileReader stuff here
})(_file);
}
I was just wondering... Maybe I'm missing something. Is there a way to get the File object from within the onload function of the FileReader? Both this and e.target are the FileReader object and not the File. Is there something in this or e that is the File?? I can't find it :(
Thanks a bunch.
PS. A fiddle: http://jsfiddle.net/rudiedirkx/ZWMRd/1/
I already found a way. Maybe not better than the scope wrapper, but I think it's neater:
for ( var i=0; i<files.length; i++ ) {
var file = files[i]; // this is the file I want!!
var filereader = new FileReader();
filereader.file = file;
filereader.onload = function(e) {
var file = this.file; // there it is!
// do stuff
}
}
There is now a much easier (apparently faster) way (sync!) to get a file's data URL:
img.src = URL.createObjectURL(file);
Demo on http://jsfiddle.net/rudiedirkx/ZWMRd/8/show/ of both methods, and the original problem illustrated (drag multiple images and check the title tooltips).
I don't think this.file is still supported. When I try to run the answer code, this.file is undefined whereas if I run the code from the question I get the expected results. I think you have to use the closure (at least this is how they do it on html5rocks (Example)).

Categories

Resources