How to get excel sheet names in JavaScript - javascript

I am trying to get the list of the sheets from an excel file in order to display it in a combobox. The idea is that the user can select the file that he want to import from an excel file instead of typing and avoid typo errors
function getSheets(file)
{
var reader;
reader = new FileReader();
reader.onload = function(e)
{
var data;
var workbook;
var sheets;
data = e.target.result();
workbook = XLSX.read(data, {type: 'binary'});
sheet = workbook.SheetNames;
for (var i in sheets.items)
{
console.log(sheets.items[i].name);
}
}
reader.onerror = function(ex)
{
console.log(ex);
}
reader.readAsBinaryString(file);
}
The following error is displayed when the function is executed:
Function expected on line: data = e.target.result();
Any idea of how should I face it?

Detail explaination can be found Here
sheet.forEach(function (y) { /*Iterate through all sheets*/
/*Convert the cell value to Json*/
var exceljson = XLSX.utils.sheet_to_json(workbook.Sheets[y]);
});

In NodeJS you can use the Node XLSX (NodeJS excel file parser & builder).
There is a parse method that reads the Excel file and gives you an array of all it's sheets.
Then you could loop the array and get the name of each sheet and all the data.
To Install the package use:
npm install node-xlsx --save
This code will print all the sheet names in an Excel file:
var xlsx = require('node-xlsx');
const worksheetsArray = xlsx.parse('example.xlsx'); // parses a file
worksheetsArray.forEach(sheet => {
console.log(sheet.name);
})

I like to use the following lib: npm install xlsx
const xlsx = require('xlsx')
const workbook = xlsx.readFile(file); //Here you should pass the file path
const sheetList = workbook.SheetNames; //Array of sheet names.
console.log(sheetList)

Related

XLSX to CSV file convert for API call

Im trying to convert .xlsx file to .csv file before i send it to the API (because it accepts only .csv files) ;
I am using package xlsx and i got this function that converts it for me but problem is that this function will make the user download the file, and i don't want that i just want that it saves it kinda in like a object so i can use it only for the api (and don't let know the user that its converted ).
Here is code:
file.arrayBuffer().then(res => {
let data = new Uint8Array(res)
let workbook = XLSX.read(data, {type: "array"})
let first_sheet_name = workbook.SheetNames[0]
let worksheet = workbook.Sheets[first_sheet_name]
let jsonData = XLSX.utils.sheet_to_json(worksheet, {raw: false, defval: null})
let fileName;
if (file) {
fileName = file?.name.substring(0, file?.name?.indexOf("."))
}
let new_worksheet = XLSX.utils.json_to_sheet(jsonData);
let new_workbook = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(new_workbook, new_worksheet, "csv_sheet")
getRandomRows(jsonData)
XLSX.writeFile(new_workbook, fileName + ".csv")
})
Was wondering if there are other options too.
Based on Readme from xlsx try to use writeFileAsync or just write instead of writeFile as it force browser to start download
I fixed it this way :
let dataToSheet = XLSX.utils.json_to_sheet(data)
const dataFileCSV = XLSX.utils.sheet_to_csv(dataToSheet, {raw: false, defval: null});
let blob = new Blob(["\ufeff", dataFileCSV]);
let fileBlob = new File([blob], "name");

Read a csv or excel (xlsx) file with just javascript and html?

Is it possible to read a excel xlsx or csv, preferably xlsx, using just JavaScript and html. All the solutions (sheetsJS, d3{d3 uses the Fetch API}) I have found require a webserver. I understand I can get a simple webserver using web server for chrome or python or node.js. Futhermore, I understand I can run chrome with certain flags, but I would like to not do this because of security concerns. I am building a demo for someone who is not web savvy and would like to avoid doing this.
my file structure is very simple :
TestFolder
| index.html
| js/
| test.js
| data/
| test.xlsx
| css/
| test.css
I simply need to read the xlsx and then display that data in html page.
I've added a simple example that accepts Excel or CSV files (current example accepts a single file), uses the SheetJS library to parse the Excel file type, convert the data to JSON and logs the contents to the console.
This should be more than enough to complete your demo. Hope this helps!
var file = document.getElementById('docpicker')
var viewer = document.getElementById('dataviewer')
file.addEventListener('change', importFile);
function importFile(evt) {
var f = evt.target.files[0];
if (f) {
var r = new FileReader();
r.onload = e => {
var contents = processExcel(e.target.result);
console.log(contents)
}
r.readAsBinaryString(f);
} else {
console.log("Failed to load file");
}
}
function processExcel(data) {
var workbook = XLSX.read(data, {
type: 'binary'
});
var firstSheet = workbook.SheetNames[0];
var data = to_json(workbook);
return data
};
function to_json(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;
});
return JSON.stringify(result, 2, 2);
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.14.3/xlsx.full.min.js"></script>
<label for="avatar">Choose an Excel or CSV file:</label>
<input type="file" id="docpicker" accept=".csv,application/vnd.ms-excel,.xlt,application/vnd.ms-excel,.xla,application/vnd.ms-excel,.xlsx,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,.xltx,application/vnd.openxmlformats-officedocument.spreadsheetml.template,.xlsm,application/vnd.ms-excel.sheet.macroEnabled.12,.xltm,application/vnd.ms-excel.template.macroEnabled.12,.xlam,application/vnd.ms-excel.addin.macroEnabled.12,.xlsb,application/vnd.ms-excel.sheet.binary.macroEnabled.12">
<div id="dataviewer">
You could try using the Fetch API to download the file and process it with JavaScript.
fetch('data/test.xlsx').then(function(resp) {
// Process the data here...
console.log('Data Response: ', resp);
});
It would be much easier to work with if your data file was in JSON format, but this might work for your needs.
Update - Example when the data is in JSON format
fetch('data/test.xlsx').then(function(resp) {
var records = resp.json(); // Assuming that we receive a JSON array.
console.log('Records: ', records.length);
records.forEach(function(record){
console.log('Record Name: ', record.name); // Assuming each record has a name property
});
});
Here is how I ended up doing it:
I got error w/ readAsBinaryString so I went out w/ the below. I noted that sheet_to_json didn't work w/ csv so I ran that first and checked results and parsed sheet_to_csv if sheet_to_json === 0.
HTML:
<!-- SheetsJS CSV & XLSX -->
<script src="xlsx/xlsx.full.min.js"></script>
<!-- SheetsJS CSV & XLSX -->
<!-- CSV/XLSX -->
<div class="ms-font-xl ms-settings__content__subtitle">CSV/XLSX Upload:</div>
<input type="file" id="csv-xlsx-file" accept=".csv,application/vnd.ms-excel,.xlt,application/vnd.ms-excel,.xla,application/vnd.ms-excel,.xlsx,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,.xltx,application/vnd.openxmlformats-officedocument.spreadsheetml.template,.xlsm,application/vnd.ms-excel.sheet.macroEnabled.12,.xltm,application/vnd.ms-excel.template.macroEnabled.12,.xlam,application/vnd.ms-excel.addin.macroEnabled.12,.xlsb,application/vnd.ms-excel.sheet.binary.macroEnabled.12">
<!-- CSV/XLSX -->
JS:
var csv_file_elm = document.getElementById("csv-xlsx-file")
csv_file_elm.addEventListener('change', CSV_XLSX_File_Selected_Event)
async function CSV_XLSX_File_Selected_Event() {
var id = this.id
var inputElement = document.getElementById(id)
let ext = inputElement.value
ext = ext.split(".")
ext = ext[ext.length - 1]
var files = inputElement.files || [];
if (!files.length) return;
var file = files[0];
var reader = new FileReader();
reader.onloadend = async function (event) {
var arrayBuffer = reader.result;
var options = { type: 'array' };
var workbook = XLSX.read(arrayBuffer, options);
//console.timeEnd();
var sheetName = workbook.SheetNames
var sheet = workbook.Sheets[sheetName]
var sheet_to_html = XLSX.utils.sheet_to_html(sheet)
var sheet_to_json = XLSX.utils.sheet_to_json(sheet)
if (sheet_to_json.length === 0) {
var sheet_to_csv = [XLSX.utils.sheet_to_csv(sheet)]
var results = sheet_to_csv
}
if (sheet_to_json.length > 0) {
var results = sheet_to_json
}
let Parsed_File_Obj = {
"sheet_to_html": sheet_to_html,
"results": results,
"ext": ext,
}
console.log('Parsed_File_Obj')
console.log(Parsed_File_Obj)
};
reader.readAsArrayBuffer(file);
}

How can I get the local path of the currently open excel workbook?

I'm using the default 'Excel web add-in' template in Visual Studio 2017. I'm trying to create an excel add-in that inserts a copy of an existing workbook into the current one. The first step is to get the full path and name of the current workbook. I got the code from here. I'm using the beta excel API. At the line 'var myFile = document.getElementById("file");' myFile is always null. I assume the null value is because the workbook isn't 'loaded' but the workbook does open when I run the program.
Here is the code from Home.js:
'use strict';
(function () {
Office.onReady(function () {
// Office is ready
$(document).ready(function () {
// The document is ready
$('#RunMacroButton').click(RunMacro);
});
});
function RunMacro() {
var myFile = document.getElementById("file");
var reader = new FileReader();
reader.onload = (function (event) {
Excel.run(function (context) {
// strip off the metadata before the base64-encoded string
var startIndex = event.target.result.indexOf("base64,");
var workbookContents = event.target.result.substr(startIndex + 7);
Excel.createWorkbook(workbookContents);
return context.sync();
}).catch(errorHandlerFunction);
});
// read in the file as a data URL so we can parse the base64-encoded string
reader.readAsDataURL(myFile.files[0]);
}
})();
The line 'var myFile = document.getElementById("file");' is always null because there is no element called "file". This is also the wrong way to get the path of the currently open workbook. Instead use 'Office.context.document.url' to return the path.

Import Data From Excel To MySql With Node JS

I want to read excel to save in MySQL database by using NodeJS. I do not know what library to use. I want to be able to read excel based on certain rows and columns. Please help me.
There are many libraries that you can use :
sheetjs/xlsx
excel.js
etc.
There's a great library SheetJS/js-xlsx that provides an API for reading Excel documents.
For example, if you are uploading a file, you'll end up with something like this:
var XLSX = require('xlsx');
function importFromExcel(file) {
var reader = new FileReader();
reader.onload = function (e) {
/* read workbook */
var bstr = e.target.result;
var workbook = XLSX.read(bstr, { type: 'binary' });
/* for each sheet, grab a sheet name */
workbook.SheetNames.forEach(function (workSheetName, index) {
var sheetName = workbook.SheetNames[index];
var workSheet = workbook.Sheets[sheetName];
var excelData = (XLSX.utils.sheet_to_json(workSheet, { header: 1 }));
mapExcelData(excelData); // do whatever you want with your excel data
});
};
reader.readAsBinaryString(file);
}
function mapExcelData(data) {...}

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
}

Categories

Resources