Упатство за Apache POI


Добредојдовте во упатството за Apache POI. Понекогаш треба да читаме податоци од Microsoft Excel Files или треба да генерираме извештаи во формат Excel, најчесто за деловни или финансиски цели. Јава не обезбедува вградена поддршка за работа со ексел-датотеки, па затоа треба да бараме API со отворен код за оваа работа. Кога почнав да ловам Java API за ексел, повеќето од луѓето ми препорачаа JExcel или Apache POI. По понатамошно истражување, открив дека Apache POI е начин да се оди поради следниве главни причини. Постојат некои други причини поврзани со напредните функции, но да не навлегуваме во толку детали.

  • Поддршка на фондацијата Апачи.
  • JExcel не поддржува xlsx формат додека POI поддржува и xls и xlsx формати.
  • Apache POI обезбедува обработка базирана на пренос, која е погодна за големи датотеки и бара помалку меморија.

Апачи POI

Apache POI обезбедува одлична поддршка за работа со документи на Microsoft Excel. Apache POI може да се справи со XLS и XLSX формати на табели. Некои важни точки за Apache POI API се:

  1. Apache POI содржи имплементација на HSSF за формат на датотека Excel 97(-2007), т.е. XLS.
  2. Имплементацијата на Apache POI XSSF треба да се користи за формат на датотека Excel 2007 OOXML (.xlsx).
  3. Apache POI HSSF и XSSF API обезбедуваат механизми за читање, пишување или менување на ексел табели.
  4. Apache POI обезбедува и SXSSF API што е продолжение на XSSF за работа со многу големи Excel листови. SXSSF API бара помалку меморија и е погоден кога работите со многу големи табели и меморијата на купот е ограничена.
  5. Постојат два модели за избор - модел на настан и модел на корисник. Моделот на настан бара помалку меморија бидејќи датотеката Excel се чита во токени и бара нивна обработка. Корисничкиот модел е повеќе објектно ориентиран и лесен за користење и ние ќе го користиме ова во нашите примери.
  6. Apache POI обезбедува одлична поддршка за дополнителни функции на Excel, како што се работа со формули, создавање стилови на ќелии со пополнување бои и граници, фонтови, заглавија и подножја, валидација на податоци, слики, хиперврски итн.

Apache POI Maven Dependencies

Ако користите Maven, додајте ги подолу зависностите од Apache POI.

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

Apache POI Пример - прочитајте ја датотеката Excel

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

Apache POI пример програма за читање на Excel датотека на списокот на земји изгледа вака подолу. 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<Country> readExcelData(String fileName) {
		List<Country> countriesList = new ArrayList<Country>();
		
		try {
			//Create the input stream from the xlsx/xls file
			FileInputStream fis = new FileInputStream(fileName);
			
			//Create Workbook instance for xlsx/xls file input stream
			Workbook workbook = null;
			if(fileName.toLowerCase().endsWith("xlsx")){
				workbook = new XSSFWorkbook(fis);
			}else if(fileName.toLowerCase().endsWith("xls")){
				workbook = new HSSFWorkbook(fis);
			}
			
			//Get the number of sheets in the xlsx file
			int numberOfSheets = workbook.getNumberOfSheets();
			
			//loop through each of the sheets
			for(int i=0; i < numberOfSheets; i++){
				
				//Get the nth sheet from the workbook
				Sheet sheet = workbook.getSheetAt(i);
				
				//every sheet has rows, iterate over them
				Iterator<Row> rowIterator = sheet.iterator();
				while (rowIterator.hasNext()) 
		        {
					String name = "";
					String shortCode = "";
					
					//Get the row object
					Row row = rowIterator.next();
					
					//Every row has columns, get the column iterator and iterate over them
					Iterator<Cell> cellIterator = row.cellIterator();
		             
		            while (cellIterator.hasNext()) 
		            {
		            	//Get the Cell object
		            	Cell cell = cellIterator.next();
		            	
		            	//check the cell type and process accordingly
		            	switch(cell.getCellType()){
		            	case Cell.CELL_TYPE_STRING:
		            		if(shortCode.equalsIgnoreCase("")){
		            			shortCode = cell.getStringCellValue().trim();
		            		}else if(name.equalsIgnoreCase("")){
		            			//2nd column
		            			name = cell.getStringCellValue().trim();
		            		}else{
		            			//random data, leave it
		            			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
			
			//close file input stream
			fis.close();
			
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		return countriesList;
	}

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

}

Програмата е многу лесна за разбирање и ги содржи следниве чекори:

  1. Креирајте пример Работна книга врз основа на типот на датотеката. XSSFWorkbook за формат xlsx и HSSFWorkbook за формат xls. Забележете дека можевме да создадеме класа на обвивка со фабричка шема за да го добиеме примерот на работната книга врз основа на името на датотеката.
  2. Користете ја работната книга getNumberOfSheets() за да го добиете бројот на листови и потоа користете ја јамката за да го анализирате секој од листовите. Добијте го примерот Лист користејќи го методот getSheetAt(int i).
  3. Добијте Ред итератор и потоа Cell итератор за да го добиете објектот Cell. Апачи POI користи шема на итератор овде.
  4. Користете прекинувач за да го прочитате типот на ќелија и соодветно да го обработите.

Сега кога работиме над Apache POI пример-програмата, таа го произведува следниот излез на конзолата.

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 Пример - напишете датотека Excel

Пишувањето ексел-датотека во POI на apache е слично на читањето, освен што овде прво ја креираме работната книга. Потоа поставете вредности на листови, редови и ќелии и користете FileOutputStream за да ги напишете во датотека. Ајде да напишеме едноставен Apache POI пример каде што ќе користиме список на земји од горенаведениот метод за зачувување во друга датотека во еден лист. 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<Country> 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<Country> 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());
		}
		
		//lets write the excel data to file now
		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<Country> list = ReadExcelFileToList.readExcelData("Sample.xlsx");
		WriteListToExcelFile.writeCountryListToFile("Countries.xls", list);
	}
}

Apache POI Пример - прочитајте ја формулата на Excel

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);
		
		//assuming xlsx file
		Workbook workbook = new XSSFWorkbook(fis);
		Sheet sheet = workbook.getSheetAt(0);
		Iterator<Row> rowIterator = sheet.iterator();
		while (rowIterator.hasNext()) 
        {
			Row row = rowIterator.next();
			Iterator<Cell> 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");
	}
}

Кога ја извршуваме горенаведената програма за пример apache poi, го добиваме следниот излез.

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

Apache POI Пример - Excel Write Formula

Понекогаш, треба да направиме некои пресметки и потоа да ги напишеме вредностите на ќелиите. Можеме да ги користиме формулите на excel за да ја направиме оваа пресметка и тоа ќе ја направи попрецизна бидејќи вредностите ќе се променат ако се променат вредностите на ќелиите што се користат во пресметките. Ајде да видиме едноставен пример за пишување ексел датотека со формули користејќи 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);
		//set formula cell
		row.createCell(3).setCellFormula("A1*B1*C1");
		
		//lets write to file
		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");
	}
}