Como acceder desde Java a contenidos de celdas en Excel


Lo cierto es puede que  en  ocasiones necesitemos procesar ficheros excel u otro tipo de hojas de cálculo de   forma automatizada, por ejemplo  para extraer  información  de determinadas celdas, manipular estas , generar ficheros de metadatos que  sigan ciertas reglas , etc

En este caso nos vamos a centrar en los documentos OLE 2 de Microsoft, que manipularemos  usando la libreria  Apache POI – the Java API for Microsoft Documents, que nos proporciona acceso a los diferentes tipos de ficheros de Microsoft que utilizan esta estructura como:  Excel Word o  Powerpoint, también hay otros proyectos dentro de esta API para Visio y Publisher por ejemplo

Como se  puede   imaginar de todos estos el más desarrollado es Excel Workbooks y es precisamente el tipo de fichero elegido para este ejemplo.

Antes de empezar  usaremos  la librería POI-HSSF and POI-XSSF – Java API To Access Microsoft, donde HSSF es el proyecto POI de implementación total en Java para ficheros excel.Esta libreria usa cuatro componentes fundamentalmente:

  • HSSFWorkbook: Representación de alto nivel de un libro (Workbook) que será nuestra documento excel. Es el primer objeto que construiremos si vamos a leer o escribir una hoja excel.
  • HSSFSheet: representación de alto nivel de una hoja excel, podemos elegir la hoja de la excel usando el HSSFWorkBook.
  • HSSFRow: representación de celda de una fila de la hoja excel, solo las filas que tienen filas se pueden añadir a la hoja.
  • HSSFCell: representación de una celda en una fila de la un hoja de la excel, la utilizaremos para manejar el contenido de la celda.

Bien, sin más  dilaciones,  empezamos  a  ver como podemos procesar ficheros de Tipo Excel  

Paso 1: Descargar librería Apache Poi Java API

Antes de nada, tenemos que descargar la librería API Apache Poi Java, para añadirla a nuestro proyecto, voy a explicar cómo hacerlo en el IDE que estoy usando para este ejemplo: Netbeans, en otros IDES será similar la forma de integración de las librerías.

En nuestro proyecto buscamos la carpeta Libraries nos colocamos encima y seleccionamos Add Library, no tiene mucho que explicar así que te lo mostraré en imágenes:

La librería es  https://www.apache.org/dyn/closer.lua/poi/release/bin/poi-bin-4.1.0-20190412.zip

 

 

 

 

Paso 2-Registro de la librería en nuestro proyecto

Una vez  descargada y descomprimida, nos iremos a Properties del proyecto , después a   Java Build Path y   pincharemos en la pestaña  Libraries

Aquí  pulsaremos Add External JARs  seleccionando “poi-4.01.jar” desde al ruta donde la hayamos dejado esta librería.

 

 

Paso 3-Incluir las librerías

Ahora toca pasarse  a  programar, pero antes , no debemos olvidar importar las  cuatro librerias  que comentaabamos al principio

  • HSSFRow: representación de celda de una fila de la hoja excel, solo las filas que tienen filas se pueden añadir a la hoja.
  • HSSFWorkbook: Representación de alto nivel de un libro (Workbook) que será nuestra documento excel. Es el primer objeto que construiremos si vamos a leer o escribir una hoja excel.
  • HSSFSheet: representación de alto nivel de una hoja excel, podemos elegir la hoja de la excel usando el HSSFWorkBook.
  • HSSFCell: representación de una celda en una fila de la un hoja de la excel, la utilizaremos para manejar el contenido de la celda

Visto asi , adjuntando otras librerias utiles , la cabecera de importaciones de librerias quedaria  asi: 

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;


import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.ArrayList;
import java.util.List;

import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFSheet;

import java.io.FileDescriptor;

import org.apache.poi.ss.usermodel.Cell;

 

Paso 4-Convertir al menos a  formato excel97  o superior

Antes de proseguir , en caso de tener ficheros excel en formato muy antiguos( por ejemplo Excel 95) .  deberemos  convertir estos   al menos al  formato excel 97,  para ello, en caso de que el formato sea de excel 95 deberemos abrir dicho fichero e irnos  a la opción   Guardar como seleccionamos   “libro de Excel 97-2003(*.xls)”

 

 

 

5-Pasemos al código

Una vez salvada  la hoja en formato excel 97 o superior  veamos un simple ejemplo de cómo capturar  los valores contenidos en las celdas

 

                      ——

      FileInputStream file = new FileInputStream(new File("C:\\prueba.xls"));

    // Crear el objeto que tendrá el libro de Excel

      XSSFWorkbook workbook = new XSSFWorkbook(file);

      /** Obtenemos la primera pestaña a la que se quiera procesar indicando el indice.

     * Una vez obtenida la hoja excel con las filas que se quieren leer obtenemos el iterator

      * que nos permite recorrer cada una de las filas que contiene.

      */



      XSSFSheet sheet = workbook.getSheetAt(0);

      Iterator<Row> rowIterator = sheet.iterator();

      Row row;

    // Recorremos todas las filas para mostrar el contenido de cada celda

      while (rowIterator.hasNext()){

          row = rowIterator.next();

         // Obtenemos el iterator que permite recorres todas las celdas de una fila

          Iterator<Cell> cellIterator = row.cellIterator();

          Cell celda;

          while (cellIterator.hasNext()){

            celda = cellIterator.next();

            // Dependiendo del formato de la celda el valor se debe mostrar como String, Fecha, boolean, entero...

            switch(celda.getCellType()) {

            case Cell.CELL_TYPE_NUMERIC:

                if( DateUtil.isCellDateFormatted(celda) ){

                   System.out.println(celda.getDateCellValue());

                }else{

                   System.out.println(celda.getNumericCellValue());

                }

                break;

            case Cell.CELL_TYPE_STRING:

                System.out.println(celda.getStringCellValue());

                break;

            case Cell.CELL_TYPE_BOOLEAN:

                System.out.println(celda.getBooleanCellValue());

                break;

            }

          }

      }


   // cerramos el libro excel

      workbook.close();


Como vemos en el ejemplo anterior , crearemos el objeto que tendrá el libro de Excel(FileInputStream file = new FileInputStream(new File(“xxx..) y obtenemos la primera pestaña a la que se quiera procesar indicando el indice 0 (  XSSFSheet sheet = workbook.getSheetAt(0);

Una vez obtenida la hoja excel con las filas que se quieren leer ,obtenemos el iterator que nos permite recorrer cada una de las filas que contiene. (  Iterator<Row> rowIterator = sheet.iterator()😉

Y  ya bastaría ir recorriendo todas las filas con un bucle  while ( while (cellIterator.hasNext()))  ,  lo cual nos  va  a permitir  procesar  el contenido de cada celda

Obtenemos el iterator(  row = rowIterator.next(); ) que permite recorrer todas las celdas de una fila y salvar el objeto en la variable row

Ahora ya dependiendo del formato de la celda de la variable   row  ,  el valor se debe mostrar como String, Fecha, boolean, entero

El programa tras recorrer todas las filas acaba cerrando el libro excel

 

 

Como ejemplo más elaborado , vamos a ver como procesar  una hoja excel s donde cada fila representa los diferentes metadatos , por lo que con el programa  iremos capturando dicha información diferente  celda a celda para cada fila , para ir componiendo una fila de texto con los diferentes metadatos  capturados   y  que separaremos por el carácter almohadilla ( #) .

Finalmente veamos  pues el ejemplo cuya finalidad es extraer de un excel un fichero csv de un modo automático via el siguiente programa en java;

 

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;


import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.ArrayList;
import java.util.List;

import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFSheet;

import java.io.FileDescriptor;

import org.apache.poi.ss.usermodel.Cell;

 

 

public class Main {

//private static String nombre;

public static void main(final String[] args) throws IOException {

String lineaslog=””;
String lineaslog2=”\r\n”;

//fichero de log
File filelog = new File(“d://ficherolog.txt”);
FileOutputStream fos2log = new FileOutputStream(filelog);

 


//añadimos 4 ceros la contador y generamos nuevo nombre
nfichero= “salida.txt”;
System.out.println(“Nuevo nombre fichero salida:” + nfichero);
lineaslog=”Nuevo nombre fichero salida:” + nfichero;
fos2log.write(lineaslog.getBytes());
fos2log.write(lineaslog2.getBytes());
//Procesar el excel a txt


//Creamos nuevo fichero de metadatos del tipo texto
File file = new File(nfichero);
FileOutputStream fos1 = new FileOutputStream(file);
FileDescriptor fd = fos1.getFD();


FileOutputStream fos2 = new FileOutputStream(fd);

String rutaArchivo=files22[ i ] ; //directorio3;
System.out.println (“Leyendo archivo :” + rutaArchivo );
lineaslog=”Leyendo archivo :” + rutaArchivo ;
fos2log.write(lineaslog.getBytes());
fos2log.write(lineaslog2.getBytes());

System.out.println (“NOMBRE HOJA :”+ hoja);
lineaslog=”NOMBRE HOJA :”+ hoja;
fos2log.write(lineaslog.getBytes());
fos2log.write(lineaslog2.getBytes());



try (FileInputStream fileexcel = new FileInputStream(new File(rutaArchivo)))

{
System.out.println(“Leer archivo Excel “);
lineaslog=”Leer archivo Excel “;
fos2log.write(lineaslog.getBytes());
fos2log.write(lineaslog2.getBytes());

// leer archivo excel97
HSSFWorkbook worbook = new HSSFWorkbook(fileexcel);

System.out.println(“Leyendo la hoja del fichero excel”);
lineaslog=”Leyendo la hoja del fichero excel”;
fos2log.write(lineaslog.getBytes());
fos2log.write(lineaslog2.getBytes());

//obtener la hoja que se va leer
HSSFSheet sheet = worbook.getSheetAt(0);

System.out.println(“Obtener las hojas del fichero excel”);
lineaslog=”Obtener las hojas del fichero excel”;
fos2log.write(lineaslog.getBytes());
fos2log.write(lineaslog2.getBytes());
//obtener todas las filas de la hoja excel
Iterator<Row> rowIterator = sheet.iterator();

Row row;

System.out.println(“La ruta del fichero excel es rutaarchivo :”+rutaArchivo);
lineaslog=”La ruta del fichero excel es rutaarchiv:”+rutaArchivo;
fos2log.write(lineaslog.getBytes());
fos2log.write(lineaslog2.getBytes());


Integer nm3=0;

while (rowIterator.hasNext()) // se recorre cada fila hasta el final

{

//System.out.println(“linea1”);

row = rowIterator.next();
nm3=nm3+1;

//se obtiene las celdas por fila
Iterator<Cell> cellIterator = row.cellIterator();
Cell cell;

//se recorre cada celda
int indice=0;
while (cellIterator.hasNext()) {

// se obtiene la celda en específico y se la imprime
cell = cellIterator.next();

//System.out.print(“(i”+i +”)=”+ cell.getStringCellValue()+” | “);

switch (indice) //tomaremos diferentes columnas del fichero excel
{

case 0:
{
nombre_fichero=cell.getStringCellValue();
}
case 1:
{
boletin=cell.getStringCellValue();
}
case 2:
{
telefono=cell.getStringCellValue();
}

case 3: // cif o nif
{
ncif=cell.getStringCellValue();
}

case 4: //valor del cif
{
cif=cell.getStringCellValue();
}

case 8:
{
fecha=cell.getStringCellValue();
}
case 9:
{
hora=cell.getStringCellValue();
}
}



linea= linea + cell.getStringCellValue() +”#”;

indice=indice+1;

}


lineas=boletin +”#” +telefono +”#”+ncif+”#” + cif+”#”+tipo +”#” +fecha+” “+hora+”#” +”#” +”#” +”#”+ nombre_fichero+ “#”+ nombre_fichero+”#”;


fos2.write(lineas.getBytes());

//System.out.println();

lineas=”\r\n”;

fos2.write(lineas.getBytes());

}

worbook.close();


linearesumen= directorio+”;”+ hoja +”;”+directorio22+ “P5_”+ fechaok+String.format(“%05d”, contador) +”;”+nm3;

fos3.write(linearesumen.getBytes());

linearesumen=”\r\n”;

fos3.write(linearesumen.getBytes());

nm3=0;

}
catch (Exception e)

{

e.getMessage();
System.out.println(e.getMessage());
lineaslog=e.getMessage();
fos2log.write(lineaslog.getBytes());
fos2log.write(lineaslog2.getBytes());

}

fos1.close();
fos2.close();

System.out.println(“Fin de generacion del txt de metadatos desde excel a txt”);
lineaslog=”Fin de generacion del txt de metadatos desde excel a txt”;
fos2log.write(lineaslog.getBytes());
fos2log.write(lineaslog2.getBytes());

}

Anuncios