Leer excel - POI

Apache Poi es un proyecto establecido para crear y mantener una solución para los documentos Microsoft.
Con el API del mismo nombre podemos leer y escribir archivos Excel como también Word y PowerPoint.
En este tema hablaremos de un grupo de clases que es de gran ayuda en nuestras labores como por ejemplo en la manipulación de archivos Excel:

POIFSFileSystem
HSSFWorkbook
HSSFSheet
Row
Cell

POIFSFileSystem : Esta clase es la principal del sistema POIFS encargada de la gestión en el uso de los archivos.
En esta clase podemos encontrar un constructor que recibe un parámetro de tipo InputStream.

Exported from Notepad++
String strRutaArchivo="/home/arielb/documento.xls"; FileInputStream archivoEntrada = new FileInputStream(strRutaArchivo); POIFSFileSystem poiArchivo = new POIFSFileSystem(archivoEntrada);

HSSFWorkbook: Esta es la clase utilizada para manipular el objeto resultante del archivo físico ya sea para escribir, leer y agregar nuevas hojas.

Exported from Notepad++
HSSFWorkbook libro = new HSSFWorkbook(poiArchivo );

HSSFSheet: Esta es la clase que permite manipular una hoja tomada del libro que se está manipulando, es resultante de la clase HSSFWorkbook.

Exported from Notepad++
HSSFSheet hoja = libro.getSheetAt(0);

Row: Esta clase nos permite manipular el registro de una hoja.




Cell: Esta clase nos permite manipular una celda de un registro de una hoja.
Según las especificaciones de POI, las celdas no pueden combinar formatos, es decir una celda especificada con formato numérico no puede tener en otra celda una cadena.


Agregaré un ejemplo que está compuesto por 4 fuentes:
1- ManipularLibros.java

Exported from Notepad++
import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.util.Iterator; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.poifs.filesystem.POIFSFileSystem; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Row; public class ManipularLibros { private FileInputStream fiArchivoEntrada; private POIFSFileSystem poiArchivo; private HSSFWorkbook libro; private HSSFSheet hoja; /** * Este método se encarga de buscar el archivo en la ruta indicada. * cargando un objeto POIFSFileSystem. * @param strRutaArchivoIn : ruta completa y el nombre del archivo. * @throws FileNotFoundException * @throws IOException */ public void cargarArchivo(String strRutaArchivoIn) throws FileNotFoundException, IOException { StringBuilder builder; if (strRutaArchivoIn == null) { builder = new StringBuilder("Debe colocar una ruta válida, valor recibido["); builder.append(strRutaArchivoIn).append("]"); throw new IOException(builder.toString()); } else if (strRutaArchivoIn.trim().length() &gt; 0) { fiArchivoEntrada = new FileInputStream(strRutaArchivoIn); poiArchivo = new POIFSFileSystem(fiArchivoEntrada); } else { builder = new StringBuilder("Debe colocar una ruta válida, valor recibido["); builder.append(strRutaArchivoIn).append("]"); throw new IOException(builder.toString()); } } /** * Retorna el objeto de tipo POIFSFileSystem cargado con el método * cargarArchivo(String strRutaArchivoIn) * @return POIFSFileSystem */ public POIFSFileSystem obtenerPOIFS() { return poiArchivo; } /** * <pre>* Con este método obtenemos el libro basado en un * objeto válido de tipo POIFSFileSystem. * </pre> * @return HSSFWorkbook * @throws IOException */ public HSSFWorkbook obtenerLibro() throws IOException { if (poiArchivo != null) { libro = new HSSFWorkbook(poiArchivo); } return libro; } /** * <pre>* Con este método obtenemos la hoja indicada con un indice * que inicia desde 0 según la hoja que se desee procesar * </pre> * @param intIndiceIn * @return HSSFSheet * @throws IOException */ public HSSFSheet obtenerHoja(int intIndiceIn) throws IOException { libro = obtenerLibro(); hoja = libro.getSheetAt(intIndiceIn); return hoja; } /** * * @return */ public String toString() { StringBuilder b; b = new StringBuilder(); Iterator<row> row = hoja.rowIterator(); int i = 1, h = 1; while (row.hasNext()) { Row r = row.next(); h = 1; Iterator<cell> cel = r.cellIterator(); b.append("Registro ").append(i++).append(":\n"); while (cel.hasNext()) { b.append(" Celda ").append(h++).append(": "); Cell c = cel.next(); b.append(" ").append(c.toString()); b.append("\n"); } b.append("\n"); } return b.toString(); }

2- ProcesarDatosHoja.java
Exported from Notepad++
import java.io.FileNotFoundException; import java.io.IOException; import java.util.ArrayList; import java.util.Date; import java.util.Iterator; import java.util.List; import org.apache.poi.hssf.usermodel.HSSFDateUtil; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.DateUtil; import org.apache.poi.ss.usermodel.Row; public class ProcesarDatosHoja extends ManipularLibros { /** * * @param strArchivoIn * @param intIndice * @return * @throws FileNotFoundException * @throws IOException * @throws FormatoUsuariosException */ public List cargarDatos(String strArchivoIn, int intIndice) throws FileNotFoundException, IOException, FormatoUsuariosException { Iterator<row> row = tomarRegistros(strArchivoIn, intIndice); Usuarios usuarios = null; List lista = new ArrayList(); while (row.hasNext()) { Row r = row.next(); Iterator<cell> celda = r.cellIterator(); usuarios = new Usuarios(); while (celda.hasNext()) { Cell cel = celda.next(); if (cel.getColumnIndex() == 0) { if (cel.getCellType() == 1) { usuarios.setNombre(cel.toString()); } else { establecerException(cel); } } if (cel.getColumnIndex() == 1) { if (cel.getCellType() == 1) { usuarios.setApellido(cel.toString()); } else { establecerException(cel); } } if (cel.getColumnIndex() == 2) { if (cel.getCellType() == 0) { usuarios.setEdad((int) cel.getNumericCellValue()); } else { establecerException(cel); } } if (cel.getColumnIndex() == 3) { if (cel.getCellType() == 0) { double d = HSSFDateUtil.getExcelDate(cel.getDateCellValue()); if (DateUtil.isCellDateFormatted(cel)) { Date fecha = HSSFDateUtil.getJavaDate(d); usuarios.setFecha(fecha); } else { establecerException(cel); } } else { establecerException(cel); } } } lista.add(usuarios); } return lista; } /** * * @param strArchivoIn * @param intIndice * @return * @throws FileNotFoundException * @throws IOException */ public Iterator<row> tomarRegistros(String strArchivoIn, int intIndice) throws FileNotFoundException, IOException { cargarArchivo(strArchivoIn); HSSFSheet hoja = obtenerHoja(intIndice); Iterator<row> row = hoja.rowIterator(); return row; } public void establecerException(Cell cel) throws FormatoUsuariosException { StringBuilder builder; builder = new StringBuilder(); builder.append("La columna [").append(cel.getColumnIndex()); builder.append("] tiene un valor incorrecto ["); builder.append(cel.toString()).append("]"); throw new FormatoUsuariosException(builder.toString()); } }

3- FormatoUsuariosException.java

Exported from Notepad++
public class FormatoUsuariosException extends Exception { public FormatoUsuariosException(Throwable cause) { super(cause); } public FormatoUsuariosException(String message, Throwable cause) { super(message, cause); } public FormatoUsuariosException(String message) { super(message); } public FormatoUsuariosException() { } }

4- Main.java

Exported from Notepad++
import java.io.FileNotFoundException; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; public class Main { public static void main(String arg[]) { try { ProcesarDatosHoja hoja = new ProcesarDatosHoja(); List registros = hoja.cargarDatos("/home/ariel/blog/fuentesjava/excel-POI/Libro1.xls", 0); int f, longitud=registros.size() for ( f = 0; f &lt; longitud; f++) { Usuarios u = (Usuarios) registros.get(f); System.out.println(f + 1); System.out.println(" Nombre==&gt; " + u.getNombre()); System.out.println(" Apellido==&gt; " + u.getApellido()); System.out.println(" Edad==&gt; " + u.getEdad()); if (u.getFecha() != null) { SimpleDateFormat sdf; sdf = new SimpleDateFormat("dd/MM/yyyy"); System.out.println(" Fecha==&gt; " + sdf.format(u.getFecha())); } System.out.println(); } } catch (FileNotFoundException ex) { Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); } catch (FormatoUsuariosException ex) { Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); } catch (IOException ex) { Logger.getLogger(ProcesarDatosHoja.class.getName()).log(Level.SEVERE, null, ex); } } }









Ejemplo utilizado:



Si esta entrada te fue de ayuda, no olvides hacer clic  sobre las propagandas :)

El API utilizado fue descargado del sitio de APACHE POI

Y los fuentes puedes descargarlos de :

https://github.com/arielb2/read-excel.git

El que sacrifica alabanza me honrará; Y al que ordenare su camino, Le mostraré la salvación de Dios. Salmos 50:23

20 comentarios:

RosselHerrera dijo...

Excelente ejemplo, claro, diáfano, educativo, se agradece infinitamente vuestro aporte

Ariel O. Barria dijo...

no es nada, que bueno que te sirva.
Saludos,

Anónimo dijo...

Como puedo hacer para escribir en un archivo ya creado sin que borre lo qeu tengo?

Ariel O. Barria dijo...

Revisa esta entrada http://fuentesjava.blogspot.com/2011/09/escribir-en-libro-excel-existente-poi.html

nebured dijo...

brother gracias por la publicación me ayudó mucho en un proyecto que estoy desarrollando...

Ariel O. Barria dijo...

No es nada, que bueno que te ayudó :)

Jose Marckwordt dijo...

Que tal!, disculpa no se si me puedes ayudar, solamente necesito hacer una clase java que lea archivos de excel, para un juego que estoy haciendo, que me cargue la pantalla(laberinto) desde el archivo excel. No se si me puedes ayudar, soy principiante en java y me cuesta enteder unas cosillas.. gracias y saludos.! josec_ma16@yahoo.com

Anónimo dijo...

¿Es posible leer el resultado o el valor de un checkbox por ejemplo?

Estoy en ese dilema.

Muchas gracias por esta informacion, me sirvio de mucho.

Saludos

Ariel O. Barria dijo...

Hola,disculpa la demora, bueno la verdad no me ha tocado hacerlo, pero puedes investigar por la clase FtCblsSubRecord.
Si me da tiempo trataré de realizar un pequeño ejemplo.
Saludos,

santos dijo...

MUchas gracias amigo, una duda: como hago para leer una celda cuando esta celda tiene la fecha y hora, lo que ocurre es que cuando la leo solo me sale la fecha, te agradeceria mucho tu ayuda

Ariel O. Barria dijo...

No, es nada.
El ejemplo que está acá, tiene la clase Usuario con el método getFecha(), este método te da la fecha como está en la celda.
En la clase Main tiene este código
if (u.getFecha() != null) { SimpleDateFormat sdf; sdf = new SimpleDateFormat("dd/MM/yyyy"); System.out.println(" Fecha==> " + sdf.format(u.getFecha())); }

Que le da el formato a la fecha solo de día/mes/año, por lo tanto debes buscar el formato que desees darle y trabajarlo con la clase SimpleDateFormat o simplemente trabajarlo sin formato.

Unknown dijo...

En el ejemplo ya sabes que tipo es cada celda, pero ¿se puede identificar que tipo es una celda, si esta es del tipo fecha?

Ariel O. Barria dijo...

Hola, realmente del ejemplo verifica en la columna que esta para ser mas especifico, pero puedes obviar esa linea.
Quitando la linea de la columna lo que sigue es como se verifica si la columna es fecha, dado que internamente el excel guarda las fecha como valor de tipo double por eso se verifica si el contenido que esta en la celda es de tipo cero (tipo cero es a numeros) asi :
if (cel.getCellType() == 0) {
ya esta linea nos dice que vamos por buen camino para verificar si es fecha

luego al final con el metodo isCellDateFormatted verificamos el formato:

if (DateUtil.isCellDateFormatted(cel)) {

Desde luego hay otros metodos en la documentacion que tambien pueden servir.

Disculpa las falta de tildes, no se las pude colocar.

Allan dijo...

Exelente informacion te agradeco, disculpa la consulta tengo una aplicación en zk y necesito cargar los datos de un exel a mi aplicación para luego almacenarlos en la base de datos, sera posible hacer todo esto
saludos

Ariel O. Barria dijo...

Hola vivilets, si es posible hacerlo.
Saludos.

Anónimo dijo...

La verdad que suerte que hay gente como tú, que comparte sus conocimientos. Un gran aporte, muy claro. Me ha servido muchísimo!

Excelente ejemplo!

Ariel O. Barria dijo...

que bueno, me alegro :)

Unknown dijo...

Hola como vas mira es que tengo un problemita.
uso primefaces para descargar el documento y no hay problemas pero me toca crear un libro en excel y adicionarle una hoja csv esta hoja seria la descargada desde prime faces si me puedes ayudar te lo agradesco mucho

Ariel O. Barria dijo...

Hola, bien gracias. Envíame un correo, por favor, con el detalle para buscar la manera d ayudarte.

Unknown dijo...

hola ya te envié un correo ojala puedas ayudarme muchas gracias