Apache POI 教程

欢迎学习ApachePOI教程。有时我们需要从Microsoft Excel文件 读取数据,或者需要生成Excel格式的报告,主要用于商业或财务目的。Java不提供对处理EXCEL文件的内置支持,因此我们需要为这项工作寻找开源API。当我开始寻找用于EXCEL的Java API时,大多数人推荐JExcel或ApachePOI。在进一步研究后,我发现ApachePOI是可行的,主要原因有以下几个。还有其他一些与高级功能相关的原因,但我们不详细讨论。

  • 阿帕奇基金会的支持。
  • JExcel不支持xlsx格式,而POI同时支持xls和xlsx格式。
  • ApachePOI提供基于流的处理,适用于大文件,需要更少的内存。

阿帕奇POI

Apache POI 为处理Microsoft Excel文档提供了出色的支持。Apache POI能够处理XLS和XLSX格式的电子表格。关于Apache POI API的一些要点是:

1.ApachePOI包含针对Excel‘97(-2007)文件格式的HSSF实现,即XLS。 2.Excel 2007 OOXML(.xlsx)文件格式应使用ApachePOI XSSF实现。 3.ApachePOI HSSF和XSSF API提供了读、写或修改Excel电子表格的机制。 4.ApachePOI还提供了SXSSF API,它是XSSF的扩展,用于处理非常大的EXCEL表格。SXSSF API需要较少的内存,适用于处理非常大的电子表格和堆内存有限的情况。 5.有两种模型可供选择-事件模型和用户模型。事件模型需要较少的内存,因为EXCEL文件是读入内标识并需要处理它们的。用户模型更面向对象,更易于使用,我们将在示例中使用这一点。 6.ApachePOI提供了对其他Excel功能的出色支持,如使用公式、通过填充颜色和边框创建单元格样式、字体、页眉和页脚、数据验证、图像、超链接等。

Apache POI Maven依赖关系

如果您使用的是Maven,请在下面添加ApachePOI依赖项。

 1<dependency>
 2    <groupId>org.apache.poi</groupId>
 3    <artifactId>poi</artifactId>
 4    <version>3.10-FINAL</version>
 5</dependency>
 6<dependency>
 7    <groupId>org.apache.poi</groupId>
 8    <artifactId>poi-ooxml</artifactId>
 9    <version>3.10-FINAL</version>
10</dependency>

Apache POI的当前版本是3.10-FINAL。如果你有独立的java应用程序,包括下面图片中的jar。Apache POI Jars,Apache POI,Apache POI example,apache poi tutorial

Apache POI示例-阅读Excel文件

假设我们有一个包含两张工作表的Excel文件)](https://journaldev.nyc3.digitaloceanspaces.com/2014/03/Java-Read-Excel-File-1.png)[![Java Read Excel文件,ApachePOI,ApachePOI Example,ApachePOI tutorial](https://cdn.jsdelivr.net/gh/andsky/tutorials-images/spaces/2014/03/Java-Read-Excel-File-2-450x366.png)](https://journaldev.nyc3.digitaloceanspaces.com/2014/03/Java-Read-Excel-File-2.png)我国Java Bean代码为:Country.java

 1package com.journaldev.excel.read;
 2
 3public class Country {
 4
 5    private String name;
 6    private String shortCode;
 7    
 8    public Country(String n, String c){
 9    	this.name=n;
10    	this.shortCode=c;
11    }
12    
13    public String getName() {
14    	return name;
15    }
16    public void setName(String name) {
17    	this.name = name;
18    }
19    public String getShortCode() {
20    	return shortCode;
21    }
22    public void setShortCode(String shortCode) {
23    	this.shortCode = shortCode;
24    }
25    
26    @Override
27    public String toString(){
28    	return name + "::" + shortCode;
29    }
30    
31}

APACHE POI示例程序将EXCEL文件读取到国家列表,如下所示。ReadExcelFileToList.java

 1package com.journaldev.excel.read;
 2
 3import java.io.FileInputStream;
 4import java.io.IOException;
 5import java.util.ArrayList;
 6import java.util.Iterator;
 7import java.util.List;
 8
 9import org.apache.poi.hssf.usermodel.HSSFWorkbook;
10import org.apache.poi.ss.usermodel.Cell;
11import org.apache.poi.ss.usermodel.Row;
12import org.apache.poi.ss.usermodel.Sheet;
13import org.apache.poi.ss.usermodel.Workbook;
14import org.apache.poi.xssf.usermodel.XSSFWorkbook;
15
16public class ReadExcelFileToList {
17
18    public static List<Country> readExcelData(String fileName) {
19    	List<Country> countriesList = new ArrayList<Country>();
20    	
21    	try {
22    		//Create the input stream from the xlsx/xls file
23    		FileInputStream fis = new FileInputStream(fileName);
24    		
25    		//Create Workbook instance for xlsx/xls file input stream
26    		Workbook workbook = null;
27    		if(fileName.toLowerCase().endsWith("xlsx")){
28    			workbook = new XSSFWorkbook(fis);
29    		}else if(fileName.toLowerCase().endsWith("xls")){
30    			workbook = new HSSFWorkbook(fis);
31    		}
32    		
33    		//Get the number of sheets in the xlsx file
34    		int numberOfSheets = workbook.getNumberOfSheets();
35    		
36    		//loop through each of the sheets
37    		for(int i=0; i < numberOfSheets; i++){
38    			
39    			//Get the nth sheet from the workbook
40    			Sheet sheet = workbook.getSheetAt(i);
41    			
42    			//every sheet has rows, iterate over them
43    			Iterator<Row> rowIterator = sheet.iterator();
44    			while (rowIterator.hasNext()) 
45    	        {
46    				String name = "";
47    				String shortCode = "";
48    				
49    				//Get the row object
50    				Row row = rowIterator.next();
51    				
52    				//Every row has columns, get the column iterator and iterate over them
53    				Iterator<Cell> cellIterator = row.cellIterator();
54    	             
55    	            while (cellIterator.hasNext()) 
56    	            {
57    	            	//Get the Cell object
58    	            	Cell cell = cellIterator.next();
59    	            	
60    	            	//check the cell type and process accordingly
61    	            	switch(cell.getCellType()){
62    	            	case Cell.CELL_TYPE_STRING:
63    	            		if(shortCode.equalsIgnoreCase("")){
64    	            			shortCode = cell.getStringCellValue().trim();
65    	            		}else if(name.equalsIgnoreCase("")){
66    	            			//2nd column
67    	            			name = cell.getStringCellValue().trim();
68    	            		}else{
69    	            			//random data, leave it
70    	            			System.out.println("Random data::"+cell.getStringCellValue());
71    	            		}
72    	            		break;
73    	            	case Cell.CELL_TYPE_NUMERIC:
74    	            		System.out.println("Random data::"+cell.getNumericCellValue());
75    	            	}
76    	            } //end of cell iterator
77    	            Country c = new Country(name, shortCode);
78    	            countriesList.add(c);
79    	        } //end of rows iterator
80    			
81    			
82    		} //end of sheets for loop
83    		
84    		//close file input stream
85    		fis.close();
86    		
87    	} catch (IOException e) {
88    		e.printStackTrace();
89    	}
90    	
91    	return countriesList;
92    }
93
94    public static void main(String args[]){
95    	List<Country> list = readExcelData("Sample.xlsx");
96    	System.out.println("Country List\n"+list);
97    }
98
99}

该程序非常容易理解,并包含以下步骤:

1.根据文件类型创建Workbook实例。Xlsx格式为XSSFWorkbook,xls格式为HSSFWorkbook。请注意,我们可以使用Factory pattern创建一个包装类,以根据文件名获取工作簿实例。 2.使用workbook getNumberOfSheets()获取表的数量,然后使用for循环解析每个表。使用getSheetAt(Int I)方法获取Sheet实例。 3.获取Row迭代器,然后获取Cell迭代器,得到Cell对象。ApachePOI在这里使用迭代器pattern。 4.使用switch-case读取单元格的类型并进行相应的处理。

现在,当我们在上面运行ApachePOI示例程序时,它在控制台上生成以下输出。

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

Apache POI示例-编写Excel文件

在ApachePOI中写入EXCEL文件类似于阅读,不同之处在于这里我们首先创建工作簿。然后设置工作表、行和单元格值,并使用FileOutputStream将其写入文件。让我们编写一个简单的ApachePOI示例,其中我们将使用上述方法中的国家/地区列表保存到单个工作表中的另一个文件中。WriteListToExcelFile.java

 1package com.journaldev.excel.read;
 2
 3import java.io.FileOutputStream;
 4import java.util.Iterator;
 5import java.util.List;
 6
 7import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 8import org.apache.poi.ss.usermodel.Cell;
 9import org.apache.poi.ss.usermodel.Row;
10import org.apache.poi.ss.usermodel.Sheet;
11import org.apache.poi.ss.usermodel.Workbook;
12import org.apache.poi.xssf.usermodel.XSSFWorkbook;
13
14public class WriteListToExcelFile {
15
16    public static void writeCountryListToFile(String fileName, List<Country> countryList) throws Exception{
17    	Workbook workbook = null;
18    	
19    	if(fileName.endsWith("xlsx")){
20    		workbook = new XSSFWorkbook();
21    	}else if(fileName.endsWith("xls")){
22    		workbook = new HSSFWorkbook();
23    	}else{
24    		throw new Exception("invalid file name, should be xls or xlsx");
25    	}
26    	
27    	Sheet sheet = workbook.createSheet("Countries");
28    	
29    	Iterator<Country> iterator = countryList.iterator();
30    	
31    	int rowIndex = 0;
32    	while(iterator.hasNext()){
33    		Country country = iterator.next();
34    		Row row = sheet.createRow(rowIndex++);
35    		Cell cell0 = row.createCell(0);
36    		cell0.setCellValue(country.getName());
37    		Cell cell1 = row.createCell(1);
38    		cell1.setCellValue(country.getShortCode());
39    	}
40    	
41    	//lets write the excel data to file now
42    	FileOutputStream fos = new FileOutputStream(fileName);
43    	workbook.write(fos);
44    	fos.close();
45    	System.out.println(fileName + " written successfully");
46    }
47    
48    public static void main(String args[]) throws Exception{
49    	List<Country> list = ReadExcelFileToList.readExcelData("Sample.xlsx");
50    	WriteListToExcelFile.writeCountryListToFile("Countries.xls", list);
51    }
52}

当我执行上面的ApachePOI示例程序时,生成的EXCEL文件如下图所示。JAVA WRITE EXCEL文件,ApachePOI,ApachePOI示例,ApachePOI tutorial

Apache POI示例-阅读Excel公式

有时我们需要处理复杂的excel文件与公式,让我们看一个简单的apache POI的例子来读取一个单元格的公式与它的值。Java Excel读取公式,Apache POI,Apache POI示例,Apache POI教程ReadExcelFormula.java

 1package com.journaldev.excel.read;
 2
 3import java.io.FileInputStream;
 4import java.io.IOException;
 5import java.util.Iterator;
 6
 7import org.apache.poi.ss.usermodel.Cell;
 8import org.apache.poi.ss.usermodel.Row;
 9import org.apache.poi.ss.usermodel.Sheet;
10import org.apache.poi.ss.usermodel.Workbook;
11import org.apache.poi.xssf.usermodel.XSSFWorkbook;
12
13public class ReadExcelFormula {
14
15    public static void readExcelFormula(String fileName) throws IOException{
16    	
17    	FileInputStream fis = new FileInputStream(fileName);
18    	
19    	//assuming xlsx file
20    	Workbook workbook = new XSSFWorkbook(fis);
21    	Sheet sheet = workbook.getSheetAt(0);
22    	Iterator<Row> rowIterator = sheet.iterator();
23    	while (rowIterator.hasNext()) 
24        {
25    		Row row = rowIterator.next();
26    		Iterator<Cell> cellIterator = row.cellIterator();
27
28            while (cellIterator.hasNext()) 
29            {
30            	Cell cell = cellIterator.next();
31            	switch(cell.getCellType()){
32            	case Cell.CELL_TYPE_NUMERIC:
33            		System.out.println(cell.getNumericCellValue());
34            		break;
35            	case Cell.CELL_TYPE_FORMULA:
36            		System.out.println("Cell Formula="+cell.getCellFormula());
37            		System.out.println("Cell Formula Result Type="+cell.getCachedFormulaResultType());
38            		if(cell.getCachedFormulaResultType() == Cell.CELL_TYPE_NUMERIC){
39            			System.out.println("Formula Value="+cell.getNumericCellValue());
40            		}
41            	}
42            }
43        }
44    }
45    
46    public static void main(String args[]) throws IOException {
47    	readExcelFormula("FormulaMultiply.xlsx");
48    }
49}

当我们执行上面的ApachePOI示例程序时,我们得到以下输出。

11.0
22.0
33.0
44.0
5Cell Formula=A1*A2*A3*A4
6Cell Formula Result Type=0
7Formula Value=24.0

APACHE POI示例-Excel编写公式

有时,我们需要进行一些计算,然后写入单元格值。我们可以使用EXCEL公式来进行此计算,这将使计算更加准确,因为如果计算中使用的单元格值发生变化,值也会发生变化。让我们来看一个使用ApachePoi API编写带有公式Excel文件的简单示例。WriteExcelWithFormula.java

 1package com.journaldev.excel.read;
 2
 3import java.io.FileOutputStream;
 4import java.io.IOException;
 5
 6import org.apache.poi.ss.usermodel.Row;
 7import org.apache.poi.ss.usermodel.Sheet;
 8import org.apache.poi.ss.usermodel.Workbook;
 9import org.apache.poi.xssf.usermodel.XSSFWorkbook;
10
11public class WriteExcelWithFormula {
12
13    public static void writeExcelWithFormula(String fileName) throws IOException{
14    	Workbook workbook = new XSSFWorkbook();
15    	Sheet sheet = workbook.createSheet("Numbers");
16    	Row row = sheet.createRow(0);
17    	row.createCell(0).setCellValue(10);
18    	row.createCell(1).setCellValue(20);
19    	row.createCell(2).setCellValue(30);
20    	//set formula cell
21    	row.createCell(3).setCellFormula("A1*B1*C1");
22    	
23    	//lets write to file
24    	FileOutputStream fos = new FileOutputStream(fileName);
25    	workbook.write(fos);
26    	fos.close();
27    	System.out.println(fileName + " written successfully");
28    }
29    
30    public static void main(String[] args) throws IOException {
31    	writeExcelWithFormula("Formulas.xlsx");
32    }
33}

用上述APACHE POI API示例程序生成的EXCEL文件如下图所示。JAVA WRITE EXCEL FORMULA,APACHE POI,APACHE POI TUTOUAL,APACHE POI example这些都是关于使用EXCEL文件的APACHE POI教程,请查看APACHE POI类方法以了解它的更多功能。参考资料ApachePOI Developers Guide

Published At
Categories with 技术
Tagged with
comments powered by Disqus