Revista 100% Verde

Como acceder desde Java a contenidos de celdas en Excel

Por Soloelectronicos @soloelectronico

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

Como acceder desde Java a contenidos de celdas en Excel

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.

Como acceder desde Java a contenidos de celdas en Excel

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 org.apache.poi.ss.usermodel.Row;import java.io.FileDescriptor; import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
Como acceder desde Java a contenidos de celdas en Excel

import org.apache.poi.hssf.usermodel.HSSFSheet; import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.ArrayList;import java.io.File;
import org.apache.poi.ss.usermodel.Row;import java.io.FileDescriptor; import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFSheet; 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 java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import java.io.FileOutputStream;
import java.io.IOException;

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

--

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. ( I terator<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;

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());

}


Volver a la Portada de Logo Paperblog