Cómo analizar un archivo Excel en Javascript / HTML5

136

Puedo leer el archivo de Excel a través de, FileReaderpero genera texto y caracteres extraños con él. Necesito leer el xlsarchivo en filas, leer los datos en cada columna y convertirlo a JSON.

¿Cómo leer el archivo xls fila por fila?

tipo pato
fuente
1
posible duplicado de Cómo leer el contenido de un archivo de Excel en el lado del cliente?
Algún programador amigo
1
@JoachimPileborg: esto no responde la pregunta. Necesito leer el archivo de Excel fila por fila. Aunque puedo leerlo usando FileReader (HTML5) pero aún no puedo navegar por las filas.
pato el

Respuestas:

104

La siguiente función convierte los datos de la hoja de Excel (formato XLSX) a JSON. Puedes agregar promesa a la función.

<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.8.0/jszip.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.8.0/xlsx.js"></script>
<script>
var ExcelToJSON = function() {

  this.parseExcel = function(file) {
    var reader = new FileReader();

    reader.onload = function(e) {
      var data = e.target.result;
      var workbook = XLSX.read(data, {
        type: 'binary'
      });

      workbook.SheetNames.forEach(function(sheetName) {
        // Here is your object
        var XL_row_object = XLSX.utils.sheet_to_row_object_array(workbook.Sheets[sheetName]);
        var json_object = JSON.stringify(XL_row_object);
        console.log(json_object);

      })

    };

    reader.onerror = function(ex) {
      console.log(ex);
    };

    reader.readAsBinaryString(file);
  };
};
</script>

Debajo de la publicación tiene el código para el formato XLS de Excel a JSON código JavaScript?

Perú
fuente
1
se bloquea por archivos de Excel más grandes en Chrome, ¿alguna buena solución para eso?
Zed
¿Puedo saber qué tan grande es tu archivo?
Perú
66
e.target.result () debe ser e.target.result, consulte developer.mozilla.org/en-US/docs/Web/API/FileReader/onload
user227353
3
Para mí, tuve que declarar jszip.jsscript antes xlsx.js.
Florin Vîrdol
1
¿Cómo puedo asignar json_object a la variable pública y acceder a ella fuera del ciclo for?
Shardul
109

Antigua pregunta, pero debo tener en cuenta que la tarea general de analizar archivos XLS desde JavaScript es tediosa y difícil, pero no imposible.

Tengo analizadores básicos implementados en JS puro:

Ambas páginas son analizadores XLS / XLSX de HTML5 File API (puede arrastrar y soltar su archivo e imprimirá los datos en las celdas en una lista separada por comas). También puede generar objetos JSON (suponiendo que la primera fila sea una fila de encabezado).

El conjunto de pruebas http://oss.sheetjs.com/ muestra una versión que utiliza XHR para obtener y analizar archivos.

SheetJS
fuente
44
Si pudiera agregar un código de muestra a la respuesta, sería mucho mejor (también agregue un diaclaimer si usted es el líder de las bibliotecas).
acdcjunior
3
Publiqué un blog sobre esto psjinx.com/programming/2014/01/04/… :)
pankaj28843
¿Podríamos omitir algunas filas y columnas superiores de xlsx con JS-XLSX?
mayank
19

Suba excel fileaquí y puede obtener los datos en JSONformato en console:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.8.0/jszip.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.8.0/xlsx.js"></script>
<script>
    var ExcelToJSON = function() {

      this.parseExcel = function(file) {
        var reader = new FileReader();

        reader.onload = function(e) {
          var data = e.target.result;
          var workbook = XLSX.read(data, {
            type: 'binary'
          });
          workbook.SheetNames.forEach(function(sheetName) {
            // Here is your object
            var XL_row_object = XLSX.utils.sheet_to_row_object_array(workbook.Sheets[sheetName]);
            var json_object = JSON.stringify(XL_row_object);
            console.log(JSON.parse(json_object));
            jQuery( '#xlx_json' ).val( json_object );
          })
        };

        reader.onerror = function(ex) {
          console.log(ex);
        };

        reader.readAsBinaryString(file);
      };
  };

  function handleFileSelect(evt) {
    
    var files = evt.target.files; // FileList object
    var xl2json = new ExcelToJSON();
    xl2json.parseExcel(files[0]);
  }


 
</script>

<form enctype="multipart/form-data">
    <input id="upload" type=file  name="files[]">
</form>

    <textarea class="form-control" rows=35 cols=120 id="xlx_json"></textarea>

    <script>
        document.getElementById('upload').addEventListener('change', handleFileSelect, false);

    </script>

Esta es una combinación de las siguientes Stackoverflowpublicaciones:

  1. https://stackoverflow.com/a/37083658/4742733
  2. https://stackoverflow.com/a/39515846/4742733

Buena suerte...

Akash
fuente
14

Este código te puede ayudar
La mayoría de las veces jszip.js no funciona, así que incluya xlsx.full.min.js en su código js.

Código HTML

 <input type="file" id="file" ng-model="csvFile"  
    onchange="angular.element(this).scope().ExcelExport(event)"/>

Javascript

<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.8.0/xlsx.js">
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.8.0/jszip.js">
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.10.8/xlsx.full.min.js">
</script>

$scope.ExcelExport= function (event) {


    var input = event.target;
    var reader = new FileReader();
    reader.onload = function(){
        var fileData = reader.result;
        var wb = XLSX.read(fileData, {type : 'binary'});

        wb.SheetNames.forEach(function(sheetName){
        var rowObj =XLSX.utils.sheet_to_row_object_array(wb.Sheets[sheetName]);
        var jsonObj = JSON.stringify(rowObj);
        console.log(jsonObj)
        })
    };
    reader.readAsBinaryString(input.files[0]);
    };
afzalriz304
fuente
¿Qué pasa si quiero subir imágenes también en la hoja de Excel
Mayur Agarwal
9

Si desea la forma más simple y pequeña de leer un archivo * .xlsx en un navegador, esta biblioteca podría hacer lo siguiente:

https://catamphetamine.github.io/read-excel-file/

<input type="file" id="input" />
import readXlsxFile from 'read-excel-file'

const input = document.getElementById('input')

input.addEventListener('change', () => {
  readXlsxFile(input.files[0]).then((data) => {
    // `data` is an array of rows
    // each row being an array of cells.
  })
})

En el ejemplo anterior datason datos de cadena sin formato. Se puede analizar a JSON con un esquema estricto pasandoschema argumento. Vea los documentos de API para un ejemplo de eso.

Documentos de la API: http://npmjs.com/package/read-excel-file

catamphetamine
fuente
4

Gracias por la respuesta anterior, creo que el alcance (de las respuestas) se ha completado, pero me gustaría agregar una "forma de reacción" para quien usa react.

Cree un archivo llamado importData.js:

import React, {Component} from 'react';
import XLSX from 'xlsx';
export default class ImportData extends Component{
    constructor(props){
        super(props);
        this.state={
            excelData:{}
        }
    }
    excelToJson(reader){
        var fileData = reader.result;
        var wb = XLSX.read(fileData, {type : 'binary'});
        var data = {};
        wb.SheetNames.forEach(function(sheetName){
             var rowObj =XLSX.utils.sheet_to_row_object_array(wb.Sheets[sheetName]);
             var rowString = JSON.stringify(rowObj);
             data[sheetName] = rowString;
        });
        this.setState({excelData: data});
    }
    loadFileXLSX(event){
        var input = event.target;
        var reader = new FileReader();
        reader.onload = this.excelToJson.bind(this,reader);
        reader.readAsBinaryString(input.files[0]);
    }
    render(){
        return (
            <input type="file" onChange={this.loadFileXLSX.bind(this)}/>
        );
    }
}

Luego puede usar el componente en el método de representación como:

import ImportData from './importData.js';
import React, {Component} from 'react';
class ParentComponent extends Component{
    render(){
        return (<importData/>);
    }
}

<ImportData/>establecería los datos en su propio estado, puede acceder a los datos de Excel en el "componente principal" siguiendo esto :

Las puertas de sion
fuente
Creo que la etiqueta en la declaración de devolución debería ser en <ImportData/>lugar de <importData/>. Soy bastante nuevo en React pero creo que los nombres de los componentes siempre están en mayúscula. En cualquier caso, ese es el nombre utilizado al importar en el ejemplo.
rhaben
3

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.8.0/jszip.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.8.0/xlsx.js"></script>
<script>
    var ExcelToJSON = function() {

      this.parseExcel = function(file) {
        var reader = new FileReader();

        reader.onload = function(e) {
          var data = e.target.result;
          var workbook = XLSX.read(data, {
            type: 'binary'
          });
          workbook.SheetNames.forEach(function(sheetName) {
            // Here is your object
            var XL_row_object = XLSX.utils.sheet_to_row_object_array(workbook.Sheets[sheetName]);
            var json_object = JSON.stringify(XL_row_object);
            console.log(JSON.parse(json_object));
            jQuery( '#xlx_json' ).val( json_object );
          })
        };

        reader.onerror = function(ex) {
          console.log(ex);
        };

        reader.readAsBinaryString(file);
      };
  };

  function handleFileSelect(evt) {
    
    var files = evt.target.files; // FileList object
    var xl2json = new ExcelToJSON();
    xl2json.parseExcel(files[0]);
  }


 
</script>

<form enctype="multipart/form-data">
    <input id="upload" type=file  name="files[]">
</form>

    <textarea class="form-control" rows=35 cols=120 id="xlx_json"></textarea>

    <script>
        document.getElementById('upload').addEventListener('change', handleFileSelect, false);

    </script>

amin
fuente
0

Si alguna vez se pregunta cómo leer un archivo del servidor, este código puede ser útil.

Restricciones:

  1. El archivo debe estar en el servidor (Local / Remoto).
  2. Tendrá que configurar encabezados o tener el complemento de Google CORS.

<Head>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
    <script lang="javascript" src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.12.4/xlsx.core.min.js"></script>
</head>

<body>
    <script>
    /* set up XMLHttpRequest */


    // replace it with your file path in local server
    var url = "http://localhost/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("");

        var cfb = XLSX.read(bstr, { type: 'binary' });

        cfb.SheetNames.forEach(function(sheetName, index) {

            // Obtain The Current Row As CSV
            var fieldsObjs = XLS.utils.sheet_to_json(cfb.Sheets[sheetName]);

            fieldsObjs.map(function(field) {
                $("#my_file_output").append('<input type="checkbox" value="' + field.Fields + '">' + field.Fields + '<br>');
            });

        });
    }

    oReq.send();
    </script>
</body>
<div id="my_file_output">
</div>

</html>
Vijay Reddy
fuente
0

incluye los xslx.js, xlsx.full.min.js, jszip.js

agregar un controlador de eventos onchange a la entrada del archivo

function showDataExcel(event)
{
            var file = event.target.files[0];
            var reader = new FileReader();
            var excelData = [];
            reader.onload = function (event) {
                var data = event.target.result;
                var workbook = XLSX.read(data, {
                    type: 'binary'
                });

                workbook.SheetNames.forEach(function (sheetName) {
                    // Here is your object
                    var XL_row_object = XLSX.utils.sheet_to_row_object_array(workbook.Sheets[sheetName]);

                    for (var i = 0; i < XL_row_object.length; i++)
                    {
                        excelData.push(XL_row_object[i]["your column name"]);

                    }

                    var json_object = JSON.stringify(XL_row_object);
                    console.log(json_object);
                    alert(excelData);
                })

            };

            reader.onerror = function (ex) {
                console.log(ex);
            };

            reader.readAsBinaryString(file);

}
vsnahar
fuente
-4

XLS es un formato propietario binario utilizado por Microsoft. Analizar XLS con los idiomas del lado del servidor es muy difícil sin usar alguna biblioteca específica o Office Interop. Hacer esto con javascript es una misión imposible. Gracias a la API de archivos HTML5, puede leer su contenido binario, pero para analizarlo e interpretarlo deberá profundizar en las especificaciones del formato XLS . A partir de Office 2007, Microsoft adoptó los formatos de archivo Open XML ( xslxpara Excel), que es un estándar.

Darin Dimitrov
fuente
@ducktyped, no conozco ni he visto ningún código javascript que lea un archivo binario de Excel.
Darin Dimitrov el
13
¿Misión imposible? Lo dudo. Si podemos ejecutar el kernel de Linux en javascript del lado del cliente, entonces debería ser posible analizar un archivo binario de Excel. Es que nadie que yo sepa lo haya hecho todavía.
JP Richardson
Aquí está la documentación para curiosos de la estructura ms xls msdn.microsoft.com/en-us/library/office/…
djra
-5

var excel = new ActiveXObject ("Excel.Application"); var book = excel.Workbooks.Open (your_full_file_name_here.xls); var sheet = book.Sheets.Item (1); valor var = hoja. Rango ("A1");

cuando tengas la sábana. Puede usar las funciones de VBA como lo hace en Excel.

i100
fuente
66
esto solo funciona con "nuestro querido amigo" IE. Y necesito usar HTML5. Solo necesito examinar el contenido de texto real fila por fila.
Ducktyped