欢迎学习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示例-阅读Excel文件
假设我们有一个包含两张工作表的Excel文件)](https://journaldev.nyc3.digitaloceanspaces.com/2014/03/Java-Read-Excel-File-1.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文件如下图所示。
Apache POI示例-阅读Excel公式
有时我们需要处理复杂的excel文件与公式,让我们看一个简单的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文件如下图所示。这些都是关于使用EXCEL文件的APACHE POI教程,请查看APACHE POI类方法以了解它的更多功能。参考资料 :ApachePOI Developers Guide