Apache POI Zelfstudie

Welkom bij de Apache POI Tutorial. Soms moeten we gegevens lezen uit Microsoft Excel-bestanden of rapporten genereren in Excel-formaat, voornamelijk voor zakelijke of financiële doeleinden. Java biedt geen ingebouwde ondersteuning voor het werken met Excel-bestanden, dus moeten we op zoek naar open source API’s voor deze taak. Toen ik op zoek ging naar Java API’s voor Excel, werd mij meestal JExcel of Apache POI aanbevolen. Na verder onderzoek ontdekte ik dat Apache POI de beste keuze is om de volgende belangrijkste redenen. Er zijn ook andere redenen met betrekking tot geavanceerde functies, maar laten we daar niet te diep op ingaan.

  • Ondersteuning van de Apache Foundation.
  • JExcel ondersteunt het xlsx-formaat niet, terwijl POI zowel xls- als xlsx-formaten ondersteunt.
  • Apache POI biedt streamgebaseerde verwerking, wat geschikt is voor grote bestanden en minder geheugen vereist.

Apache POI

Apache POI biedt uitstekende ondersteuning voor het werken met Microsoft Excel-documenten. Apache POI kan zowel XLS- als XLSX-formaten van spreadsheets verwerken. Enkele belangrijke punten over de Apache POI API zijn:

  1. Apache POI bevat de HSSF-implementatie voor het Excel ’97(-2007) bestandsformaat, oftewel XLS.
  2. Voor het Excel 2007 OOXML (.xlsx) bestandsformaat moet de Apache POI XSSF-implementatie worden gebruikt.
  3. Apache POI HSSF en XSSF API bieden mechanismen om Excel-spreadsheets te lezen, schrijven of wijzigen.
  4. Apache POI biedt ook de SXSSF API aan, een uitbreiding van XSSF om te werken met zeer grote Excel-sheets. SXSSF API vereist minder geheugen en is geschikt voor het werken met zeer grote spreadsheets wanneer de heap-geheugen beperkt is.
  5. Er zijn twee modellen om uit te kiezen – het eventmodel en het gebruikersmodel. Het eventmodel vereist minder geheugen omdat het Excel-bestand wordt gelezen in tokens en deze moeten worden verwerkt. Het gebruikersmodel is meer objectgeoriënteerd en gemakkelijk te gebruiken, en we zullen dit in onze voorbeelden gebruiken.
  6. Apache POI biedt uitstekende ondersteuning voor aanvullende Excel-functies zoals werken met formules, het maken van celstijlen door kleuren en randen te vullen, lettertypen, kopteksten en voetteksten, gegevensvalidaties, afbeeldingen, hyperlinks, enz.

Apache POI Maven-afhankelijkheden

Als u Maven gebruikt, voeg dan de onderstaande Apache POI-afhankelijkheden toe.

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

De huidige versie van Apache POI is 3.10-FINAL. Als u een op zichzelf staande Java-toepassing gebruikt, voeg dan de jars toe van onderstaande afbeelding.

Apache POI Voorbeeld – Excel-bestand lezen

Laten we zeggen dat we een Excel-bestand “Sample.xlsx” hebben met twee tabbladen en gegevens zoals de onderstaande afbeelding. We willen het Excel-bestand lezen en een lijst van landen maken. Tabblad 1 heeft aanvullende gegevens die we negeren bij het parseren ervan. Onze Java bean-code voor het land is: 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;
	}
	
}

Het Apache POI-voorbeeldprogramma om een Excel-bestand naar de lijst met landen te lezen, ziet er als volgt uit. 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 {
			// Maak de invoerstroom van het xlsx/xls-bestand
			FileInputStream fis = new FileInputStream(fileName);
			
			// Maak een Workbook-instantie voor het xlsx/xls-bestand van de invoerstroom
			Workbook workbook = null;
			if(fileName.toLowerCase().endsWith("xlsx")){
				workbook = new XSSFWorkbook(fis);
			}else if(fileName.toLowerCase().endsWith("xls")){
				workbook = new HSSFWorkbook(fis);
			}
			
			// Krijg het aantal tabbladen in het xlsx-bestand
			int numberOfSheets = workbook.getNumberOfSheets();
			
			// Loop door elk van de tabbladen
			for(int i=0; i < numberOfSheets; i++){
				
				// Krijg het nth-tabblad uit de workbook
				Sheet sheet = workbook.getSheetAt(i);
				
				// Elk tabblad heeft rijen, itereer eroverheen
				Iterator rowIterator = sheet.iterator();
				while (rowIterator.hasNext()) 
		        {
					String name = "";
					String shortCode = "";
					
					// Krijg het rijobject
					Row row = rowIterator.next();
					
					// Elke rij heeft kolommen, krijg de kolomiterator en itereer eroverheen
					Iterator cellIterator = row.cellIterator();
		             
		            while (cellIterator.hasNext()) 
		            {
		            	// Krijg het celobject
		            	Cell cell = cellIterator.next();
		            	
		            	// Controleer het celtype en verwerk dienovereenkomstig
		            	switch(cell.getCellType()){
		            	case Cell.CELL_TYPE_STRING:
		            		if(shortCode.equalsIgnoreCase("")){
		            			shortCode = cell.getStringCellValue().trim();
		            		}else if(name.equalsIgnoreCase("")){
		            			// 2e kolom
		            			name = cell.getStringCellValue().trim();
		            		}else{
		            			// Willekeurige gegevens, laat het staan
		            			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
			
			// Sluit de bestandsinvoerstroom
			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);
	}

}

Het programma is zeer eenvoudig te begrijpen en bevat de volgende stappen:

  1. Creëer een instantie van Workbook op basis van het bestandstype. Gebruik XSSFWorkbook voor het xlsx-formaat en HSSFWorkbook voor het xls-formaat. Let op dat we een wrapperklasse hadden kunnen maken met het factory-patroon om de werkboekinstantie te verkrijgen op basis van de bestandsnaam.
  2. Gebruik workbook getNumberOfSheets() om het aantal vellen te verkrijgen en gebruik vervolgens een for-lus om elk van de vellen te doorlopen. Verkrijg de Sheet-instantie met de methode getSheetAt(int i).
  3. Krijg Row-iterator en vervolgens Cell-iterator om het Cell-object te verkrijgen. Apache POI gebruikt hier het iteratorpatroon.
  4. Gebruik switch-case om het type cel te lezen en verwerk het dienovereenkomstig.

Wanneer we nu het bovenstaande Apache POI voorbeeldprogramma uitvoeren, produceert het de volgende uitvoer op de 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]

Apache POI Voorbeeld – Excel-bestand schrijven

Het schrijven van een Excel-bestand in Apache POI is vergelijkbaar met lezen, behalve dat we hier eerst het werkboek creëren. Vervolgens stellen we waarden in voor bladen, rijen en cellen, en gebruiken FileOutputStream om het naar een bestand te schrijven. Laten we een eenvoudig voorbeeld van Apache POI schrijven waarbij we de lijst van landen uit de bovenstaande methode gebruiken om op te slaan in een ander bestand op een enkel blad. 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());
		}
		
		// laten we de Excel-gegevens nu naar het bestand schrijven 
		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);
	}
}

Wanneer ik het bovenstaande Apache POI-voorbeeldprogramma uitvoer, ziet het gegenereerde Excel-bestand eruit als de onderstaande afbeelding.

Apache POI Voorbeeld – Excel-formule lezen

Soms moeten we omgaan met complexe Excel-bestanden met formules. Laten we een eenvoudig Apache POI-voorbeeld bekijken om de formule van een cel met zijn waarde te lezen. 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);
		
		// ervan uitgaande dat het een xlsx-bestand is 
		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");
	}
}

Wanneer we het bovenstaande Apache POI-voorbeeldprogramma uitvoeren, krijgen we de volgende uitvoer.

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

Voorbeeld van Apache POI – Excel Formule Schrijven

Soms moeten we wat berekeningen doen en vervolgens de celwaarden schrijven. We kunnen de Excel-formules gebruiken om deze berekening uit te voeren en dat maakt het nauwkeuriger omdat waarden zullen veranderen als de celwaarden die in de berekeningen worden gebruikt, worden gewijzigd. Laten we eens kijken naar een eenvoudig voorbeeld om een Excel-bestand met formules te schrijven met behulp van de Apache POI API. 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);
		//stel formulecel in
		row.createCell(3).setCellFormula("A1*B1*C1");
		
		//laten we naar het bestand schrijven
		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");
	}
}

Het Excel-bestand dat wordt geproduceerd met het bovenstaande voorbeeldprogramma van Apache POI API ziet eruit als de onderstaande afbeelding. Dat is alles over de Apache POI-zelfstudie voor het werken met Excel-bestanden, kijk in de methoden van Apache POI-klassen om meer functies ervan te leren. Referenties: Apache POI Ontwikkelaarsgids

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