Tutorial de Apache POI

Bienvenido al Tutorial de Apache POI. A veces necesitamos leer datos de Archivos de Microsoft Excel o necesitamos generar informes en formato Excel, principalmente para fines comerciales o financieros. Java no proporciona soporte integrado para trabajar con archivos de Excel, por lo que necesitamos buscar APIs de código abierto para el trabajo. Cuando comencé la búsqueda de APIs de Java para Excel, la mayoría de las personas recomendaron JExcel o Apache POI. Después de una investigación adicional, encontré que Apache POI es la mejor opción por las siguientes razones principales. Hay algunas otras razones relacionadas con características avanzadas, pero no profundizaremos en eso.

  • Respaldado por la fundación Apache.
  • JExcel no soporta el formato xlsx mientras que POI soporta tanto los formatos xls como xlsx.
  • Apache POI proporciona procesamiento basado en flujo, que es adecuado para archivos grandes y requiere menos memoria.

Apache POI

Apache POI proporciona un excelente soporte para trabajar con documentos de Microsoft Excel. Apache POI es capaz de manejar tanto los formatos XLS como XLSX de hojas de cálculo. Algunos puntos importantes sobre la API de Apache POI son:

  1. Apache POI contiene la implementación HSSF para el formato de archivo Excel ’97(-2007) es decir XLS.
  2. La implementación XSSF de Apache POI debe ser usada para el formato de archivo Excel 2007 OOXML (.xlsx).
  3. La API HSSF y XSSF de Apache POI proporciona mecanismos para leer, escribir o modificar hojas de cálculo de Excel.
  4. Apache POI también proporciona la API SXSSF que es una extensión de XSSF para trabajar con hojas de cálculo de Excel muy grandes. La API SXSSF requiere menos memoria y es adecuada cuando se trabaja con hojas de cálculo muy grandes y la memoria heap es limitada.
  5. Hay dos modelos para elegir: el modelo de evento y el modelo de usuario. El modelo de evento requiere menos memoria porque el archivo de Excel se lee en tokens y requiere procesarlos. El modelo de usuario es más orientado a objetos y fácil de usar, y lo usaremos en nuestros ejemplos.
  6. Apache POI proporciona un excelente soporte para características adicionales de Excel, como trabajar con fórmulas, crear estilos de celda llenando colores y bordes, fuentes, encabezados y pies de página, validaciones de datos, imágenes, hipervínculos, etc.

Dependencias de Maven de Apache POI

Si estás utilizando Maven, añade las dependencias de Apache POI que se muestran a continuación.

<dependency>
	<groupId>org.apache.poi</groupId>
	<artifactId>poi</artifactId>
	<version>3.10-FINAL</version>
</dependency>
<dependency>
	<groupId>org.apache.poi</groupId>
	<artifactId>poi-ooxml</artifactId>
	<version>3.10-FINAL</version>
</dependency>

La versión actual de Apache POI es 3.10-FINAL. Si estás utilizando una aplicación Java independiente, incluye los archivos JAR como se muestra en la imagen a continuación.

Ejemplo de Apache POI – Leer Archivo de Excel

Vamos a suponer que tenemos un archivo de Excel llamado “Sample.xlsx” con dos hojas y datos como se muestra en la siguiente imagen. Queremos leer el archivo de Excel y crear una lista de países. La Hoja1 tiene algunos datos adicionales que ignoraremos al analizarla. El código de nuestro bean Java para el país es: Country.java

package com.journaldev.excel.read;

public class Country {

	private String name;
	private String shortCode;
	
	public Country(String n, String c){
		this.name=n;
		this.shortCode=c;
	}
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getShortCode() {
		return shortCode;
	}
	public void setShortCode(String shortCode) {
		this.shortCode = shortCode;
	}
	
	@Override
	public String toString(){
		return name + "::" + shortCode;
	}
	
}

Un ejemplo de programa de Apache POI para leer un archivo de Excel a una lista de países se ve así. ReadExcelFileToList.java

package com.journaldev.excel.read;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class ReadExcelFileToList {

	public static List readExcelData(String fileName) {
		List countriesList = new ArrayList();
		
		try {
			//Crear el flujo de entrada desde el archivo xlsx/xls
			FileInputStream fis = new FileInputStream(fileName);
			
			//Crear una instancia de Workbook para el flujo de entrada del archivo xlsx/xls
			Workbook workbook = null;
			if(fileName.toLowerCase().endsWith("xlsx")){
				workbook = new XSSFWorkbook(fis);
			}else if(fileName.toLowerCase().endsWith("xls")){
				workbook = new HSSFWorkbook(fis);
			}
			
			//Obtener el número de hojas en el archivo xlsx
			int numberOfSheets = workbook.getNumberOfSheets();
			
			//recorrer cada una de las hojas
			for(int i=0; i < numberOfSheets; i++){
				
				//Obtener la hoja n del workbook
				Sheet sheet = workbook.getSheetAt(i);
				
				//cada hoja tiene filas, iterar sobre ellas
				Iterator rowIterator = sheet.iterator();
				while (rowIterator.hasNext()) 
		        {
					String name = "";
					String shortCode = "";
					
					//Obtener el objeto fila
					Row row = rowIterator.next();
					
					//Cada fila tiene columnas, obtener el iterador de columnas e iterar sobre ellas
					Iterator cellIterator = row.cellIterator();
		             
		            while (cellIterator.hasNext()) 
		            {
		            	//Obtener el objeto celda
		            	Cell cell = cellIterator.next();
		            	
		            	//verificar el tipo de celda y procesar en consecuencia
		            	switch(cell.getCellType()){
		            	case Cell.CELL_TYPE_STRING:
		            		if(shortCode.equalsIgnoreCase("")){
		            			shortCode = cell.getStringCellValue().trim();
		            		}else if(name.equalsIgnoreCase("")){
		            			//2da columna
		            			name = cell.getStringCellValue().trim();
		            		}else{
		            			//datos aleatorios, déjalos
		            			System.out.println("Random data::"+cell.getStringCellValue());
		            		}
		            		break;
		            	case Cell.CELL_TYPE_NUMERIC:
		            		System.out.println("Random data::"+cell.getNumericCellValue());
		            	}
		            } //end of cell iterator
		            Country c = new Country(name, shortCode);
		            countriesList.add(c);
		        } //end of rows iterator
				
				
			} //end of sheets for loop
			
			//cerrar el flujo de entrada del archivo
			fis.close();
			
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		return countriesList;
	}

	public static void main(String args[]){
		List list = readExcelData("Sample.xlsx");
		System.out.println("Country List\n"+list);
	}

}

El programa es muy fácil de entender y contiene los siguientes pasos:

  1. Cree una instancia de Workbook basada en el tipo de archivo. XSSFWorkbook para el formato xlsx y HSSFWorkbook para el formato xls. Tenga en cuenta que podríamos haber creado una clase envoltorio con el patrón de fábrica para obtener la instancia del libro según el nombre del archivo.
  2. Utilice workbook getNumberOfSheets() para obtener el número de hojas y luego utilice un bucle for para analizar cada una de las hojas. Obtenga la instancia de Sheet utilizando el método getSheetAt(int i).
  3. Obtenga el iterador de Row y luego el iterador de Cell para obtener el objeto Cell. Apache POI está utilizando el patrón de iterador aquí.
  4. Utilice switch-case para leer el tipo de celda y procesarlo en consecuencia.

Ahora, cuando ejecutamos el programa de ejemplo anterior de Apache POI, produce la siguiente salida en la consola.

Random data::1.0
Random data::2.0
Random data::3.0
Random data::4.0
Country List
[India::IND, Afghanistan::AFG, United States of America::USA, Anguilla::AIA, 
Denmark ::DNK, Dominican Republic ::DOM, Algeria ::DZA, Ecuador ::ECU]

Ejemplo de Apache POI – Escribir Archivo de Excel

Escribir un archivo de Excel en Apache POI es similar a la lectura, excepto que aquí primero creamos el libro de trabajo. Luego establecemos los valores de hojas, filas y celdas y usamos FileOutputStream para escribirlo en el archivo. Escribamos un ejemplo simple de Apache POI donde usaremos una lista de países del método anterior para guardar en otro archivo en una sola hoja. WriteListToExcelFile.java

package com.journaldev.excel.read;

import java.io.FileOutputStream;
import java.util.Iterator;
import java.util.List;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class WriteListToExcelFile {

	public static void writeCountryListToFile(String fileName, List countryList) throws Exception{
		Workbook workbook = null;
		
		if(fileName.endsWith("xlsx")){
			workbook = new XSSFWorkbook();
		}else if(fileName.endsWith("xls")){
			workbook = new HSSFWorkbook();
		}else{
			throw new Exception("invalid file name, should be xls or xlsx");
		}
		
		Sheet sheet = workbook.createSheet("Countries");
		
		Iterator iterator = countryList.iterator();
		
		int rowIndex = 0;
		while(iterator.hasNext()){
			Country country = iterator.next();
			Row row = sheet.createRow(rowIndex++);
			Cell cell0 = row.createCell(0);
			cell0.setCellValue(country.getName());
			Cell cell1 = row.createCell(1);
			cell1.setCellValue(country.getShortCode());
		}
		
		// vamos a escribir los datos de Excel al archivo ahora
		FileOutputStream fos = new FileOutputStream(fileName);
		workbook.write(fos);
		fos.close();
		System.out.println(fileName + " written successfully");
	}
	
	public static void main(String args[]) throws Exception{
		List list = ReadExcelFileToList.readExcelData("Sample.xlsx");
		WriteListToExcelFile.writeCountryListToFile("Countries.xls", list);
	}
}

Cuando ejecuto el programa de ejemplo de Apache POI anterior, el archivo de Excel generado se ve como la imagen a continuación.

Ejemplo de Apache POI – Leer fórmula de Excel

A veces necesitamos manejar archivos de Excel complejos con fórmulas, veamos un ejemplo simple de Apache POI para leer la fórmula de una celda con su valor. ReadExcelFormula.java

package com.journaldev.excel.read;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.Iterator;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class ReadExcelFormula {

	public static void readExcelFormula(String fileName) throws IOException{
		
		FileInputStream fis = new FileInputStream(fileName);
		
		// suponiendo archivo xlsx
		Workbook workbook = new XSSFWorkbook(fis);
		Sheet sheet = workbook.getSheetAt(0);
		Iterator rowIterator = sheet.iterator();
		while (rowIterator.hasNext()) 
        {
			Row row = rowIterator.next();
			Iterator cellIterator = row.cellIterator();
            
            while (cellIterator.hasNext()) 
            {
            	Cell cell = cellIterator.next();
            	switch(cell.getCellType()){
            	case Cell.CELL_TYPE_NUMERIC:
            		System.out.println(cell.getNumericCellValue());
            		break;
            	case Cell.CELL_TYPE_FORMULA:
            		System.out.println("Cell Formula="+cell.getCellFormula());
            		System.out.println("Cell Formula Result Type="+cell.getCachedFormulaResultType());
            		if(cell.getCachedFormulaResultType() == Cell.CELL_TYPE_NUMERIC){
            			System.out.println("Formula Value="+cell.getNumericCellValue());
            		}
            	}
            }
        }
	}
	
	public static void main(String args[]) throws IOException {
		readExcelFormula("FormulaMultiply.xlsx");
	}
}

Cuando ejecutamos el programa de ejemplo de Apache POI anterior, obtenemos la siguiente salida.

1.0
2.0
3.0
4.0
Cell Formula=A1*A2*A3*A4
Cell Formula Result Type=0
Formula Value=24.0

Ejemplo de Apache POI – Escribir Fórmulas en Excel

A veces, necesitamos hacer algunos cálculos y luego escribir los valores de las celdas. Podemos usar las fórmulas de Excel para hacer estos cálculos y eso hará que sea más preciso porque los valores cambiarán si se modifican los valores de las celdas utilizados en los cálculos. Veamos un ejemplo simple para escribir un archivo de Excel con fórmulas usando la API de Apache POI. WriteExcelWithFormula.java

package com.journaldev.excel.read;

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

import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class WriteExcelWithFormula {

	public static void writeExcelWithFormula(String fileName) throws IOException{
		Workbook workbook = new XSSFWorkbook();
		Sheet sheet = workbook.createSheet("Numbers");
		Row row = sheet.createRow(0);
		row.createCell(0).setCellValue(10);
		row.createCell(1).setCellValue(20);
		row.createCell(2).setCellValue(30);
		// configurar celda de fórmula
		row.createCell(3).setCellFormula("A1*B1*C1");
		
		// vamos a escribir en el archivo
		FileOutputStream fos = new FileOutputStream(fileName);
		workbook.write(fos);
		fos.close();
		System.out.println(fileName + " written successfully");
	}
	
	public static void main(String[] args) throws IOException {
		writeExcelWithFormula("Formulas.xlsx");
	}
}

El archivo de Excel producido con el programa de ejemplo de la API de Apache POI anterior se ve como la imagen a continuación. Eso es todo en el tutorial de Apache POI para trabajar con archivos de Excel, examine los métodos de las clases de Apache POI para aprender más características de ella. Referencias: Guía del Desarrollador de Apache POI

Source:
https://www.digitalocean.com/community/tutorials/apache-poi-tutorial