Convertir un Archivo Excel a JSON con Sheet JS

Publicado el 12 agosto 2018 por Juan Ricardo Castro Lurita @pepoflex

Demo Github

En determinadas ocasiones necesitas convertir un archivo Excel a JSON, puedes hacerlo con la librería Sheet JS que nos da la posibilidad de convertir un archivo Excel a formato JSON y muchos otros formatos más, teniendo los datos en JSON puedes crear aplicaciones más dinámicas y usables, veamos como hacerlo en este artículo.

Desplegando Sheet JS

Sheet JS esta moderna librería Javascript usa Webworkers para trabajar de manera óptima la ejecución de los procesos a llevar a cabo para convertir un archivo Excel a JSON.

Vamos a declarar el formato que usaremos el cual es XLSX (Extensión de un archivo Excel), asimismo vamos a usar la librería xlsxworker.js para ejecutar en segundo plano el proceso de conversión del archivo Excel a JSON

var X = XLSX;
var XW = {
	msg: 'xlsx',
	worker: 'js/xlsxworker.js'
};

Bien iniciamos el webworker y el proceso para crear un archivo JSON en segundo plano

var webworkers;

var ejecutar_webworkers = (function() {
	var OUT = document.getElementById('json');

	var crear_json = (function() {
		var fmt= document.getElementsByName( "JSON" );
		return function() {
			for(var i = 0; i < fmt.length; ++i) if(fmt[i].checked || fmt.length === 1) return fmt[i].value;
		};
	})();

	var to_json = function to_json(workbook) {
		var result = {};
		workbook.SheetNames.forEach(function(sheetName) {
			var roa = X.utils.sheet_to_json(workbook.Sheets[sheetName], {header:1});
			if(roa.length) result[sheetName] = roa;
		});
		return JSON.stringify(result, 2, 2);
	};

	return function ejecutar_webworkers(wb) {
		webworkers = wb;
		var output = "";
		switch(crear_json()) {
			default: output = to_json(wb);
		}
		if(OUT.innerText === undefined) OUT.textContent = output;
		else OUT.innerText = output;
		if(typeof console !== 'undefined') console.log("output", new Date());
	};
})();

Una ves que leemos el formato Excel, pasamos a la creamos el archivo JSON

var do_file = (function() {
	var rABS = typeof FileReader !== "undefined" & (FileReader.prototype||{}).readAsBinaryString;
	var domrabs = document.getElementsByName("userabs")[0];

	var use_worker = typeof Worker !== 'undefined';
	var domwork = document.getElementsByName("useworker")[0];

	var xw = function xw(data, cb) {
		var worker = new Worker(XW.worker);
		worker.onmessage = function(e) {
			switch(e.data.t) {
				case 'ready': break;
				case 'e': console.error(e.data.d); break;
				case XW.msg: cb(JSON.parse(e.data.d)); break;
			}
		};
		worker.postMessage({d:data,b:rABS?'binary':'array'});
	};

	return function do_file(files) {
		
		var f = files[0];
		var reader = new FileReader();
		reader.onload = function(e) {
			if(typeof console !== 'undefined') console.log("onload", new Date(), rABS, use_worker);
			var data = e.target.result;
			if(!rABS) data = new Uint8Array(data);
			if(use_worker) xw(data, ejecutar_webworkers);
			else ejecutar_webworkers(X.read(data, {type: rABS ? 'binary' : 'array'}));
		};
		if(rABS) reader.readAsBinaryString(f);
		else reader.readAsArrayBuffer(f);
	};
})();

Por ultimo ejecutamos el evento de mostrar el JSON al cargar un archivo Excel desde el <select>

(function() {
	var xlf = document.getElementById('xlf');
	if(!xlf.addEventListener) return;
	function handleFile(e) { do_file(e.target.files); }
	xlf.addEventListener('change', handleFile, false);
})();

Aca tenemos el código completo, lo colocamos en un archivo llamado app.js

var X = XLSX;
var XW = {
	msg: 'xlsx',
	worker: 'js/xlsxworker.js'
};

var webworkers;

var ejecutar_webworkers = (function() {
	var OUT = document.getElementById('json');

	var crear_json = (function() {
		var fmt= document.getElementsByName( "JSON" );
		return function() {
			for(var i = 0; i < fmt.length; ++i) if(fmt[i].checked || fmt.length === 1) return fmt[i].value;
		};
	})();

	var to_json = function to_json(workbook) {
		var result = {};
		workbook.SheetNames.forEach(function(sheetName) {
			var roa = X.utils.sheet_to_json(workbook.Sheets[sheetName], {header:1});
			if(roa.length) result[sheetName] = roa;
		});
		return JSON.stringify(result, 2, 2);
	};

	return function ejecutar_webworkers(wb) {
		webworkers = wb;
		var output = "";
		switch(crear_json()) {
			default: output = to_json(wb);
		}
		if(OUT.innerText === undefined) OUT.textContent = output;
		else OUT.innerText = output;
		if(typeof console !== 'undefined') console.log("output", new Date());
	};
})();


var do_file = (function() {
	var rABS = typeof FileReader !== "undefined" & (FileReader.prototype||{}).readAsBinaryString;
	var domrabs = document.getElementsByName("userabs")[0];

	var use_worker = typeof Worker !== 'undefined';
	var domwork = document.getElementsByName("useworker")[0];

	var xw = function xw(data, cb) {
		var worker = new Worker(XW.worker);
		worker.onmessage = function(e) {
			switch(e.data.t) {
				case 'ready': break;
				case 'e': console.error(e.data.d); break;
				case XW.msg: cb(JSON.parse(e.data.d)); break;
			}
		};
		worker.postMessage({d:data,b:rABS?'binary':'array'});
	};

	return function do_file(files) {
		
		var f = files[0];
		var reader = new FileReader();
		reader.onload = function(e) {
			if(typeof console !== 'undefined') console.log("onload", new Date(), rABS, use_worker);
			var data = e.target.result;
			if(!rABS) data = new Uint8Array(data);
			if(use_worker) xw(data, ejecutar_webworkers);
			else ejecutar_webworkers(X.read(data, {type: rABS ? 'binary' : 'array'}));
		};
		if(rABS) reader.readAsBinaryString(f);
		else reader.readAsArrayBuffer(f);
	};
})();

(function() {
	var xlf = document.getElementById('xlf');
	if(!xlf.addEventListener) return;
	function handleFile(e) { do_file(e.target.files); }
	xlf.addEventListener('change', handleFile, false);
})();

Vista

Ahora en nuestra vista vamos instanciar 2 archivos uno es nuestro archivo creado app.js y el otro es la libreria de Sheet JS, los colocamos al final antes de cerrar la etiqueta </body>

<!-- Librería Sheet JS y archivo de configuracion app.js -->
     <script src="js/xlsx.full.min.js"></script>
     <script src="js/app.js"></script>
    
  </body>
</html>

Por ultimo para nuestro ejemplo vamos a imprimir los datos en una página html, lo que haremos es colocar 2 elementos HTML y selector de archivos <select> y un contenedor de tipo <pre> en donde mostraremos el JSON del archivo Excel que carguemos con el <select>

<div class="row text-center">          	
   <div class="col-md-12">				
      <input type="file" name="cargararchivo" id="cargararchivo" />
   </div>
</div>

<div class="row mt-3">
   <div class="col-md-12">
      <pre id="json"></pre>
   </div>
</div>

Conclusión

Puedes leer en la documentación oficial de su repositorio Github más funciones y formatos para manipular archivos Excel, la idea de este artículo es guiarte con los primeros pasos con Sheet JS.

Si deseas ver el resultado final, puedes ver el Demo que esta al inicio de este artículo.

imagen: techlaunch.io

Síguenos en las Redes Sociales para que no te pierdas nuestros próximos contenidos.