Lo mejor de utilizar un lenguaje de programación tan popular como Java es que para cada necesidad hay una librería. El otro día necesitaba recorrer un fichero Excel (como parte de un generador de bots para Xatkit) y empecé a buscar cuál era la mejor manera de procesar ficheros Excel en Java. Hubo un ganador claro, la librería Apache POI, que sirve también para los otros archivos de Microsoft Office. No es la única alternativa pero creedme, no hay ninguna mejor hoy en día. Y si no me creéis, mirad lo fácil que es leer hojas de cálculo con ella.
Instalando Apache POI
Basta con añadir estas dos dependencias a tu fichero pom.xml (para proyectos Maven). Si lo prefieres también te las puedes descargar tú mismo.
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>4.1.2</version> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>4.1.2</version> </dependency>
Abriendo el fichero Excel
Sólo tienes que abrir un InputStream
al fichero y crear una instancia de la clase WorkBook a partir de ahí. Esta clase es la que te da acceso al contenido del fichero. Por ejemplo, puedes acceder a la primera hoja de cálculo con getSheetAt
(fijaros que aquí también contamos a partir de cero).
File f = new File("PATH\FICHERO.xlsx"); InputStream inp = new FileInputStream(f); Workbook wb = WorkbookFactory.create(inp); sheet = wb.getSheetAt(0);
Recorriendo el fichero Excel
Una vez tenemos acceso a la hoja podemos acceder a sus filas, columnas y celdas de una forma muy intuitiva. Por ejemplo éste código os imprimirá el contenido de todas las celdas de la segunda columna de la hoja. Lo que hacemos es recorrer cada fila del excel (hasta llegar al final) y para cada fila acceder a la celda en segunda posición, recuperar su valor e imprimirlo.
Row row = sh.getRow(iRow); //En qué fila empezar ya dependerá también de si tenemos, por ejemplo, el título de cada columna en la primera fila while(row!=null) { Cell cell = row.getCell(1); String value = cell.getStringCellValue(); System.out.println("Valor de la celda es " + value); iRow++; row = sh.getRow(iRow); }
Este código es muy esquemático y no controla todos los errores que nos podemos controlar, por ejemplo, el hecho de qué la celda en una de las filas esté vacía. Apache POI permite indicar si quieres que los vacíos se devuelvan como valores nulos o cadenas vacías (y lo mismo para las celdas inexistentes) para controlar mejor cuando quieres que se pare el recorrido por el Excel.
Modificando el fichero Excel
Igual que podemos leer el archivo, podemos modificarlo. Se puede añadir nuevas filas ( sh.createRow
), modificar valores de celdas existentes ( cell.setCellValue
) y todo lo que se te pueda ocurrir. Aquí podéis ver ejemplos de modificación de ficheros Excel en Java.
Espero que este post os sirva para ver hasta qué punto es fácil trabajar con Excel. Algo que seguramente os tocará hacer en algún momento de vuestra vida profesional. Y es que Excel genera controversias (esta es la última) pero sigue siendo una de las mejores opciones para analizar y manipular datos sin tener que ser experto programador, lo que convierte Excel en la opción por defecto en muchas empresas.
Imagen destacada por Mika Baumeister en Unsplash
Hola, interesante post, hice la prueba y funciona bien, sin embargo no he logrado que me devuelva el resultado de una celda con formula y no la formula en si. Alguna idea?
Apache POI viene con un evaluador de fórmulas que puedes utilizar para ese fin: https://poi.apache.org/components/spreadsheet/eval.html
que clase de variable es “sheet” , “sh” y debo dar por hecho que “iRow” es un int , cierto ??
El tipo es org.apache.poi.ss.usermodel.Sheet y , sí, entero el iRow.
Recuerda que tienes la documentación de todas las clases aqui: https://poi.apache.org/apidocs/dev/overview-summary.html
Hola. Siempre me da un error de excepción. ¿Que puede ser? Gracias.
Yo de nuevo. Se planta en esta instrucción Workbook wb = WorkbookFactory.create(inp);
Pues así sin más no sé que te puede pasar, mírate las instrucciones de la librería e intenta utilizar algún otro de los ejemplos que dan
Hola, una pregunta, si tengo 10 columnas fijas pero puede suceder que la columna 3 en algunos renglones esté en blanco, como puedo hacer para que estas las lea de manera correcta ya que en el Iterator cuando esta en blanco la columna no la toma
Supongo que puedes pasar a un “for” clásico con el que recorrer siempre 10 columnas (y luego chequear si la columna “i” tiene un valor o está en blanco)
Hola, es una buena forma de leer! solo una duda, si se quiere meter eso que se lee a una base de datos donde los encabezados son String pero su contenido es numerico, sería recomendable hacer un Value() ?
Si lo vas a guardar en una base de datos, el objetivo es convertir el tipo que leas (con el método que sea) al tipo que espera la columna de la base de datos antes de guardarlo
Eres un grande, logré meter los datos extaídos a una base de datos! solo una duda, la variable row de tipo Row que esta dentro del bucle while.. lee hasta que sea igual a null? es decir, row puede devolver la palabra null? … tengo entendido que row contiene la información de cada fila y al tener la fila puedo seleccionar que celda d la fila deseo extraer, pero me interaba saber si la variable row puede devolver precisamente la palabra null.
Si no recuerdo mal esto era configurable (no es lo mismo que haya una fila en blanco en mitad del excel que el conjunto de filas en blanco que hay después de la última fila con datos). Mejor mira la documentación de la librería.
No puedo leer mas de 400 mil datos como puedo hacerlo?
Sinceramente, ni idea. Tendrás que preguntar al autor de la librería a ver si hay alguna limitación “hardcoded” en el código o es un problema de que con tantos datos en algún momento tienes un time-out o problemas de memoria.
Hola, soy yo ezequiel de nuevo, en el 2022 te hice comentarios acerca de como leer documentos excel en java. me gustaría saber si hay una forma de contactarte ya que he vuelto retomar java para dedicarme de lleno a aprender java con spring. me gustaría saber si hay una forma de contactarte 🙂 saludos.