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