Tutorial do Apache POI

Bem-vindo ao Tutorial do Apache POI. Às vezes, precisamos ler dados de Arquivos do Microsoft Excel ou gerar relatórios em formato Excel, principalmente para fins comerciais ou financeiros. Java não oferece suporte embutido para trabalhar com arquivos Excel, então precisamos procurar APIs de código aberto para a tarefa. Quando comecei a busca por APIs Java para o Excel, a maioria das pessoas recomendava JExcel ou Apache POI. Após uma pesquisa mais aprofundada, descobri que o Apache POI é a escolha certa, pelos seguintes motivos principais.

  • Apoio da Apache Foundation.
  • JExcel não suporta o formato xlsx, enquanto o POI suporta tanto os formatos xls quanto xlsx.
  • O Apache POI oferece processamento baseado em stream, adequado para arquivos grandes e que requerem menos memória.

Apache POI

Apache POI fornece excelente suporte para trabalhar com documentos do Microsoft Excel. O Apache POI é capaz de lidar com os formatos de planilhas XLS e XLSX. Alguns pontos importantes sobre a API do Apache POI são:

  1. O Apache POI contém a implementação HSSF para o formato de arquivo Excel ’97(-2007), ou seja, XLS.
  2. A implementação XSSF do Apache POI deve ser usada para o formato de arquivo Excel 2007 OOXML (.xlsx).
  3. A API Apache POI HSSF e XSSF oferece mecanismos para ler, escrever ou modificar planilhas do Excel.
  4. O Apache POI também fornece a API SXSSF, que é uma extensão do XSSF para trabalhar com planilhas do Excel muito grandes. A API SXSSF requer menos memória e é adequada quando se trabalha com planilhas muito grandes e a memória heap é limitada.
  5. Há dois modelos para escolher – o modelo de evento e o modelo de usuário. O modelo de evento requer menos memória porque o arquivo do Excel é lido em tokens e requer processamento deles. O modelo de usuário é mais orientado a objetos e fácil de usar, e é isso que usaremos em nossos exemplos.
  6. O Apache POI oferece excelente suporte para recursos adicionais do Excel, como trabalhar com fórmulas, criar estilos de célula preenchendo cores e bordas, fontes, cabeçalhos e rodapés, validações de dados, imagens, hiperlinks etc.

Dependências do Apache POI Maven

Se você estiver usando o Maven, adicione as dependências do Apache POI abaixo.

<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>

A versão atual do Apache POI é 3.10-FINAL. Se você estiver usando um aplicativo Java independente, inclua os jars da imagem abaixo.

Exemplo do Apache POI – Ler Arquivo do Excel

Vamos supor que temos um arquivo Excel “Sample.xlsx” com duas planilhas e dados como na imagem abaixo. Queremos ler o arquivo Excel e criar a lista de países. A Sheet1 possui alguns dados adicionais que vamos ignorar ao analisá-la. Nosso código Java bean para País é: 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;
	}
	
}

Um exemplo de programa usando Apache POI para ler o arquivo Excel para a lista de países é semelhante ao seguinte. 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 {
			//Crie o fluxo de entrada a partir do arquivo xlsx/xls
			FileInputStream fis = new FileInputStream(fileName);
			
			//Crie uma instância de Workbook para o fluxo de entrada do arquivo xlsx/xls
			Workbook workbook = null;
			if(fileName.toLowerCase().endsWith("xlsx")){
				workbook = new XSSFWorkbook(fis);
			}else if(fileName.toLowerCase().endsWith("xls")){
				workbook = new HSSFWorkbook(fis);
			}
			
			//Obtenha o número de planilhas no arquivo xlsx
			int numberOfSheets = workbook.getNumberOfSheets();
			
			//iterar através de cada planilha
			for(int i=0; i < numberOfSheets; i++){
				
				//Obtenha a enésima planilha do Workbook
				Sheet sheet = workbook.getSheetAt(i);
				
				//cada planilha tem linhas, itere sobre elas
				Iterator rowIterator = sheet.iterator();
				while (rowIterator.hasNext()) 
		        {
					String name = "";
					String shortCode = "";
					
					//Obtenha o objeto de linha
					Row row = rowIterator.next();
					
					//Cada linha tem colunas, obtenha o iterador de colunas e itere sobre elas
					Iterator cellIterator = row.cellIterator();
		             
		            while (cellIterator.hasNext()) 
		            {
		            	//Obtenha o objeto de Célula
		            	Cell cell = cellIterator.next();
		            	
		            	//verifique o tipo de célula e processe conforme necessário
		            	switch(cell.getCellType()){
		            	case Cell.CELL_TYPE_STRING:
		            		if(shortCode.equalsIgnoreCase("")){
		            			shortCode = cell.getStringCellValue().trim();
		            		}else if(name.equalsIgnoreCase("")){
		            			//2ª coluna
		            			name = cell.getStringCellValue().trim();
		            		}else{
		            			//dados aleatórios, deixe como está
		            			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
			
			//feche o fluxo de entrada do arquivo
			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);
	}

}

O programa é fácil de entender e contém os seguintes passos:

  1. Crie uma instância do Workbook com base no tipo de arquivo. Use XSSFWorkbook para o formato xlsx e HSSFWorkbook para o formato xls. Observe que poderíamos ter criado uma classe de wrapper com o padrão de factory para obter a instância do workbook com base no nome do arquivo.
  2. Use workbook getNumberOfSheets() para obter o número de planilhas e então use um loop for para analisar cada uma das planilhas. Obtenha a instância do Sheet usando o método getSheetAt(int i).
  3. Obtenha o iterador de Row e então o iterador de Cell para obter o objeto Cell. O Apache POI está usando o padrão de iterador aqui.
  4. Use switch-case para ler o tipo de célula e processá-lo de acordo.

Agora, quando executamos o programa de exemplo do Apache POI acima, ele produz a seguinte saída no console.

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]

Exemplo do Apache POI – Escrever Arquivo do Excel

Escrever um arquivo do Excel no Apache POI é semelhante à leitura, exceto que aqui primeiro criamos o livro de trabalho. Em seguida, definimos os valores das planilhas, linhas e células e usamos FileOutputStream para escrevê-lo no arquivo. Vamos escrever um exemplo simples do Apache POI onde usaremos uma lista de países do método acima para salvar em outro arquivo em uma única planilha. 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 escrever os dados do Excel no arquivo agora 
		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);
	}
}

Quando executo o programa de exemplo do Apache POI acima, o arquivo do Excel gerado parece com a imagem abaixo.

Exemplo do Apache POI – Ler Fórmula do Excel

Às vezes, precisamos lidar com arquivos do Excel complexos com fórmulas, vamos ver um exemplo simples do Apache POI para ler a fórmula de uma célula com seu 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);
		
		// supondo arquivo 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");
	}
}

Quando executamos o programa de exemplo do Apache POI acima, obtemos a seguinte saída.

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

Exemplo do Apache POI – Escrever Fórmula no Excel

Às vezes, precisamos fazer alguns cálculos e depois escrever os valores das células. Podemos usar as fórmulas do Excel para fazer esses cálculos e isso tornará mais preciso, pois os valores mudarão se os valores das células usados nos cálculos forem alterados. Vamos ver um exemplo simples de escrever um arquivo do Excel com fórmulas usando a API do 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);
		// definir célula de fórmula
		row.createCell(3).setCellFormula("A1*B1*C1");
		
		// vamos escrever no arquivo
		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");
	}
}

O arquivo do Excel produzido com o exemplo do programa acima usando a API do Apache POI se parece com a imagem abaixo. Isso é tudo no tutorial do Apache POI para trabalhar com arquivos do Excel, veja as classes e métodos do Apache POI para aprender mais recursos dele. Referências: Guia do Desenvolvedor Apache POI

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