Java读Exlcel表格数据
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java读Exlcel表格数据相关的知识,希望对你有一定的参考价值。
1. 了解Excel相关概念
- Excel文件有两种格式,文件后缀为.xls的为excel2003及以前版本,文件后缀为.xlsx的为excel2007及以后版本。不同的版本,所使用的API不一样。
- 一个Excel文件对应一个工作簿(Workbook),一个workbook可以有多个工作表(Sheet)组成,一个sheet由多个单元格(cell)组成。这些单元格分成M行(row)、N列(Column)组成。列用大写英文字母表示,从A开始到Z共26列,然后再从AA到AZ又26列,再从BA到BZ再26列以此类推。行则使用数字表示,例如;A3 表示第三行第一列,E5表示第五行第五列。
- 工作簿里的工作表(sheet)从0开始编号。比如一个excel文件有3个sheet,则这三个sheet的序号分别是0,1,2。
2. Java操作Excel的方法
Java操作Excel需要用到第三方工具包。在搜索引擎中搜索“Java excel 操作“,查阅相关资料后可以知道:
JAVA中操作Excel的有两种比较主流的工具包:JXL和POI。jxl 只能操作Excel 95, 97, 2000,即以.xls为后缀的excel。而poi可以操作Excel 95及以后的版本,即可操作后缀为.xls和.xlsx两种格式的excel。
POI全称 Poor Obfuscation Implementation,直译为“可怜的模糊实现”,利用POI接口可以通过JAVA操作Microsoft office 套件工具的读写功能。官网:http://poi.apache.org,POI支持office的所有版本,所以这里选择POI进行讲解。
a) 下载工具包
打开POI官网,在左侧导航栏处点击“Download
第一步:打开官网
第二步:下载3.14版
选中下载3.14最新稳定版。下载文件分为二进制文件(容量小)和源码文件(容量大)两种,我们直接使用二进制文件即可。如果网站打不开或者开速度慢,大家也可以搜索其它网站下载其它版本,因为我们程序只需要处理简单的excel,没有其它特殊要求,所以一些较早版本(如3.9)也可以使用。3.9版本下载地址:http://pan.baidu.com/s/1slIf2Zb
3.14版下载后,会看到根目录、lib目录、ooxml-lib下有一些后缀为jar的文件,这些就是我们要使用的jar包。docs目录下的文件是帮助文档。
b) 添加jar包到项目中
软件包需要先导入到我们的项目中,我们的程序才可以使用poi。下载的jar包比较多,包括处理excel、word、ppt、visio、outlook等多种格式的office文档。我们的项目只需要处理excel,所以不必将所有jar包都导入进项目。我们可以通过下面方法来决定具体导入哪些:
在poi官网上左侧导航栏处点击“Components”菜单项,会看到与excel相关的组件:
从表中看出与excel操作相关的组件是poi和poi-ooxml。继续查看官网Components下面的说明,得知poi-ooxml包还需依赖poi-ooxml-schemas,而poi-ooxml-schemas包又依赖xmlbeans包(依赖是指一个工具包需要有另一个工具包才能够正常运行)。所以我们需要在项目中添加下图所示的4个jar包。添加方法是:
在MyEclipse的工作空间中,选中项目,点击右键,选择Properties菜单,弹出如下窗口:
按上图顺序就可将poi包导入进工程中。
c) 使用poi读写excel
了解POI的用法有两种方式,一种是阅读官网提供的文档。这种方法要求大家具有一定英文文档阅读能力。通常,很多有价值的第三方工具包都是国外发布的,作为程序员英语阅读能力是最基本的要求。官方文档一般会提供软件包的使用方法、api文档介绍、演示实例等。要想全面了解工具包的用法,阅读官方文档是最直接有效的途径。
第二种方法是查找对应的中文资料。这要求具有较强的互联网信息获取能力。
下面看一下Apache POI的基本用法。
Apache POI处理excel的类有两种前缀:
l HSSF:以此为前缀的API用来处理Excel 2003及以前的文档。
l XSSF:以此为前缀的API用来处理Excel 2007及以后的文档。
使用POI进行Excel文档处理之前还需要了解以下概念:
l Workbook:Excel工作簿的接口(interface),xls工作簿HSSFWorkbook类和xlsx工作簿XSSFWorkbook类都是Workbook的具体实现(implement)。
l Sheet:Excel工作表的接口,典型的实现类是HSSFSheet and XSSFSheet。
l Row:工作表的行接口。HSSFRow和XSSFRow是具体的实现类。
l Cell:工作表的列接口。HSSFCell和XSSFCell是具体的实现类。
让我们看看实际的读excel文件的例子:
简单读Excel文件的例子
假设要读一个如下内容的excel文件(见book.xlsx):
表中三列信息分表图书名称、作者和价格。一共有4行图书数据。
ExcelReaderDemo.java示例代码:
import java.io.File; 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 ExcelReaderDemo { public static void main(String[] args) throws IOException{ String excelFilePath = "E:/book.xlsx"; FileInputStream inputStream = new FileInputStream(new File(excelFilePath));
Workbook workbook = new XSSFWorkbook(inputStream); Sheet firstSheet = workbook.getSheetAt(0); Iterator<Row> iterator = firstSheet.iterator();
while (iterator.hasNext()) { Row nextRow = iterator.next(); Iterator<Cell> cellIterator = nextRow.cellIterator();
while (cellIterator.hasNext()) { Cell cell = cellIterator.next();
switch (cell.getCellType()) { case Cell.CELL_TYPE_STRING: System.out.print(cell.getStringCellValue()); break; case Cell.CELL_TYPE_BOOLEAN: System.out.print(cell.getBooleanCellValue()); break; case Cell.CELL_TYPE_NUMERIC: System.out.print(cell.getNumericCellValue()); break; } System.out.print(" "); } System.out.println(); }
workbook.close(); inputStream.close(); } }
|
输出结果:
一个面向对象的例子
这个例子是读上面的book.xlsx文件,将每行数据转换成对象。先在项目中添加一个模型类(Book.java),类代码如下:
Book.java代码
public class Book { private String title; private String author; private double price;
public Book() { }
public String toString() { return String.format("%s - %s - %f", title, author, price); } public String getAuthor() { return author; } public String getTitle() { return title; } public double getPrice() { return price; } public void setAuthor(String author) { this.author = author; } public void setPrice(double price) { this.price = price; } public void setTitle(String title) { this.title = title; } }
Excel表中每一行数据需要转换成一个Book对象。转换过程由一个专门的类ExcelReadUtil完成。在项目中添加ExcelReadUtil类,列代码如下: ExcelReadUtil.java代码 import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Iterator; import java.util.List;
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 ExcelReaderUtil { private Object getCellValue(Cell cell) { switch (cell.getCellType()) { case Cell.CELL_TYPE_STRING: return cell.getStringCellValue();
case Cell.CELL_TYPE_BOOLEAN: return cell.getBooleanCellValue();
case Cell.CELL_TYPE_NUMERIC: return cell.getNumericCellValue(); } return null; } public List<Book> readBooksFromExcelFile(String excelFilePath) throws IOException { List<Book> listBooks = new ArrayList<>(); FileInputStream inputStream = new FileInputStream(new File(excelFilePath));
Workbook workbook = new XSSFWorkbook(inputStream); Sheet firstSheet = workbook.getSheetAt(0); Iterator<Row> iterator = firstSheet.iterator();
while (iterator.hasNext()) { Row nextRow = iterator.next(); Iterator<Cell> cellIterator = nextRow.cellIterator(); Book aBook = new Book();
while (cellIterator.hasNext()) { Cell nextCell = cellIterator.next(); int columnIndex = nextCell.getColumnIndex();
switch (columnIndex) { case 1: aBook.setTitle((String) getCellValue(nextCell)); break; case 2: aBook.setAuthor((String) getCellValue(nextCell)); break; case 3: aBook.setPrice((double) getCellValue(nextCell)); break; } } listBooks.add(aBook); }
workbook.close(); inputStream.close();
return listBooks; }
public static void main(String[] args) throws IOException{ String excelFilePath = "E:/book.xlsx"; ExcelReaderUtil reader = new ExcelReaderUtil(); List<Book> listBooks = reader.readBooksFromExcelFile(excelFilePath); System.out.println(listBooks); } }
|
getCellValue方法用来将Cell表格中的字符串、布尔值、数值数据转换成对应类型的java类型数据。
readBooksFromExcelFile方法用来读取指定的excel文件,并将excel文件中的数据转换成相应的Book对象,将得到的所有Book对象存放在List<Book>链表中返回给调用者。
main是测试代码(你也可以将main方法放在一个单独的入口类中),在main中实例化了一个ExcelReaderUtil对象reader,调用reader的readBooksFromExcelFile方法,得到一个存放4个Book对象的链表,然后将此链表输出。
输出结果:
让程序既可以读Excel 2003,也可以读Excel 2007
通过阅读POI的API文档,我们知道读Excel 2003和Excel 2007所使用的API是不同的,一个是HSSFXXX,一个是XSSFXXX(XXX表示Workbook、Sheet、Row、Cell等)。其实,所有的HSSFWorkbook和XSSFWorkbook都是继承自Workbook,HSSFSheet和XSSFSheet都是继承自Sheet,HSSFRow和XSSFRow都是继承自Row,…,正式这种继承关系,我们就可以使用面向对象中的多态,对代码进行少许改动就能达到同时支持Excel 2003和Excel 2007。
在ExcelReaderUtil中添加如下getWorkbook方法:
private Workbook getWorkbook(FileInputStream inputStream,String excelFilePath) throws IOException { Workbook workbook = null;
if (excelFilePath.endsWith("xlsx")) { workbook = new XSSFWorkbook(inputStream); } else if (excelFilePath.endsWith("xls")) { workbook = new HSSFWorkbook(inputStream); } else { thrownewIllegalArgumentException("The specified file is not Excel file"); }
return workbook; } |
这样,在readBooksFromExcelFile方法中直接调用此方法就可以获取excel文件的Workbook对象了,而不用考虑是xls文件还是xlsx文件:
读Excel文件的其它信息
l 获取指定工作表
Sheet thirdSheet = workbook.getSheetAt(2);
l 获取工作表名称
String sheetName = sheet.getSheetName();
l 获取工作簿中工作表的总数
int numberOfSheets = workbook.getNumberOfSheets();
l 获取工作簿中所有工作表的名称
要获取其它更多信息,请查看
API
文档中
Workbook, Sheet, Row 和 Cell 接口的getXXX()
方法。
3.
实训任务一解析
编写代码,读取“附件
1
:
2013
级
2015
—
2016
学年度第一学期教材计划
.xlsx
”文档中的内容,将每行数据转换成一个课程类对象和两个教材类对象(主教材对应一个教材对象,辅教材也对应一个教材对象)
类关系图:
以上是关于Java读Exlcel表格数据的主要内容,如果未能解决你的问题,请参考以下文章
java中ReentrantReadWriteLock读写锁的使用